导出Word排版总崩?DOM-docx用"可编辑优先+视觉回归打分"挑战WPS也没解决的难题
导出Word排版总崩?DOM-docx用”可编辑优先+视觉回归打分”挑战WPS也没解决的难题
“网页上编辑好好的,导出来全乱套了。”
做过报表导出、合同生成、文档下载功能的人,对这句话都不陌生。你在富文本编辑器里调好的标题字号、表格列宽、列表缩进,一导出 Word 就面目全非——标题字号不对、表格跨页断开、列表缩进消失。
更让人郁闷的是,这个问题不是什么边缘技术难题,但它就是一直没人解决干净。WPS 没解决,腾讯文档没解决,Google Docs 导出也不完美。用户不管你的技术选型有多复杂,他们要的就是一件事:
我在网页上看到什么样,导出来(或打印出来)就是什么样。
2026年7月,GitHub 上出现了一个叫 DOM-docx 的项目,247 星,MIT 协议。看起来又是个 HTML 转 Word 的库,但当你看完它的设计逻辑,会发现它切入的角度和别人不太一样:它不追求”像素复刻”,而是追求”可编辑结构+可量化的视觉保真度”。
这个项目是什么:不止又一个转换器
DOM-docx 做的事情可以用一句话说完:把语义化的 HTML 片段转成原生、可编辑的 Word 文档(OOXML)。
但关键在三个字——可编辑。
绝大多数 HTML 转 Word 的方案走的是”截图路线”:用 Puppeteer 把网页截成图片,或者转成 PDF,然后塞进 Word 文档。导出来的东西看着像样,但选不中文字、改不了字号、调不了表格,用户骂”你这是截图不是文档”。
另一条路是用模板引擎拼字符串:在 Word 模板里留占位符,后端用 Python-docx 或 docx 这种库往里面填内容。这条路可编辑性有了,但每改一次模板都要走一遍发布流程,维护成本随着文档种类线性增长。
DOM-docx 选了第三条路:输入标准化 HTML,输出原生 OOXML 结构。标题就是标题(<h1> → w:pStyle),表格就是表格(<table> → w:tbl),列表就是列表(<ul> → w:numPr)。不是截图的”看起来像”,而是结构上的”它本来就是”。

