有个前端需求看起来特别简单:把富文本编辑器里的 html 字符串导成 Word 文档,按钮一按就能下载。我当时搜了一圈,最后选中了 html-docx-js 这个前端插件,示例里只写一行 API,跑通 Demo 只用了一个下午。可后续几乎全在和兼容问题缠斗:在 Chrome 里导出的文档,换个浏览器打开就少了半屏内容;打包发给客户,有的 Word 版本干脆提示文件损坏;WPS 用户那边的反馈更是一言难尽。
这篇文章不想再讲那种“照着两步就能跑通”的教程。我想把 html 格式字符串转 Word 这个需求背后,html-docx-js 真实的形态、我在字体分页表格图片里踩过的坑、排查兼容问题的方法论,以及最终怎么决定换不换方案,完整记录下来。如果你也正打算在项目里用这个库,或者已经在用它并且被各种环境问题折磨,这篇应该能帮你少走不少弯路。
1. 先别急着调样式:先搞清楚 html-docx-js 到底生成了什么格式的文件
1.1 为什么它能靠一行代码下载“Word 文档”
html-docx-js 这个插件的名字太有迷惑性了。名字里带着 docx,很容易让人误以为它真的能把 HTML 转成标准 OOXML 文档。当初我搜到的示例一般长这样:
javascript复制import HtmlDocx from 'html-docx-js';
const html = '<html><head><meta charset="utf-8"></head><body>' + editorContent + '</body></html>';
const blob = HtmlDocx.create(html, {
orientation: 'portrait',
margins: {
top: 720,
right: 720,
bottom: 720,
left: 720
}
});
saveAs(blob, 'report.docx');
拿过来复制到项目里,再点一下下载按钮,一个后缀为 .docx 的文件真的就出来了。打开以后内容也在,文本样式也基本能看清,那一刻很难不觉得“这库真省事”。我甚至在初期遇到样式问题的时候,第一反应都是去调整 CSS,而不是先怀疑文件本身有问题。
真正让我开始起疑心,是有一次我想看看这个文件里到底长什么样,把文件名后缀从 .docx 改成 .txt,用文本编辑器打开。然后发现文件开头并没有想象中标准的 zip 压缩包标识 PK,而是一大段 XML 和 <html> 标签。标准 .docx 本质上是一个 zip 压缩包,里面装着 word/document.xml、word/styles.xml 等文件;html-docx-js 产出的内容却明显不是这个结构。
1.2 MHTML 与 Office 命名空间:它走的是 Word 的兼容后门
我后来翻了插件的源码和早期文档,又看了一些历史 issue,基本确认了它的工作原理:html-docx-js 并不是真正“生成 docx”,而是把一个完整带 Word 命名空间声明的 HTML 文档包装成 Word 能识别的格式。它在文件头部写一段类似 <mso-application progid="Word.Document"> 的标记,让 Windows 上的 Word 看见这个文件时,知道该用“网页文档”的方式打开。
这段处理在 Word 里有一个非常典型的表现:点击文件后,Word 经常弹出提示“文件是网页文档,是否转换为 Word 格式”,或者文件以兼容模式打开,功能区始终显示“兼容模式”几个字。很多业务系统的用户遇到这个弹窗会以为文件损坏,实际上不是损坏,而是 Word 正在试图把那个披着 doc
