Сжатие Word DOC XML с помощью архиватора - PullRequest
0 голосов
/ 04 июня 2019

Я пытаюсь создать программу на Node.js, которая анонимизировала бы заданный путь для слова doc для более крупного проекта.Я уже разархивировал файл docx и отредактировал файл document.xml.Все, что мне нужно сейчас сделать, - это повторно сжать его.

Я изучил использование Archiver, но проблема в том, что он архивирует папку в .zip, поэтому, когда вы пытаетесь конвертировать его в docx, онповрежден.

fs.readFile('./extracted_doc/word/document.xml', 'utf8', (err, data) => {
                        if (err) reject(err);
                        var name = data.indexOf('<w:t>')
                        var end = data.indexOf('<\/w:t>')
                        var result = data.replace(data.slice(name + 5, end), "XXXXXXXXXXXXXXXXXX")
                        fs.writeFile('./extracted_doc/word/document.xml', result, (err) => {
                            if (err) reject(err)
                            //zipping the file back to docx
                            var output = fs.createWriteStream('./anonymized_submission.docx')
                            var archive = archiver('zip')

                            archive.on('error', function (err) {
                                throw err;
                            })

                            archive.pipe(output)
                            archive.directory("./extracted_doc", "extracted_doc")
                            archive.finalize()
                        })
                    });

1 Ответ

0 голосов
/ 04 июня 2019

Вот потенциальное решение вашей проблемы, я проверил, и оно работает для меня.Он заменит строку first на «XXXX ...».

Основная проблема с вашим существующим кодом заключалась в том, что он создавал корневой каталог «extract_doc» в файле .zip, который содержит архив документов.Это не то, что ожидает Слово.Ожидается структура документа в корне архива.

Я создал функцию zipDirectory, чтобы обойти это.Основной целью здесь является сохранение структуры каталогов архива.

const archiver = require("archiver");
const fs = require("fs");

fs.readFile('./extracted_doc/word/document.xml', 'utf8', (err, data) => {
    if (err) reject(err);
    var name = data.indexOf('<w:t>');
    var end = data.indexOf('<\/w:t>');
    var result = data.replace(data.slice(name + 5, end), "XXXXXXXXXXXXXXXXXX")
    fs.writeFile('./extracted_doc/word/document.xml', result, (err) => {
        if (err) reject(err);
        zipDirectory('./extracted_doc/', './anonymized_submission.docx');
    })
});

function zipDirectory(inputDir, outputFile) {
    let archive = archiver('zip');
    archive.on('error', function (err) {
        throw err;
    })

    let output = fs.createWriteStream(outputFile);
    archive.pipe(output);
    /* Ok, so we don't want a root name of <input_dir>, this is our workaround. */
    archive.directory(inputDir, '../');
    archive.finalize();
}
...