和其他方案的本质区别
下面这张表可以看清楚它和主流方案的差异:
| 维度 | DOM-docx | Puppeteer 截图/PDF | 模板引擎(docx 模板) | html-to-docx / html-docx-js |
|---|---|---|---|---|
| 输出产物 | 原生 OOXML 结构 | 图片/PDF 嵌入 | 原生 Word 文档 | 原生 OOXML |
| 可编辑性 | ✅ 完全可编辑 | ❌ 图片不可编辑 | ✅ 完全可编辑 | ⚠️ 部分可编辑(结构保真度不一) |
| 输入源 | 语义化 HTML 片段 | 任意网页 URL | 固定模板+变量 | HTML 字符串 |
| 浏览器依赖 | ❌ 默认无浏览器(纯 JS) | ✅ 需要 Puppeteer | ❌ 无 | ❌ 纯 JS |
| 样式解析 | inline(默认)或 computed | 像素级还原 | 模板预定义 | 基础 inline 样式 |
| 视觉回归测试 | ✅ 自建打分体系 | ❌ 无 | ❌ 无 | ❌ 无 |
| 学习成本 | 低(HTML 片段 + API 调用) | 中(Puppeteer + 容器部署) | 中(模板语法学习) | 低 |
| 复杂布局 | CSS grid/float 不支持 | ✅ 完整还原 | ❌ 模板限制 | ⚠️ 部分支持 |
核心差异在最后一行之前的那一格:DOM-docx 是唯一一个给自己装了”视觉回归测试系统”的 HTML-to-DOCX 库。
最与众不同的地方:把质量变成可衡量的数字
这是 DOM-docx 最值得关注的设计决策——它不只是写了一个转换器,还搭了一整套质量打分体系。
项目的测试管线是这样的:
-
准备一个 HTML 片段作为测试用例 -
用 Chromium 渲染这个 HTML → 截取”理想输出”作为视觉基准 -
用 DOM-docx 把同样的 HTML 转成 .docx -
用 LibreOffice 把 .docx 渲染成 PDF -
比较两个 PDF(基准 vs 转换结果)的布局一致性,打出 视觉保真度分数 -
同时检查输出文档的 结构可编辑性(是不是真有段落/列表/表格结构,而不是用 1×1 表格拼凑的伪结构)
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│ HTML Fragment │───→│ Chromium 渲染 │───→│ 基准 PDF(标准答案) │
└──────────────┘ └──────────────┘ └──────────────────┘
│
▼
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│ DOM-docx 转换 │───→│ LibreOffice 渲染 │───→│ 输出 PDF(待评估) │
└──────────────┘ └──────────────┘ └──────────────────┘
│
▼
┌─────────────────────┐
│ 布局一致性打分算法 │
│ 85.6% 与人工盲评一致 │
└─────────────────────┘
这个体系产出一个 Engine Score(引擎总分),由三部分组成:
-
50% 视觉保真度:布局层面的结构一致性(不是像素级对比,是”墨水投影结构”比较——哪块内容在哪块下面、间距是否对) -
35% 可编辑性:输出的 Word 文档是否真正保留了原生结构,还是靠布局表格模拟的 -
15% 编译速度:转换效率
更难得的是,DOM-docx 把竞品也纳入了同一套打分系统——它的 benchmark 会同时测试 html-to-docx[1] 和 @turbodocx/html-to-docx[2],在同一套测试用例下打出可对比的分数。
这就像考试的时候,你不仅给自己出了卷子,还拉着竞争对手一起考——分数高低一目了然。
能力边界:30+ 回归用例圈定的”舒适区”
DOM-docx 当前 v0.1.x 版本的能力边界非常清晰。它不是万能的 HTML 转换器,而是一个优化了特定子集的工具。
做得好的(默认 inline 路径):
-
标题、段落、有序/无序列表(含 list-style-type) -
表格、链接、内联加粗/斜体 -
区块背景色、引用块、分隔线 -
简单 Flex 行布局(≤4 项) -
data:图片嵌入 -
页眉页脚、页码、目录、封面页 -
页面尺寸/方向/边距 -
基础内联 SVG(矩形条+文字)
需要额外配置的(computed 样式/rasterizeInPlace):
-
<style>块和 class 选择器解析 → 需要 Playwright + Chromium(Node 端) -
<canvas>和复杂 SVG 图表(如 Highcharts)→ 需要rasterizeInPlace: { scale: 2 }
当前不支持的:
| 特性 | 状态 | 替代方案 |
|---|---|---|
| CSS grid / float 布局 | ❌ 不支持 | 使用基础表格/Flex 布局 |
| web 字体 | ❌ 不支持 | 使用系统字体 |
| 表单元素 | ❌ 不支持 | 避免在转换 HTML 中使用 |
<pre> 代码块 |
❌ 精排不支持 | 手动处理 |
<dl> 定义列表 |
❌ 不支持 | 用普通列表替代 |
| 表格 rowspan | ❌ 不支持 | 基础表格可用 |
| 复杂 SVG(路径/渐变/use) | ❌ 不原生支持 | 走 rasterizeInPlace 方案 |
换句话说,如果你的文档场景是表格+文字+列表+标题——报表导出、合同模板、商品说明书——DOM-docx 的默认路径已经能覆盖 90% 的需求。但如果你的页面有大量自定义布局、web 字体、复杂图表,就得多装一个 Playwright,走 computed 路线。
上手体验:确实简单
DOM-docx 的上手成本几乎是这个领域最低的。
Node.js 端
import { writeFile } from "node:fs/promises";
import { convertHtmlToDocx } from "dom-docx";
const html = `
<h1 style="color:#1a1a2e">业务数据报告</h1>
<p>本季度收入同比增长 <strong>12%</strong>。</p>
<ul>
<li>华东区</li>
<li>华南区</li>
<li>华北区</li>
</ul>
`;
const docx = await convertHtmlToDocx(html);
await writeFile("output.docx", docx);
就这么三行。默认返回的 docx 是 US Letter、1 英寸边距、Arial 10.5pt 正文——跟 Word 默认模板一致,不需要额外配置。
浏览器端
import { convertHtmlToDocx } from "dom-docx/browser";
const blob = await convertHtmlToDocx(html);
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "output.docx";
a.click();
纯前端,不需要 Node、不需要 Playwright、不需要服务端渲染。用户在浏览器里编辑富文本 → 拿到 HTML → 直接转 .docx 下载。
CLI 模式(零代码)
# 文件转文件
npx dom-docx input.html -o output.docx
# 管道模式
cat fragment.html | npx dom-docx - -o - > output.docx
这条管道命令意味着它可以轻松嵌入 CI/CD 流程、Git 钩子、无服务器函数——HTML 一进来,docx 就出去了。
要求只有一条:Node.js ≥ 20。如果用的是 computed 样式模式,再加装 playwright 和 Chromium(作为可选依赖,按需安装)。
适用场景诊断
强烈推荐:
-
报表导出系统:ERP/CRM/OA 中的财务对账单、业务月报、销售排行——数据规整、结构清晰,DOM-docx 的舒适区 -
合同/协议文档生成:合同模板多为标题+条款列表+签字栏组合,HTML 语义化越好,转换质量越高 -
富文本编辑器的文档下载功能:用户写了一篇带表格、标题、列表的文章,想要下载成 Word——用 dom-docx/browser纯前端搞定,零服务端成本 -
邮件 HTML 简报转文档存档:HTML 邮件格式 → 标准化 docx 存档,可编辑可检索
勉强可用(需额外工作):
-
包含大量图表的运营报告:需要装 Playwright + Chromium,启用 rasterizeInPlace: { scale: 2 }保证图表清晰 -
带复杂 CSS 自定义样式的文案页面:走 computed 模式,需要额外的部署依赖
暂不适合:
-
需要完整网页转 Word(含 CSS grid、Float、Web 字体):当前版本做不到 -
需要兼容二进制 .doc 格式:它只做 .docx(OOXML) -
多页严格排版控制:比如”第一页封面、第二页目录从第三页开始正文页眉不同”——v0.1.x 的页眉页脚变体支持还不完善
竞品生态:DOM-docx 站在哪个位置?
HTML 转 Word 这条赛道不算空,但每个方案都卡在不同的地方:
-
html-to-docx(npm 周下载 20 万+):老牌库,功能全但风格解析逻辑较旧,部分场景输出偏”用 1×1 表格模拟布局”——可编辑性打了折扣 -
@turbodocx/html-to-docx:较新的方案,聚焦简单转换,功能覆盖不如 DOM-docx -
html-docx-js:经典浏览器端方案,适合纯前端导出,但已缺乏维护,无页眉页脚支持 -
Mammoth.js:优秀的 .docx → HTML 解析库(反向),不处理 HTML → .docx -
docx-editor:完整的浏览器内 .docx 编辑工具(ProseMirror 引擎),但它做的是”编辑已存在的 .docx”,不是”从 HTML 创建新文档”
DOM-docx 和其他方案的最大区别不是功能多寡,而是设计哲学的差异:
-
可编辑性是第一优先级:输出的结构必须是”真正”的段落、列表、表格,不是视觉模拟 -
质量可量化:用视觉回归打分体系代替”人眼验、用手摸”的 QA 模式 -
默认路径零依赖:纯 JS、无浏览器、无 Playwright, npm install dom-docx就三样东西:docx+cheerio+fflate,总重非常轻
为了更直观,我把当前生态画了一张定位图:

