如何在 docx 文件 nodejs 的第一页附加图像?
How to attach image at first page in docx file nodejs?
现在我想实现一个功能,在nodejs中现有的docx文件的第一页添加二维码图像。
这三种方法我都试过了都无法解决
- 我试过 docx 包,但它只允许从头开始构建 docx 文件。
- 我试过 docxtemplater,但它只允许替换
{%image}
到图像文件。
- 我尝试生成一个仅包含二维码图像的新 docx 文件,并将其与原始 docx 文件合并。但是找不到任何适合 docx 合并的包。
这里有什么解决办法吗?提前致谢。
以干净的方式合并或编辑文件可能要困难得多。我的想法是解析文件,以便您可以以某种易于使用的 JSON 结构的形式对其进行编辑。
我还没有找到任何适合阅读 docx 文件的库,但它们只是 zip 存档。在里面你会发现一些文件夹和文件。其中之一是 /word/document.xml
。那是存储文档实际内容的地方。
您可能只解析其中的 XML,注入您自己的并将其重新序列化到文件中。如果您希望它居中或特定大小,您可能还需要编辑样式文件。
或者您可能想要解析内容并使用您提到的 docx
包创建一个全新的 word 文档。这可能并且很可能会导致您失去风格。
这取决于您为什么要注入二维码。您可能需要考虑一个全新的选项,例如让用户在 Markdown 编辑器中编写他们正在编写的任何内容并将其导出为 PDF。这很可能是最简单的。
实际上,很难将图像直接附加到 docx 文件。
为此,您需要将图像添加到 word/media
文件夹中,更新 word/_rels/document.xml.rels
文件中的关系并将代表图像的正确 xml 字符串添加到 word/document.xml
文件。
但它不能很好地处理大多数文件,即使文件是可恢复的,它也会损坏。
所以我的建议是将 {%image}
文本添加到 docx 文件中,并使用 docxtemplater 将其替换为图像。
要将 {%image}
添加到 docx 文件中,您需要将此 xml 字符串 <w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:t xml:space="preserve">{%image}</w:t></w:r></w:p>
添加到 word/document.xml
.
const originFile = fs.readFileSync(path.resolve('origin.docx'), 'binary');
const originZip = await JSZip.loadAsync(originFile);
const originDocumentFile = originZip.file(/^word\/document[0-9]*.xml$/)[0];
let originDocumentXml = await originDocumentFile.async("string");
const startIndex = originDocumentXml.indexOf("<w:body>") + 8;
originDocumentXml = originDocumentXml.slice(0, startIndex) + '<w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:t xml:space="preserve">{%image}</w:t></w:r></w:p>' + originDocumentXml.slice(startIndex);
originZip.file(originDocumentFile.name, originDocumentXml);
const updateFile = await originZip.generateAsync({ type: 'nodebuffer' });
fs.writeFile("output.docx", updateFile, function(err) {/*...*/});
现在我想实现一个功能,在nodejs中现有的docx文件的第一页添加二维码图像。
这三种方法我都试过了都无法解决
- 我试过 docx 包,但它只允许从头开始构建 docx 文件。
- 我试过 docxtemplater,但它只允许替换
{%image}
到图像文件。 - 我尝试生成一个仅包含二维码图像的新 docx 文件,并将其与原始 docx 文件合并。但是找不到任何适合 docx 合并的包。
这里有什么解决办法吗?提前致谢。
以干净的方式合并或编辑文件可能要困难得多。我的想法是解析文件,以便您可以以某种易于使用的 JSON 结构的形式对其进行编辑。
我还没有找到任何适合阅读 docx 文件的库,但它们只是 zip 存档。在里面你会发现一些文件夹和文件。其中之一是 /word/document.xml
。那是存储文档实际内容的地方。
您可能只解析其中的 XML,注入您自己的并将其重新序列化到文件中。如果您希望它居中或特定大小,您可能还需要编辑样式文件。
或者您可能想要解析内容并使用您提到的 docx
包创建一个全新的 word 文档。这可能并且很可能会导致您失去风格。
这取决于您为什么要注入二维码。您可能需要考虑一个全新的选项,例如让用户在 Markdown 编辑器中编写他们正在编写的任何内容并将其导出为 PDF。这很可能是最简单的。
实际上,很难将图像直接附加到 docx 文件。
为此,您需要将图像添加到 word/media
文件夹中,更新 word/_rels/document.xml.rels
文件中的关系并将代表图像的正确 xml 字符串添加到 word/document.xml
文件。
但它不能很好地处理大多数文件,即使文件是可恢复的,它也会损坏。
所以我的建议是将 {%image}
文本添加到 docx 文件中,并使用 docxtemplater 将其替换为图像。
要将 {%image}
添加到 docx 文件中,您需要将此 xml 字符串 <w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:t xml:space="preserve">{%image}</w:t></w:r></w:p>
添加到 word/document.xml
.
const originFile = fs.readFileSync(path.resolve('origin.docx'), 'binary');
const originZip = await JSZip.loadAsync(originFile);
const originDocumentFile = originZip.file(/^word\/document[0-9]*.xml$/)[0];
let originDocumentXml = await originDocumentFile.async("string");
const startIndex = originDocumentXml.indexOf("<w:body>") + 8;
originDocumentXml = originDocumentXml.slice(0, startIndex) + '<w:p><w:pPr><w:jc w:val="center"/></w:pPr><w:r><w:t xml:space="preserve">{%image}</w:t></w:r></w:p>' + originDocumentXml.slice(startIndex);
originZip.file(originDocumentFile.name, originDocumentXml);
const updateFile = await originZip.generateAsync({ type: 'nodebuffer' });
fs.writeFile("output.docx", updateFile, function(err) {/*...*/});