01 文档生成技能族:多格式文档的差异化技术选型
01 文档生成技能族:多格式文档的差异化技术选型
学习目标
- 理解四种文档格式(DOCX/PDF/PPTX/XLSX)的技术选型决策
- 掌握 unpack → edit → pack 三段式文档编辑工作流
- 分析 docx-js 的关键规则和 XML 编辑模式
- 学习跨格式的统一验证-修复循环
前置知识
本章涉及 Skill 渐进式知识管理的通用原理,建议先阅读:
下文假设你已理解上述概念,直接聚焦文档生成技能的具体实现。
项目实践
技术选型矩阵
Anthropic 对四种文档格式采用了不同的技术栈:
| 格式 | 新建 | 编辑 | 读取 | 转换 |
|---|---|---|---|---|
| DOCX | docx-js (npm) | XML 解包 + 编辑 + 重打包 | pandoc / 解包 | LibreOffice → PDF |
| - | 表单处理 | - | pdftoppm → 图片 | |
| PPTX | pptxgenjs | 解包 + 编辑 XML + 重打包 | - | LibreOffice → PDF |
| XLSX | xlsx 库 | xlsx 库直接修改 | xlsx 库读取 | - |
核心洞察:所有可编辑格式(DOCX/PPTX)都遵循相同的 unpack → edit → pack 三段式工作流。这是因为 .docx 和 .pptx 本质都是 ZIP 归档包含 XML 文件。
unpack → edit → pack 三段式工作流
unpack.py 做了什么:
- 提取 ZIP 归档中的 XML 文件
- 美化打印(pretty-print)XML
- 合并相邻的 runs(merge adjacent runs)——这是一个关键优化,因为 Word 文档中经常存在被意外拆分的 runs
- 将智能引号转换为 XML 实体(
“等),确保编辑时不会被破坏
docx-js 关键规则(新建模式)
DOCX 技能中列出了 13 条关键规则,以下是最常踩坑的几条:
| 规则 | 原因 | 后果 |
|---|---|---|
| 页面尺寸必须显式设置 | docx-js 默认 A4 | 美国文档会变成 A4 尺寸 |
绝不用 \n | 必须用 separate Paragraph | \n 创建无效 XML |
| 绝不用 unicode 子弹 | 必须用 LevelFormat.BULLET | 手动子弹在不同渲染器中不一致 |
| 表格需双宽度 | columnWidths + 单元格 width | 缺少任一维度导致渲染错误 |
WidthType.DXA 而非 PERCENTAGE | Google Docs 不支持百分比宽度 | 百分比在 Google Docs 中破坏 |
ShadingType.CLEAR 而非 SOLID | SOLID 产生黑色背景 | 表格变成全黑 |
| PageBreak 必须在 Paragraph 内 | 独立 PageBreak 创建无效 XML | 验证失败 |
ImageRun 需要 type | 必须指定 png/jpg 等 | 缺少 type 参数创建无效 XML |
| TOC 必须使用 HeadingLevel | 不能用自定义样式 | 自定义样式的标题不出现在 TOC 中 |
跟踪修改的 XML 模式
DOCX 技能中对 Word 的跟踪修改(tracked changes)定义了精确的 XML 模式:
插入:
<w:ins w:id="1" w:author="Claude" w:date="2025-01-01T00:00:00Z"> <w:r><w:t>插入的文本</w:t></w:r></w:ins>删除:
<w:del w:id="2" w:author="Claude" w:date="2025-01-01T00:00:00Z"> <w:r><w:delText>删除的文本</w:delText></w:r></w:del>关键细节:在 <w:del> 内使用 <w:delText> 而非 <w:t>。
验证-修复循环
pack.py 包含自动修复功能:
| 自动修复 | 不修复 |
|---|---|
durableId >= 0x7FFFFFFF(重新生成有效 ID) | 格式错误的 XML |
缺少 xml:space="preserve" | 无效的元素嵌套 |
| 缺少关系引用 | |
| 模式违规 |
问题与规避
DOCX 编辑后格式丢失
问题:编辑 XML 后重打包,文档格式损坏。
规避策略:
- unpack 时使用
--merge-runs false跳过 run 合并(保留原始结构) - 编辑时替换整个
<w:r>元素,不要在 run 内注入跟踪修改标签 - pack 时传入
--original document.docx保留原始关系引用
XLSX 公式引擎
问题:直接修改单元格值后公式不自动计算。
规避策略:xlsx 库直接修改时,需要手动触发公式重新计算。
设计取舍
为什么新建和编辑使用完全不同的技术栈?
优势:docx-js 对新文档更可控(从代码生成);XML 编辑对已有文档更保真(保留所有原始格式)。 代价:开发者需要学习两套工具链。 Anthropic 的选择:两套工具链都是最优解——没有一种工具能同时做好新建和编辑。
参考来源
- Anthropic Skills 仓库:
skills/docx/SKILL.md、skills/pdf/SKILL.md、skills/pptx/SKILL.md、skills/xlsx/SKILL.md - docx-js:https://github.com/dolanmiu/docx
- pptxgenjs:https://github.com/gitbrent/PptxGenJS