风险与局限(诚实评估)
这一节独立出来,因为每个想用它的团队都需要知道这些:
1. v0.1.x,版本很早期。 项目刚发布一个月不到,50 个 commit。API 还没完全稳定,rowspan、<pre> 精排、页眉页脚分页变体这些功能还在待办列表上。生产环境大规模使用前,建议先拿自己的真实模板跑一遍测试集。
2. CSS grid/float 不支持是硬伤。 如果你的文档高度依赖 CSS 布局——比如多栏混排、图文绕排、精确定位——DOM-docx 的 inline 路径直接 pass,computed 路径也不行(它只解析文字样式不解析框模型)。这个限制在 v0.1.x 阶段没办法绕过。
3. “视觉回归打分”是自建的,不是第三方认证。 项目团队的测试体系设计得比大多数开源库严谨,但 85.6% 与人工盲评的一致率是一组有限的测试集数据,不是第三方审计结果。具体到你的业务场景,实际保真度可能高也可能低。
4. 生产环境验证不足。 GitHub 247 星、9 个 fork,说明关注度不错,但还没有大面积的生产环境反馈。除了项目自己跑的打分,你很难找到”某某公司用它在生产环境跑日活 XX”的案例。
5. 图表场景的额外成本。 需要处理图表就把 Playwright+Chromium 这个”可选变成必修”,部署容器要装 Chromium(≈300MB),CI/CD 里也得配置。说好的”零依赖”在这条路径上会打回原形。
总结:这是一个值得关注的方向性项目
DOM-docx 目前还不是一个”装上去就能解决所有排版问题”的银弹——v0.1.x 的版本号和明确的能力边界都告诉你了它还在早期。
但它提供了一个值得关注的设计方向:
-
把”可编辑性”和”视觉保真度”拆成两个独立指标去优化——这比大多数”既要又要但哪个都没做好”的方案更诚实 -
用工程化的评分体系驱动质量迭代——30+ 回归用例、自动打分、竞品对比,让优化不再是感性判断 -
默认零依赖的纯 JS 路径—— npm install即用,不欠部署债
如果你的团队正卡在”报表导出要么截图不可编辑、要么模板维护成本失控”的两难里,DOM-docx 值得花一个下午拿真实模板跑一轮测试。行就用,不行就当为以后打好提前量——等 rowspan、grid 支持上线的那一天,你再回头看的成本比今天低。
有什么想法可以随时留言沟通。
喜欢就先收藏,万一找不到了呢!⭐
引用链接
[1]html-to-docx: https://www.npmjs.com/package/html-to-docx
[2]@turbodocx/html-to-docx: https://www.npmjs.com/package/@turbodocx/html-to-docx
夜雨聆风