DOCX
补丁
通过替换占位符、字面文本或元数据修改现有 .docx 文件
通过三种方式修补现有 .docx 模板:替换 {{占位符}} 标记、查找并替换字面文本,或覆盖文档元数据。补丁内容可以是内联 run、块级元素(段落、表格)、图片和超链接。
#patchDocument
替换现有 .docx 文件中的占位符:
import { patchDocument } from "@office-open/docx";
import { readFileSync, writeFileSync } from "node:fs";
const result = await patchDocument({
outputType: "nodebuffer",
data: readFileSync("template.docx"),
placeholders: {
name: {
type: "paragraph",
children: [{ text: "张三" }],
},
},
});
writeFileSync("output.docx", result);
#补丁类型
每个补丁通过裸字符串字面量 type 区分:
| 类型 | 说明 |
|---|---|
"paragraph" | 用内联运行级内容替换占位符 |
"document" | 用块级内容替换占位符 |
#"paragraph"
将段落中的占位符文本替换为新的 run。默认保留原 run 的格式属性(字体、大小、颜色、加粗等)。
{
"placeholders": {
"title": {
"type": "paragraph",
"children": [
{
"text": "你好 ",
"bold": true
},
{
"text": "世界"
}
]
}
}
}
#"document"
用块级元素(段落、表格等)替换占位符。保留周围的上下文。
placeholders: {
content: {
type: "document",
children: [
{ paragraph: { children: ["第一段"] } },
{ paragraph: { children: ["第二段"] } },
{
table: {
rows: [
{
cells: [
{ children: [{ paragraph: { children: ["单元格"] } }] },
],
},
],
},
},
],
},
}
#图片
用图片替换占位符:
placeholders: {
logo: {
type: "paragraph",
children: [
{
picture: {
data: readFileSync("logo.png"),
transformation: { width: "5.3cm", height: "2.6cm" },
type: "png",
},
},
],
},
}
#超链接
在补丁内容中包含超链接:
{
"placeholders": {
"website": {
"type": "paragraph",
"children": [
{
"text": "访问 "
},
{
"hyperlink": {
"children": [
{
"text": "我们的网站"
}
],
"url": "https://example.com"
}
}
]
}
}
}
#查找与替换
替换字面文本,无需分隔符 — 键按字面值匹配。适用于品牌更换或固定措辞更新。值使用相同的 Patch 结构(段落 run 或块内容):
const result = await patchDocument({
outputType: "nodebuffer",
data: templateBuffer,
findReplace: {
"Acme Corp": { type: "paragraph", children: [{ text: "Globex", bold: true }] },
Draft: { type: "paragraph", children: [{ text: "Final" }] },
},
});
#核心属性
覆盖文档元数据(docProps/core.xml)。值会与现有核心属性合并 — 只需提供要修改的字段:
const result = await patchDocument({
outputType: "nodebuffer",
data: templateBuffer,
coreProperties: { title: "季度报告", creator: "张三" },
});
#追加内容
向文档主体追加块级内容,插入在最后的分节符(<w:sectPr>)之前。它复用与 "document" 补丁相同的 SectionChild 词汇,因此段落、表格、图片和超链接都受支持:
const result = await patchDocument({
outputType: "nodebuffer",
data: templateBuffer,
append: [
{ paragraph: { children: ["追加的段落"] } },
{ paragraph: { children: [{ text: "加粗结尾", bold: true }] } },
],
});
追加内容经与 generateDocument 相同的编译路径序列化器处理,其图片和超链接会自动接入文档的关系。追加内容引用的样式和编号必须已存在于模板中。
#节编辑
直接编辑节列表 — 替换整节内容或追加新节。每条替换项用 0-based index 指明目标节(0 = 从文档开头算起):
const result = await patchDocument({
outputType: "nodebuffer",
data: templateBuffer,
sections: {
replace: [
{
index: 0,
section: {
children: [{ paragraph: { heading: "Heading1", children: ["第一章 — 已替换"] } }],
},
},
],
append: [
{
children: [{ paragraph: { children: ["附录"] } }],
properties: { pageSize: { width: 16838, height: 11906 } },
},
],
},
});
- 未给
properties时,被替换的节保留其现有页面设置;给了properties则由新设置接管。 - 追加的节插入在最后 body 级
sectPr之前,每节以自己的分节符收尾。未给properties的节继承最后一节的页面设置。 - 子内容与
append走同一序列化管线(段落、表格、图片、超链接)。 - 修补进来的节不支持
headers/footers— 它们需要新建 part;请改用generateDocument。
#批注
向现有文档注入批注,与现有 word/comments.xml 合并。批注 id 从现有最大 id 续编(无则从 0 开始)。两种锚点:
paragraphs— 将批注包裹在第 N 个主体段落(0-based,按文档顺序)周围。placeholders— 将批注包裹在含{{key}}标记的 run 周围,在占位符替换之前应用。
每条批注复用 CommentOptions 词汇(见批注与修订),但省略 id — 补丁会自动分配续编 id。
const result = await patchDocument({
outputType: "nodebuffer",
data: templateBuffer,
comments: {
paragraphs: [
{
index: 0,
comments: [{ author: "Alice", children: ["审阅开篇段落。"] }],
},
],
placeholders: {
name: [{ author: "Bob", children: ["核对此值。"] }],
},
},
});
现有批注会保留 — 新条目追加到 word/comments.xml 并重新序列化,当该 part 为新建时才添加批注关系与 content-type 接线。
#自定义分隔符
默认分隔符为 {{ 和 }}。使用 placeholderDelimiters 自定义:
await patchDocument({
outputType: "nodebuffer",
data: templateBuffer,
placeholders: { name: { type: "paragraph", children: [{ text: "John" }] } },
placeholderDelimiters: { start: "<<", end: ">>" },
});
#选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
outputType | string | — | 输出格式(见导出页面) |
data | Buffer | Uint8Array | ... | — | 输入 .docx 文件数据 |
placeholders | Record<string, Patch> | — | 分隔符包裹的占位符名称 → 补丁内容 |
findReplace | Record<string, Patch> | — | 字面查找字符串 → 补丁内容(无分隔符) |
coreProperties | Partial<CorePropertiesOptions> | — | 核心元数据覆盖,与现有值合并 |
append | SectionChild[] | — | 追加在最后分节符前的块级内容 |
sections | { replace?, append? } | — | 节编辑:replace 是 { index, section } 数组 |
comments | { paragraphs?, placeholders? } | — | 向段落或占位符 run 注入批注(与现有合并) |
keepOriginalStyles | boolean | true | 保留原始 run 格式属性 |
placeholderDelimiters | { start: string, end: string} | { start: "{{", end: "}}" } | 自定义占位符分隔符 |
#patchDetector
在修补之前扫描模板以发现所有占位符键:
import { patchDetector } from "@office-open/docx";
const placeholders = await patchDetector({
data: readFileSync("template.docx"),
});
// ["name", "title", "content", ...]
#提示
- Word 中跨分割运行的占位符会被库自动处理。
- 每个占位符的所有出现都会被替换,而非仅第一处 — 正文、页眉、页脚一视同仁。
placeholders和findReplace共享同一引擎;可在一次调用中同时使用。- 使用
keepOriginalStyles: true(默认)可在替换文本时继承模板的 run 格式(字体、大小、颜色等)。 - 补丁内容中的图片和超链接会自动添加到文档的关系中。