跳转到内容

01 文档生成技能族:多格式文档的差异化技术选型

01 文档生成技能族:多格式文档的差异化技术选型

学习目标

  • 理解四种文档格式(DOCX/PDF/PPTX/XLSX)的技术选型决策
  • 掌握 unpack → edit → pack 三段式文档编辑工作流
  • 分析 docx-js 的关键规则和 XML 编辑模式
  • 学习跨格式的统一验证-修复循环

前置知识

本章涉及 Skill 渐进式知识管理的通用原理,建议先阅读:

下文假设你已理解上述概念,直接聚焦文档生成技能的具体实现。


项目实践

技术选型矩阵

Anthropic 对四种文档格式采用了不同的技术栈:

格式新建编辑读取转换
DOCXdocx-js (npm)XML 解包 + 编辑 + 重打包pandoc / 解包LibreOffice → PDF
PDF-表单处理-pdftoppm → 图片
PPTXpptxgenjs解包 + 编辑 XML + 重打包-LibreOffice → PDF
XLSXxlsx 库xlsx 库直接修改xlsx 库读取-

核心洞察:所有可编辑格式(DOCX/PPTX)都遵循相同的 unpack → edit → pack 三段式工作流。这是因为 .docx.pptx 本质都是 ZIP 归档包含 XML 文件。

unpack → edit → pack 三段式工作流

unpack.py 做了什么

  1. 提取 ZIP 归档中的 XML 文件
  2. 美化打印(pretty-print)XML
  3. 合并相邻的 runs(merge adjacent runs)——这是一个关键优化,因为 Word 文档中经常存在被意外拆分的 runs
  4. 将智能引号转换为 XML 实体(“ 等),确保编辑时不会被破坏

docx-js 关键规则(新建模式)

DOCX 技能中列出了 13 条关键规则,以下是最常踩坑的几条:

规则原因后果
页面尺寸必须显式设置docx-js 默认 A4美国文档会变成 A4 尺寸
绝不用 \n必须用 separate Paragraph\n 创建无效 XML
绝不用 unicode 子弹必须用 LevelFormat.BULLET手动子弹在不同渲染器中不一致
表格需双宽度columnWidths + 单元格 width缺少任一维度导致渲染错误
WidthType.DXA 而非 PERCENTAGEGoogle Docs 不支持百分比宽度百分比在 Google Docs 中破坏
ShadingType.CLEAR 而非 SOLIDSOLID 产生黑色背景表格变成全黑
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 后重打包,文档格式损坏。

规避策略

  1. unpack 时使用 --merge-runs false 跳过 run 合并(保留原始结构)
  2. 编辑时替换整个 <w:r> 元素,不要在 run 内注入跟踪修改标签
  3. pack 时传入 --original document.docx 保留原始关系引用

XLSX 公式引擎

问题:直接修改单元格值后公式不自动计算。

规避策略:xlsx 库直接修改时,需要手动触发公式重新计算。


设计取舍

为什么新建和编辑使用完全不同的技术栈?

优势:docx-js 对新文档更可控(从代码生成);XML 编辑对已有文档更保真(保留所有原始格式)。 代价:开发者需要学习两套工具链。 Anthropic 的选择:两套工具链都是最优解——没有一种工具能同时做好新建和编辑。


参考来源