python-docx无法直接写入HTML,需先解析HTML再映射为Word对象;推荐用无头浏览器转PDF再用pdf2docx转换,或用LibreOffice命令行转换,简单场景可直接用Word打开HTML文件。

用 python-docx 直接写入 HTML 内容行不通
HTML 文件不是纯文本,python-docx 本身不解析 HTML 标签,直接把 <p>Hello</p> 写进文档,Word 会原样显示标签,而不是渲染成段落。
常见错误现象:document.add_paragraph('<h2>标题</h2>') → Word 里真出现“<h2>标题</h2>”字样。
- 必须先将 HTML 解析为结构化节点(如用
BeautifulSoup),再按语义映射到python-docx的对象(Paragraph、Run、Table) -
html2docx这类第三方包封装了这层转换,但对嵌套<div>、内联样式、CSS 类基本不支持 - 如果 HTML 来自富文本编辑器(如 TinyMCE、CKEditor),含大量
style属性或data-属性,几乎必然丢失格式
用浏览器打印成 PDF 再转 Word 是最稳的折中方案
现代浏览器(Chrome / Edge)的 headless 模式能准确还原 CSS 布局、字体、表格边框等,比纯 Python 解析靠谱得多;再用 pdf2docx 转一次,虽非 100% 精确,但保真度远高于其他路径。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用
puppeteer(Node.js)或playwright(Python/JS)启动无头浏览器,加载本地file:///path/to/file.html,调用page.pdf() - 避免用
chromedriver + selenium:PDF 生成接口不稳定,容易卡在字体加载或 JS 渲染完成判断上 -
pdf2docx转换时加参数multi_processing=True可提速,但若 HTML 含大量浮动元素(float: left),可能错乱——此时需提前在 HTML 中用@media print重置布局
libreoffice --headless 命令行转换适合批量且格式简单
LibreOffice 内置的转换引擎对标准 HTML(尤其带语义标签如 <h1>、<ul>、<table>)兼容性好,命令行方式稳定、无需额外依赖,适合 CI 或定时任务。
典型命令:
libreoffice --headless --convert-to docx --outdir ./output ./input.html
注意点:
- 必须确保系统已安装 LibreOffice(非仅 runtime),且版本 ≥ 7.0(旧版对 UTF-8 和 CSS 支持差)
- 转换结果中图片路径会失效——因为 LibreOffice 把相对路径当成本地文件系统路径,而 HTML 中的
<img src="images/a.png">在转换时找不到,需提前复制资源目录并用绝对路径或 base64 内联 - 不支持 JavaScript 渲染后的内容,只转换原始 HTML DOM,所以动态插入的节点(如
document.createElement)不会出现
Word 自带的“打开 HTML 文件”功能其实够用,但很多人没点对地方
双击 HTML 文件默认用浏览器打开,但 Word 确实能直接读取它:启动 Word → 文件 → 打开 → 浏览 → 文件类型选“网页(*.htm; *.html)” → 选中文件 → 打开。
这个方式被忽略,是因为:
- Windows 资源管理器里右键菜单没有“用 Word 打开”,需手动在打开对话框切换文件类型
- Mac 上需在 Finder 中右键 →
显示简介 → 打开方式 → Microsoft Word → 全部更改,否则双击仍走 Safari - Word 会保留基础样式(标题层级、列表、超链接),但丢弃所有自定义 CSS(比如
color: #ff6b35、margin-left: 2em),且表格合并单元格可能错位
如果你只是临时转一两个文件,且内容以文字和简单表格为主,这是最快、零配置的方法。
复杂点在于:HTML 里混用了内联样式、<style> 块、外部 CSS 链接,Word 只认前两者,且优先级混乱;更麻烦的是,某些自动生成的 HTML(如 Pandoc 输出)用 class="incremental" 这类语义不明的 class,Word 完全无视——这时候就得先用脚本清洗 HTML,删掉 class、提取 style 属性、扁平化嵌套 div。



















