docx、html-docx-js 和 mammoth 是 JavaScript 生态中处理 Word 文档的三个核心库,但它们的用途截然不同。docx 专注于从头生成高质量的 .docx 文件,提供细粒度的 OOXML 控制;html-docx-js 旨在将现有的 HTML 内容快速转换为 Word 文档,适合简单导出场景;而 mammoth 则专门用于读取 .docx 文件并将其转换为 HTML 或纯文本,不支持生成。理解它们的方向(读 vs 写)和控制粒度是架构选型的关键。
在 Web 应用中处理 Word 文档通常涉及两个相反的方向:生成(写入)和解析(读取)。docx 和 html-docx-js 属于生成工具,而 mammoth 是解析工具。这种根本性的差异决定了它们在不同架构场景下的位置。让我们深入对比它们的技术实现和适用边界。
docx 是一个完整的文档生成引擎。
// docx: 生成文档
import { Document, Packer, Paragraph } from "docx";
const doc = new Document({
sections: [{
properties: {},
children: [new Paragraph("Hello World")],
}],
});
const blob = await Packer.toBlob(doc);
html-docx-js 是一个 HTML 到 Word 的转换器。
// html-docx-js: 转换 HTML 为文档
import htmlDocx from 'html-docx-js';
const htmlContent = '<h1>Hello World</h1>';
const blob = htmlDocx.asBlob(htmlContent);
// 直接返回 Blob,无需构建对象树
mammoth 是一个文档读取器。
// mammoth: 读取文档
import mammoth from "mammoth";
// 必须传入 ArrayBuffer 或 Buffer
const result = await mammoth.convertToHtml({ arrayBuffer: buffer });
const html = result.value; // 输出 HTML 字符串
docx 提供像素级的样式控制。
// docx: 精确控制样式
import { TextRun, HeadingLevel } from "docx";
const paragraph = new Paragraph({
heading: HeadingLevel.HEADING_1,
children: [
new TextRun({
text: "Title",
bold: true,
color: "FF0000",
}),
],
});
html-docx-js 依赖 HTML/CSS 映射。
// html-docx-js: 样式依赖 HTML
const html = `
<h1 style="color: red; font-weight: bold;">Title</h1>
<p>Content</p>
`;
// 样式保留程度取决于 Word 的 HTML 解析器
const blob = htmlDocx.asBlob(html);
mammoth 忽略大部分样式。
// mammoth: 样式映射配置
const result = await mammoth.convertToHtml({ arrayBuffer: buffer }, {
styleMap: [
"p[style-name='Heading 1'] => h1:fresh"
]
});
// 可自定义样式映射,但默认忽略复杂格式
docx 需要手动管理图片媒体。
// docx: 插入图片
import { ImageRun } from "docx";
import cat from "./cat.png";
const paragraph = new Paragraph({
children: [
new ImageRun({
data: cat,
transformation: { width: 100, height: 100 },
}),
],
});
html-docx-js 支持 Data URI 图片。
// html-docx-js: 图片嵌入 HTML
const html = `
<img src="data:image/png;base64,iVBORw0KGgo..." />
`;
const blob = htmlDocx.asBlob(html);
mammoth 提取图片为 Base64。
// mammoth: 提取图片
const result = await mammoth.convertToHtml({ arrayBuffer: buffer }, {
convertImage: mammoth.images.imgElement(function(image) {
return image.read("base64").then(function(base64) {
return { src: "data:" + image.contentType + ";base64," + base64 };
});
})
});
docx 通吃 Node.js 和浏览器。
// docx: 浏览器端保存
import { saveAs } from "file-saver";
const blob = await Packer.toBlob(doc);
saveAs(blob, "example.docx");
html-docx-js 主要在浏览器端使用。
// html-docx-js: 浏览器端保存
const blob = htmlDocx.asBlob(html);
// 通常配合 file-saver 使用
mammoth 通吃 Node.js 和浏览器。
// mammoth: 浏览器读取文件
const fileInput = document.querySelector("input[type=file]");
const arrayBuffer = await fileInput.files[0].arrayBuffer();
const result = await mammoth.convertToHtml({ arrayBuffer });
| 特性 | docx | html-docx-js | mammoth |
|---|---|---|---|
| 主要用途 | 📝 生成高质量文档 | 📄 HTML 转 Word | 📖 读取 Word 内容 |
| 数据方向 | 写入 (Write) | 写入 (Write) | 读取 (Read) |
| 样式控制 | 🎨 高 (OOXML) | 🎨 中 (HTML/CSS) | 🎨 低 (结构优先) |
| 学习成本 | 📈 高 | 📉 低 | 📉 低 |
| 维护状态 | ✅ 活跃 | ⚠️ 缓慢 | ✅ 稳定 |
| 图片支持 | ✅ 原生媒体对象 | ✅ Data URI | ✅ 提取为 Base64 |
docx 是企业级文档生成的首选 🏢。如果你的应用需要生成法律合同、正式报告或任何需要精确打印布局的文件,不要犹豫,选择 docx。虽然代码量较多,但它能避免格式错乱带来的后期维护成本。
html-docx-js 是快速原型的利器 🚀。如果你正在做一个博客系统或笔记应用,用户只想把当前页面存为 Word 备份,它的集成成本最低。但要做好心理准备,用户在 Word 中打开时可能会遇到细微的格式偏差。
mammoth 是内容摄入的网关 🚪。当用户上传图片到云端时,用它来提取文本进行搜索索引,或者在网页上预览文档内容。它生成的 HTML 干净且语义化,非常适合 Web 展示。
最终建议:在一个完整的文档管理系统中,你很可能同时需要 docx(用于导出报告)和 mammoth(用于导入预览)。不要试图用一个库解决所有问题,因为它们的设计初衷本身就是互补的。
选择 docx 如果你需要从零开始生成结构复杂、样式精确的 Word 文档。它适合生成合同、报告或发票,其中布局、页眉页脚和表格格式必须严格符合规范。虽然学习曲线较陡,但它提供了最可靠的 OOXML 控制,且长期维护活跃。
选择 html-docx-js 如果你只需要将现有的 HTML 内容(如富文本编辑器内容)快速导出为 Word 文件。它适合对格式精度要求不高、追求开发速度的场景。注意它在复杂布局上的表现不如 docx 稳定,且维护频率较低。
选择 mammoth 如果你的需求是读取用户上传的 Word 文件并在网页中展示或索引内容。它专注于将 .docx 转换为 HTML,保留了基本结构但忽略复杂样式。不要用它来生成或编辑文档,因为它仅支持单向转换。
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 💖