Files
2026-07-08 20:02:29 +08:00

194 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Word ↔ HTML High-Fidelity Converter
一个基于开源工具的 `.docx``.html` 双向转换程序,目标是尽量保持 Word 文档在浏览器和再次转回 Word 后的视觉效果一致。
> 现实说明:DOCX 和 HTML/CSS 的排版模型不同,严格意义上的“完全无损双向转换”不能只靠普通 HTML 实现。本项目采用 LibreOffice Writer 的转换引擎做高保真转换,再做 HTML/CSS 后处理;同时提供 PDF 渲染级视觉对比报告,便于验收。
## 功能
- DOCX → HTML
- 保留字体、字号、颜色、粗体、斜体、下划线、删除线
- 保留段落对齐、缩进、行距、页边距、分页符
- 保留表格结构、边框、合并单元格、部分背景色样式
- 保留图片、大小、位置、页眉页脚文本
-`<style>` 中的规则尽量内联到元素 `style` 中,降低浏览器打开时样式丢失概率
- HTML → DOCX
- 使用 LibreOffice 的 Writer HTML 导入器,解析 HTML/CSS 并导出 DOCX
- 对本程序生成的 HTML 回转 DOCX,视觉一致性更好
- 验收校验
- DOCX → PDF 渲染
- 将原始 DOCX 与回转 DOCX 的 PDF 页面转图片后做像素差异报告
## 依赖
### 1. 安装 LibreOffice
Linux 示例:
```bash
sudo apt-get update
sudo apt-get install -y libreoffice libreoffice-writer fonts-noto-cjk fontconfig
```
macOS:安装 LibreOffice 后,通常路径为:
```bash
/Applications/LibreOffice.app/Contents/MacOS/soffice
```
Windows:安装 LibreOffice 后,通常路径为:
```powershell
C:\Program Files\LibreOffice\program\soffice.com
```
如程序找不到 LibreOffice,可以设置:
```bash
export SOFFICE_BIN=/path/to/soffice
```
### 2. 安装 Python 依赖
```bash
pip install -r requirements.txt
```
## 快速使用
### DOCX 转 HTML
```bash
python converter.py docx2html demo/demo.docx output/demo.html
```
### HTML 转 DOCX
```bash
python converter.py html2docx output/demo2.html output/demo2.back.docx
```
### 一键往返转换
```bash
python converter.py roundtrip demo/demo.docx output/roundtrip
```
### 一键往返并生成视觉差异报告
```bash
python converter.py roundtrip demo/demo.docx output/roundtrip --verify
```
生成文件示例:
```text
output/roundtrip/demo.html
output/roundtrip/demo.roundtrip.docx
output/roundtrip/demo.visual-report.json
```
视觉报告字段说明:
```json
{
"exact_page_count": true,
"page_reports": [
{
"page": 1,
"same_size": true,
"mean_abs_diff_0_255": 4.2738
}
]
}
```
- `exact_page_count=true`:页数一致
- `same_size=true`:渲染页面尺寸一致
- `mean_abs_diff_0_255`:平均像素差异,越低越接近;复杂文档可设自己的验收阈值
## 生成测试 DOCX
项目里已经包含 `demo/demo.docx`。如果要重新生成:
```bash
python demo/make_demo_docx.py
```
## Docker 使用
构建镜像:
```bash
docker build -t word-html-converter .
```
DOCX 转 HTML
```bash
docker run --rm -v "$PWD:/work" word-html-converter \
docx2html /work/demo/demo.docx /work/output/demo.html
```
HTML 转 DOCX
```bash
docker run --rm -v "$PWD:/work" word-html-converter \
html2docx /work/output/demo.html /work/output/demo.back.docx
```
## 关键设计说明
### 为什么不用 Mammoth 或 Pandoc 作为主引擎?
- Mammoth 更适合把 DOCX 转成语义清晰的 HTML,它明确不是为了逐像素复制 Word 样式。
- Pandoc 很适合文档格式互转,但更偏结构化内容转换,不适合要求高度还原 Word 页面排版的场景。
- LibreOffice Writer 的 DOCX/HTML 导入导出更接近真实办公软件排版结果,所以本项目把它作为主转换内核。
### 为什么 HTML 转 DOCX 要强制 `HTML (StarWriter)` 输入过滤器?
LibreOffice 默认可能把 HTML 当作 Web 文档打开,导致导出 DOCX 时出现“no export filter”或排版丢失。本项目使用:
```bash
--infilter="HTML (StarWriter)"
```
让 HTML 作为 Writer 文档导入,再导出 Office Open XML DOCX。
### 可选归档模式
DOCX 转 HTML 时可以加:
```bash
python converter.py docx2html input.docx output.html --embed-source
```
这样会把原始 DOCX 以 base64 形式嵌入 HTML。HTML 转 DOCX 时可加:
```bash
python converter.py html2docx output.html restored.docx --prefer-embedded-source
```
这适合“HTML 只用于预览/存档,希望完全恢复原始 DOCX”的场景。注意:如果用户在 HTML 中编辑了内容,使用该模式会恢复原 DOCX,不会合并 HTML 编辑内容。
## 已知边界
以下内容在开源转换链路中很难保证完全一致,需要单独测试:
- 复杂浮动图片、环绕方式、文本框、艺术字、SmartArt
- Word 域、目录、脚注尾注、批注、修订痕迹
- 复杂多级编号、样式继承、主题字体
- 页面级精确排版,如不同 Word/LibreOffice 版本的字体度量差异
- 浏览器编辑 HTML 后再转 DOCX,不能保证所有 CSS 都能被 Writer 完整识别
## 推荐验收标准
建议不要用“字节级相同”验收 DOCX,因为二次生成的 DOCX 内部 XML 顺序、关系 ID、压缩结果通常会变。建议用:
1. 页数一致;
2. 关键表格行列、合并单元格、图片数量一致;
3. PDF 渲染视觉差异低于业务阈值;
4. 典型复杂样例人工抽检。