dom-docx: HTML 转原生可编辑 Word 文档
dom-docx: HTML 转原生可编辑 Word 文档
概述
dom-docx 是一个 TypeScript 库,旨在将语义化 HTML 片段转换为原生、可编辑的 Word 文档 (OOXML)。与生成截图或布局技巧的工具不同,dom-docx 生成真正的 Word 结构——段落、运行、列表和表格——确保生成的文档在 Microsoft Word 和 LibreOffice 中完全可编辑。
核心能力
支持的 HTML 元素
在其默认的 inline 模式下,该库支持广泛的语义化 HTML:
- 文本与结构:标题、段落、列表 (
<ul>,<ol>) 和引用块。 - 格式化:行内格式 (
<strong>,<em>)、链接和水平线 (<hr>)。 - 引用与布局:数据表格、阴影提示框和简单的 flex 行(最多 4 个项目)。
- 视觉效果:
data:图像和低复杂度的行内 SVG(特别是条形图和文本)。
高级渲染选项
根据对样式和复杂度的不同需求,dom-docx 提供三种不同的转换路径:
- 行内样式解析 (
styleSource: "inline"):默认的纯 JavaScript 路径。它直接解析style=""属性,且不需要浏览器环境。 - 计算样式解析 (
styleSource: "computed"):使用getComputedStyle解析<style>块、类和 ID 选择器。- 在 Node.js 中:需要 Playwright 和 Chromium 来进行无头渲染。
- 在浏览器中:使用用户标签页的实时 DOM,无需额外安装。
- 光栅化 (
rasterizeInPlace):在转换前将<canvas>和复杂的<svg>(例如 Highcharts)转换为 PNG 图像。对于复杂的图表,建议使用scale: 2以获得高密度输出。
技术架构
转换流水线
该库通过三个阶段将 HTML 映射到 OOXML:
- 样式解析:通过行内属性或浏览器计算样式确定最终样式。
- 访问者模式 (Visitor Pattern):通过 Cheerio 遍历,将 HTML 元素转换为
docx段落、表格、编号和超链接。 - 打包与修补 (Pack & Patch):生成 OOXML 并应用修补程序,以确保列表编号和阴影块对齐在 Word 和 LibreOffice PDF 导出时保持一致。
通过视觉回归进行质量保证
作者使用“Autoresearch”模式开发 dom-docx——这是一个通过迭代不断提高保真度的自主循环。该过程包括:
- 在 Chromium 中渲染 HTML。
- 通过 dom-docx 将 HTML 转换为
.docx。 - 使用 LibreOffice 将
.docx文件光栅化。 - 将浏览器截图与 LibreOffice 截图进行对比,从而为布局保真度、可编辑性和速度评分。
该循环针对 37 种真实的 HTML 模式运行,以确保与人类质量评分具有高度一致性。
集成与使用
安装
npm install dom-docx
注意:需要 Node.js ≥ 20。Playwright 是一个可选的同级依赖,仅在 Node 中用于计算样式或光栅化。
快速入门示例
浏览器使用 (纯 JS,无需 Playwright):
import { convertHtmlToDocx } from "dom-docx/browser";
const html = `<h1 style="color:#1a1a2e">Quarterly Report</h1><p>Revenue grew <strong>12%</strong> year over year.</p>`;
const blob = await convertHtmlToDocx(html);
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = "output.docx";
a.click();
Node.js 使用:
import { writeFile } from "node:fs/promises";
import { convertHtmlToDocx } from "dom-docx";
const html = `<h1 style="color:#1a1a2e">Quarterly Report</h1><p>Revenue grew <strong>12%</strong> year over year`;
const docx = await convertHtmlToDocx(html);
await writeFile("output.docx", docx);
命令行工具 (CLI)
无需编写代码即可进行快速转换,该库提供了一个 CLI:
npx dom-docx input.html -o output.docx
局限性
在 0.1.x 版本中,以下功能暂不支持:
inline路径下的外部样式表。- Web 字体、CSS grid、浮动布局和绝对定位。
- 表单、
<dl>和表格rowspan。 - 复杂的 SVG 路径和渐变(除非使用
rasterizeInPlace)。 - 无法保证多页布局保真度,或针对首页/偶数页的特定页眉/页脚变体。