
做后台的同学对"导出 Word"这需求应该不陌生——合同、简历、周报、巡检单,PM 一张嘴就是"跟 Word 里长得一样哈"。传统路子要么是后端 Java 上 POI(XML 写吐),要么是 node 里 child_process 调 LibreOffice(重到怀疑人生),要么 puppeteer 无头浏览器绕一圈(内存爆炸)。
前两天翻到 docx 这个库(docx.js.org,注意不是那个 Snapshot Media 的 DOCX.js,是两个东西,别搞混),作者是 dolanmiu,2016 年开坑到现在 4.8k star,npm 周下载 ~450K,在 JS 生成 Word 这条赛道基本是默认选项了。
它是什么
一句话:用 TS/JS 以声明式 API 生成 .docx 文件,Node 能用,浏览器也能用,零依赖,MIT 协议。
💡 容易混:npm 上搜
docx出来的是 dolanmiu 这个(我们要讲的);还有一个docx.js/@snapshotmedia/docx是 Snapshot Media 那边纯前端向的,star 少很多,别装错。
作者的定位挺清楚——不让你碰 OOXML。Word 底层那一坨 XML 有多反人类写过的人都懂,docx 把它包成了一层对象:Paragraph、TextRun、Table、ImageRun……你要标题要表格要页眉页脚,new 一下塞进去就行。
为什么是它,不是 officegen / docxtemplater
横向扫过一圈能打的就这几个,各自站位不一样:
数据来自 [develop365 对比页]。
officegen 问题在只跑 Node,浏览器端废了,而且维护节奏慢半拍;docxtemplater 思路是"先手搓一个 Word 模板,再用标签填",适合格式固定的合同单据,但你想动态拼复杂结构就憋屈;mammoth 本职是 Word→HTML,生成不是它的活。
docx 的位置是:要从零拼一份结构化的 Word,且双端都要能跑——这份需求它吃最舒服。
最小可用
官方首页给的 Hello World 直接抄:
import { Document, Packer, Paragraph, TextRun } from "docx"import * as fs from "fs"const doc = new Document({ sections: [{ children: [ new Paragraph({ children: [ new TextRun("Hello World"), new TextRun({ text: " - Bold text", bold: true }), ], }), ], }],})Packer.toBuffer(doc).then((buf) => { fs.writeFileSync("My Document.docx", buf)})Node 端 Packer.toBuffer() 出 Buffer,浏览器端换成 Packer.toBlob() 然后 URL.createObjectURL 触发下载就行——这点挺多人不知道,纯前端也能直接生成 Word 让用户点下载,不用过服务端。
几个值得说的点
TS 优先不是口号。每个参数、返回值都严格类型,装完就有 IntelliSense,Paragraph 底下能塞啥、TextRun 有哪些样式字段,IDE 直接提示,不用反复翻文档。
功能面覆盖得意外全。段落/表格/图片/项目符号/编号/页眉页脚/页码/目录/脚注尾注/书签/超链接/批注/修订/数学公式/分栏/行号……办公场景常见的基本都有。图片支持 PNG/JPEG/GIF,表格能跨页、能合单元格。
大文件有流式 API。Packer.toStream(doc) 一块块往外吐,千页级文档内存压在 50MB 以内,Node 服务高并发场景能吃住。
Patcher 改现成文档。不是只能从零造——你有个现成 .docx 模板,想往里改几段、塞个表,patcher 能直接动。比 docxtemplater 那种纯标签替换灵活,但又比自己解 zip 改 XML 省事。
零依赖。包里没挂任何 runtime 依赖,lockfile 不会给你平白多一堆子树,SSR / Serverless 都友好。
什么时候选它,什么时候别
选它:
别选它 / 换思路:
{} 完事Styling with XML 那节),这时候心里要有数dolanmiu 这个库 2016 年开坑,9 年下来 demo 目录堆了 80+ 用例(CV 生成、图片、横版、页眉页脚……都有),文档站 docx.js.org 该有的都有。如果你下个需求正好卡在"Word 导出",Java POI 写一半写吐了,不妨 npm i docx 试五分钟,比翻 OOXML 规范强。
⚠️ 装之前确认包名就是
docx,作者 dolanmiu。别装成 Snapshot Media 那个docx.js,那是个不同项目,浏览器向但功能面薄一些,两个 star 量差一个量级。
夜雨聆风