Сжатие Word DOC XML с помощью архиватора

Я пытаюсь создать программу на 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 ответ

Решение

Вот потенциальное решение вашей проблемы, я проверил, и это работает для меня. Первая строка будет заменена на "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();
}
Другие вопросы по тегам