docx、docxtemplater、mammoth 和 pizzip 代表了 JavaScript 处理 Word 文档的四种不同技术路径。docx 专注于通过代码从头构建 .docx 文件,适合动态报告生成;docxtemplater 专注于基于现有 Word 模板填充数据,适合合同与发票;mammoth 专注于将 .docx 转换为 HTML 或纯文本,适合内容展示;而 pizzip 则是底层的 Zip 处理库,通常作为 docxtemplater 的依赖来处理 .docx 文件的压缩容器结构。
在 Node.js 和前端生态中,处理 Word 文档(.docx)通常面临三个核心需求:从头生成文档、基于模板填充数据、或将文档转换为 Web 可读格式。docx、docxtemplater、mammoth 和 pizzip 分别解决了这些不同层面的问题。理解它们的底层机制和适用边界,对于构建稳定的文档服务至关重要。
这四个库的根本区别在于它们对 .docx 文件的“读写”态度不同。
docx 是一个纯粹的生成器。它不关心现有的 .docx 文件,而是通过 JavaScript 对象描述文档结构,然后编译成二进制文件。
// docx: 通过代码定义结构生成新文件
const { Document, Packer, Paragraph, TextRun } = require("docx");
const doc = new Document({
sections: [{
properties: {},
children: [
new Paragraph({
children: [new TextRun("Hello World")],
}),
],
}],
});
const buffer = await Packer.toBuffer(doc);
docxtemplater 是一个模板引擎。它加载一个现有的 .docx 文件,查找其中的占位符(如 {name}),并用数据替换它们。
// docxtemplater: 加载模板并填充数据
const Docxtemplater = require("docxtemplater");
const PizZip = require("pizzip");
const fs = require("fs");
const content = fs.readFileSync("template.docx", "binary");
const zip = new PizZip(content);
const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });
doc.render({ name: "John" });
const buffer = doc.getZip().generate({ type: "nodebuffer" });
mammoth 是一个转换器。它读取 .docx 文件,提取内容并转换为 HTML 或文本,不保留复杂的 Word 样式,只保留语义结构。
// mammoth: 转换为 HTML 用于网页展示
const mammoth = require("mammoth");
const result = await mammoth.convertToHtml({ path: "document.docx" });
console.log(result.value); // 输出 HTML 字符串
pizzip 是底层容器处理器。.docx 本质上是 Zip 包,pizzip 负责解压和修改包内的 XML 文件,通常配合 docxtemplater 使用。
// pizzip: 直接操作 Zip 容器(底层)
const PizZip = require("pizzip");
const fs = require("fs");
const content = fs.readFileSync("file.docx", "binary");
const zip = new PizZip(content);
// 直接读取包内的 XML 文件
const xmlContent = zip.file("word/document.xml").asText();
样式处理是文档库最复杂的部分。docx 要求你在代码中定义样式,而 docxtemplater 继承模板的样式。
docx 需要显式定义样式对象。这给了你最大的灵活性,但代码量较大。
// docx: 代码中定义样式
const { Style, HeadingLevel } = require("docx");
const doc = new Document({
styles: {
paragraphStyles: [
{
id: "heading1",
name: "Heading 1",
basedOn: "Normal",
next: "Normal",
quickFormat: true,
run: { size: 28, bold: true, color: "000000" },
},
],
},
sections: [{
children: [
new Paragraph({ text: "Title", style: "heading1" })
]
}]
});
docxtemplater 直接使用 Word 中设计好的样式。你只需要在 Word 里设置好字体和颜色,代码只负责填数据。
// docxtemplater: 样式由 template.docx 决定
// Word 模板中:{title} 已经设置为红色加粗
doc.render({ title: "Project Report" });
// 输出文件中,"Project Report" 自动继承模板样式
mammoth 尝试映射样式到 CSS 类,但主要关注内容结构。它不生成 .docx,所以不涉及 Word 样式保留,而是生成 Web 样式。
// mammoth: 样式映射到 CSS
const options = {
styleMap: [
"p[style-name='Heading 1'] => h1:fresh",
"p[style-name='Normal'] => p"
]
};
const result = await mammoth.convertToHtml({ path: "doc.docx" }, options);
pizzip 不关心样式。它只处理二进制和 XML 文本。如果你要用它改样式,需要直接操作 word/styles.xml。
// pizzip: 手动修改底层 XML 影响样式(不推荐,极易出错)
const zip = new PizZip(content);
let stylesXml = zip.file("word/styles.xml").asText();
// 需要手动解析并修改 XML 字符串来改变样式定义
stylesXml = stylesXml.replace("<w:val w:val='black'/>", "<w:val w:val='red'/>");
zip.file("word/styles.xml", stylesXml);
处理列表、表格或条件显示是文档生成的常见需求。
docx 通过 JavaScript 数组映射来生成列表。逻辑完全在 JS 控制中。
// docx: 使用 JS 循环生成列表
const items = ["Item 1", "Item 2", "Item 3"];
const doc = new Document({
sections: [{
children: items.map(text => new Paragraph({
children: [new TextRun(text)]
}))
}]
});
docxtemplater 支持在 Word 模板中写简单的循环语法(如 {#items}{name}{/items})。
// docxtemplater: 模板中定义循环逻辑
// Word 模板内容:{#users}{name} - {email}{/users}
doc.render({
users: [
{ name: "Alice", email: "alice@example.com" },
{ name: "Bob", email: "bob@example.com" }
]
});
mammoth 将列表转换为 HTML <ul> 或 <ol>。它只是读取现有结构,不创造新逻辑。
// mammoth: 读取现有列表结构
// 如果 docx 中已有列表,转换为:
// <ul><li>Item 1</li><li>Item 2</li></ul>
pizzip 没有逻辑处理能力。你需要自己解析 XML 中的 w:tr (表格行) 或 w:p (段落) 并复制节点。
// pizzip: 手动复制 XML 节点实现循环(极高复杂度)
// 需要解析 document.xml,找到模板行,克隆节点并替换占位符
// 通常不建议直接使用 pizzip 处理业务逻辑循环
架构决策时,依赖链的复杂度是一个重要考量。
docx 是独立的。它不依赖外部 Zip 库来处理生成过程,打包后体积相对可控,API 自包含。
// docx: 独立使用
const { Document, Packer } = require("docx");
// 无需额外配置即可生成文件
docxtemplater 强依赖 Zip 库(如 pizzip)。它本身只处理 XML 模板逻辑,文件读写需要外部模块配合。
// docxtemplater: 必须配合 Zip 库
const Docxtemplater = require("docxtemplater");
const PizZip = require("pizzip"); // 必须引入
// 两者配合才能完成工作
mammoth 是独立的。它内置了解析 .docx Zip 结构的能力,专注于转换逻辑。
// mammoth: 独立使用
const mammoth = require("mammoth");
// 直接传入路径或 Buffer 即可
pizzip 是基础库。它通常不单独出现在业务代码顶层,而是作为 docxtemplater 的底层支撑。
// pizzip: 作为依赖存在
// 通常只在需要自定义 docxtemplater 模块或处理非标准 Zip 操作时直接调用
数据来自数据库,图表和段落结构每月变化。
docx格式固定,法务部门已审核过 Word 模板,只需填入客户信息。
docxtemplater用户上传 .docx,系统需要在网页上显示内容。
mammoth需要在底层修改 .docx 包的特定属性或添加隐藏文件。
pizzip (配合其他库)| 特性 | docx | docxtemplater | mammoth | pizzip |
|---|---|---|---|---|
| 主要用途 | 从头生成文档 | 填充现有模板 | 转换为 HTML/文本 | 处理 Zip 容器 |
| 输入源 | JavaScript 对象 | .docx 模板文件 | .docx 文件 | .docx/Zip 二进制 |
| 输出格式 | .docx 二进制 | .docx 二进制 | HTML / 纯文本 | Zip 对象 / 二进制 |
| 样式控制 | 代码定义 (灵活) | 模板定义 (保真) | 映射为 CSS | 手动修改 XML |
| 学习曲线 | 高 (需懂文档结构) | 中 (需懂模板语法) | 低 (简单转换) | 极高 (需懂 XML/Zip) |
| 依赖关系 | 独立 | 依赖 Zip 库 (如 pizzip) | 独立 | 基础依赖库 |
docx 是构建文档生成服务的基石,适合需要高度动态化的场景,但开发成本较高,因为你需要用代码“画”出文档。
docxtemplater 是业务友好型选择,它将文档设计的权力交还给了非技术人员(通过 Word),适合企业级表单和报告,但需注意模板语法的限制。
mammoth 是展示层的工具,不要试图用它来编辑文档。它在内容迁移和 Web 预览场景中无可替代。
pizzip 是底层齿轮。除非你有非常特殊的底层需求(如自定义模块开发),否则应通过 docxtemplater 间接使用它,避免直接操作 XML 带来的维护噩梦。
最终建议:对于大多数企业应用,组合使用 docxtemplater + pizzip 处理固定格式文档,使用 docx 处理动态报告,使用 mammoth 处理前端预览,是性价比最高的架构方案。
选择 docx 如果你需要通过代码完全控制文档的结构和样式,例如生成动态图表报告或复杂布局的文档。它适合不需要用户预先设计模板,而是由程序逻辑决定文档内容的场景。
选择 docxtemplater 如果你已有设计好的 Word 模板(.docx),只需要将数据填入占位符。它适合发票、合同、通知书等格式固定但内容多变的文档,且能保留原始模板的样式。
选择 mammoth 如果你需要在 Web 端展示 Word 文档的内容,而不是编辑或生成它。它将 .docx 转换为干净的 HTML,适合文档预览、内容提取或迁移场景。
选择 pizzip 通常不是直接用于业务逻辑,而是当你需要底层操作 .docx 文件的 Zip 结构时。它主要作为 docxtemplater 的依赖库存在,除非你要构建自定义的文档处理引擎,否则一般不单独使用。
Easily generate and modify .docx files with JS/TS. Works for Node and on the Browser.
Here are examples of docx being used with basic HTML/JS in a browser environment:
Here are examples of docx working in Angular:
Here are examples of docx working in React:
Here is an example of docx working in Vue.js:
Press endpoint on the RunKit website:

More here
Please refer to the documentation at https://docx.js.org/ for details on how to use this library, examples and much more!
Experience docx in action through Docx.js Editor, an interactive playground where you can code and preview the results in real-time.
Check the demo folder for examples.
Read the contribution guidelines here.
...and many more!
Made with 💖