乐于分享
好东西不私藏

导出Word排版总崩?DOM-docx用"可编辑优先+视觉回归打分"挑战WPS也没解决的难题

导出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 最值得关注的设计决策——它不只是写了一个转换器,还搭了一整套质量打分体系

项目的测试管线是这样的:

  1. 准备一个 HTML 片段作为测试用例
  2. 用 Chromium 渲染这个 HTML → 截取”理想输出”作为视觉基准
  3. 用 DOM-docx 把同样的 HTML 转成 .docx
  4. 用 LibreOffice 把 .docx 渲染成 PDF
  5. 比较两个 PDF(基准 vs 转换结果)的布局一致性,打出 视觉保真度分数
  6. 同时检查输出文档的 结构可编辑性(是不是真有段落/列表/表格结构,而不是用 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 和其他方案的最大区别不是功能多寡,而是设计哲学的差异

  1. 可编辑性是第一优先级:输出的结构必须是”真正”的段落、列表、表格,不是视觉模拟
  2. 质量可量化:用视觉回归打分体系代替”人眼验、用手摸”的 QA 模式
  3. 默认路径零依赖:纯 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 的版本号和明确的能力边界都告诉你了它还在早期。

但它提供了一个值得关注的设计方向

  1. 把”可编辑性”和”视觉保真度”拆成两个独立指标去优化——这比大多数”既要又要但哪个都没做好”的方案更诚实
  2. 用工程化的评分体系驱动质量迭代——30+ 回归用例、自动打分、竞品对比,让优化不再是感性判断
  3. 默认零依赖的纯 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