我正在尝试使用 docx javascript 库生成 docx 文件,但仅限于客户端。
新文档的生成就像魅力一样,但我想使用patcher来修补文档。该文档仅显示了使用
patchDocument(fs.readFileSync("My Document.docx")
进行服务器端加载的代码。没有有关客户端使用的信息。
我使用以下代码尝试了它:
fetch('./public/template.docx')
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch template.docx');
}
return response.blob();
})
.then(blob => {
console.dir(blob);
const reader = new FileReader();
reader.onload = function(event) {
const arrayBufferData = event.target.result;
console.log(arrayBufferData);
patchDocument({
outputType: "blob",
data: arrayBufferData,
patches: {
title: {
type: PatchType.PARAGRAPH,
children: [new TextRun("NEUER TITEL")],
},
number: {
type: PatchType.PARAGRAPH,
children: [new TextRun("XX")],
}
},
});
};
reader.readAsArrayBuffer(blob);
})
.catch(error => {
console.error('Error fetching template.docx:', error);
});
我收到以下错误:
未捕获(承诺中)错误:无法读取“加载的 zip 文件”的数据。它是受支持的 JavaScript 类型(String、Blob、ArrayBuffer 等)吗?` 在 docx.js?v=ba760d4b:16887:43
但是通过console.log查看,数据实际上是一个ArrayBuffer。我也尝试输入 blob,结果相同。我对节点没有经验,我不知道
fs.readFileSync
会返回什么对象类型。但我猜它也是一个 ArrayBuffer!?该错误还提到,它需要 Blob 或 ArrayBuffer 类型。
我做错了什么,还是客户端根本不支持补丁程序?通过 fs.readFileSync 加载文件和从 blob 转换的 ArrayBuffer 加载数据之间是否存在差异?两者不都是简单的 ArrayBuffer 对象吗?
我终于发现上面代码的问题了。虽然上面的语法与文档中的语法匹配,但它似乎只适用于以下语法:
fetch('./public/template.docx')
.then(response => {
if (!response.ok) {
throw new Error('Failed to fetch template.docx');
}
return response.blob();
})
.then(blob => {
console.dir(blob);
const reader = new FileReader();
reader.onload = function (event) {
const arrayBufferData = event.target.result;
console.log(arrayBufferData);
patchDocument(arrayBufferData, {
outputType: "nodebuffer",
patches: {
title: {
type: PatchType.PARAGRAPH,
children: [new TextRun("NEUER TITEL")],
},
number: {
type: PatchType.PARAGRAPH,
children: [new TextRun("XX")],
}
},
}).then(finaldata => {
const blob = new Blob([finaldata], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
// Now work with the data, e.g. download it.
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'output.docx';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
});
};
reader.readAsArrayBuffer(blob);
})
.catch(error => {
console.error('Error fetching template.docx:', error);
});
这里的区别在于数据作为第一个参数给出,其余选项在对象内给出。在选项对象中使用
data
字段在客户端不起作用。我不确定这是否是一个错误,或者我是否错过了一个明显的细节。
我还使用“nodebuffer”作为outputType,然后将其转换为Blob对象
无论如何,我想分享解决方案,以防其他人遇到这个问题。