Skip to content

Claude 官方 DOCX Skill 深度解析

技术栈对比速查表

对比维度docx-jspython-docx / Document 类pandocLibreOfficePoppler
语言JavaScript/TypeScriptPythonHaskell (CLI)C++ (CLI)C (CLI)
运行环境Node.js / 浏览器Python 3.x终端命令行终端命令行终端命令行
主要用途创建新文档编辑/追踪修改/批注文本提取/格式转换DOCX → PDFPDF → 图片
⭐ MD → DOCX✅ 需编程构建✅ 需编程构建一键转换⚠️ 需先转 HTML❌ 不支持
适用场景从零生成 Word修改现有文档读取文档内容文档预览可视化对比
支持追踪修改❌ 不支持✅ 完整支持✅ 可读取--
支持批注❌ 不支持✅ 完整支持✅ 可读取--
保持原格式- (新建文档)✅ 完整保持❌ 转为纯文本✅ 高保真-
API 风格声明式、直观命令式、DOM 操作CLI 参数CLI 参数CLI 参数
学习曲线⭐⭐ 简单⭐⭐⭐ 中等⭐ 简单⭐ 简单⭐ 简单
安装方式npm install docxpip install defusedxmlapt install pandocapt install libreofficeapt install poppler-utils
核心命令/APIPacker.toBuffer()Document().save()pandoc x.docx -o x.mdsoffice --convert-to pdfpdftoppm -jpeg
输出格式.docx 二进制.docx 二进制Markdown/HTML/等PDFJPEG/PNG
Claude 环境✅ 沙箱可执行✅ 沙箱可执行✅ 预装可用✅ 预装可用✅ 预装可用
API 调用环境❌ 需后端执行❌ 需后端执行❌ 需后端执行❌ 需后端执行❌ 需后端执行

场景选择指南

你想做什么首选工具备选方案命令/说明
MD → DOCX (简单)pandoc-pandoc input.md -o output.docx
MD → DOCX (精美排版)docx-jspython-docx需编程,可控制样式/页眉/目录
修改合同/保留格式python-docx-保持原文档所有格式
法律红线审阅python-docx-<w:ins>/<w:del> 追踪修改
添加审阅批注python-docx-操作 comments.xml
提取文档文本pandocpython-docxpandoc x.docx -o x.md
文档转 PDFLibreOffice-soffice --convert-to pdf
PDF 转图片预览PopplerImageMagickpdftoppm -jpeg -r 150

核心功能概览

Claude 官方 DOCX Skill 提供了 7 大核心功能,覆盖 Word 文档处理的完整生命周期:

text
┌─────────────────────────────────────────────────────────────────────────┐
│                     DOCX Skill 核心功能矩阵                              │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐                │
│   │  1. 创建    │    │  2. 编辑    │    │  3. 分析    │                │
│   │   新文档    │    │  现有文档   │    │  文档内容   │                │
│   │  (docx-js)  │    │  (Python)   │    │  (pandoc)   │                │
│   └─────────────┘    └─────────────┘    └─────────────┘                │
│                                                                         │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐                │
│   │  4. 追踪    │    │  5. 添加    │    │  6. 文档    │                │
│   │   修改      │    │   批注      │    │   验证      │                │
│   │ (Redlining) │    │ (Comments)  │    │  (Schema)   │                │
│   └─────────────┘    └─────────────┘    └─────────────┘                │
│                                                                         │
│   ┌─────────────┐                                                       │
│   │  7. 转换    │                                                       │
│   │  为图片     │                                                       │
│   │ (可视化)    │                                                       │
│   └─────────────┘                                                       │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

功能详解

序号功能名称技术实现典型场景
1创建新文档JavaScript docx从 Markdown/文本生成专业 Word 文档
2编辑现有文档Python Document修改已有文档的内容、格式、结构
3分析文档内容pandoc 转 Markdown提取文本、理解文档结构、读取批注
4追踪修改OOXML <w:ins>/<w:del>法律合同审阅、多人协作编辑
5添加批注comments.xml 操作文档审核、反馈意见、代码审查报告
6文档验证XSD Schema + 红线验证确保文档符合 OOXML 标准、可正常打开
7转换为图片LibreOffice + pdftoppm文档可视化预览、截图对比

技术栈分工

text
创建文档 ──────────────────> docx-js (JavaScript/TypeScript)
                            ├── Document, Paragraph, TextRun
                            ├── Table, TableRow, TableCell
                            ├── 样式系统、页眉页脚
                            └── Packer.toBuffer() 输出

编辑/追踪/批注 ────────────> Python Document 类
                            ├── 解包 .docx 为 XML 目录
                            ├── DOM 操作 + 自动属性注入
                            ├── 追踪修改 (ins/del 标签)
                            ├── 批注管理 (comments.xml)
                            └── 重新打包 + 验证

文本提取 ─────────────────> pandoc
                            └── pandoc --track-changes=all file.docx -o output.md

文档转图片 ────────────────> LibreOffice + Poppler
                            ├── soffice --convert-to pdf
                            └── pdftoppm -jpeg -r 150

为什么需要两套技术栈?

场景选择原因
创建新文档docx-jsAPI 简洁直观,适合构建文档结构
编辑现有文档Python需要保持原有格式、处理复杂 XML 结构
追踪修改Python需要精确操作 XML 节点,保持文档完整性

设计哲学:创建用声明式 API(docx-js),编辑用命令式操作(Python DOM)。各取所长,互补优势。

docx-js 运行环境详解

问题:JavaScript 代码在哪里运行?

docx-js 是一个 Node.js 库,需要 JavaScript 运行时来执行。它可以在以下环境运行:

text
┌─────────────────────────────────────────────────────────────────┐
│                   docx-js 可运行的环境                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────────┐   ┌─────────────────┐                    │
│   │  Node.js 服务端  │   │  浏览器端        │                    │
│   │  (后端运行)      │   │  (前端运行)      │                    │
│   └─────────────────┘   └─────────────────┘                    │
│          │                      │                               │
│          ▼                      ▼                               │
│   Packer.toBuffer()      Packer.toBlob()                       │
│   → 写入文件系统           → 触发下载                            │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

在 claude.ai 中如何运行

Claude 有内置的代码执行沙箱(类似 Node.js 环境),可以直接执行 JavaScript:

text
用户请求 → Claude 生成 JS 代码 → 沙箱执行 → 生成 .docx → Artifacts 下载

在 FastAPI + Next.js 环境中的 3 种方案

方案 A:利用 Next.js 的 API Routes(推荐)

Next.js 本身就运行在 Node.js 上,所以可以直接使用 docx-js:

text
┌──────────────────────────────────────────────────────────────┐
│                        方案 A 架构                            │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   浏览器                                                      │
│      │                                                       │
│      │ POST /api/generate-docx                               │
│      ▼                                                       │
│   ┌──────────────────────────────────────────┐              │
│   │         Next.js API Route                │              │
│   │         (Node.js 环境)                   │              │
│   │                                          │              │
│   │   import { Document, Packer } from 'docx'│              │
│   │   const doc = new Document({...})        │              │
│   │   const buffer = await Packer.toBuffer() │              │
│   │   return new Response(buffer)            │              │
│   └──────────────────────────────────────────┘              │
│                                                              │
└──────────────────────────────────────────────────────────────┘

代码示例(App Router):

javascript
// app/api/generate-docx/route.js
import { Document, Packer, Paragraph, TextRun, HeadingLevel } from 'docx';

export async function POST(request) {
  const { title, content } = await request.json();

  const doc = new Document({
    sections: [{
      children: [
        new Paragraph({
          heading: HeadingLevel.HEADING_1,
          children: [new TextRun({ text: title, bold: true })]
        }),
        new Paragraph({
          children: [new TextRun(content)]
        })
      ]
    }]
  });

  const buffer = await Packer.toBuffer(doc);

  return new Response(buffer, {
    headers: {
      'Content-Type': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'Content-Disposition': 'attachment; filename="document.docx"'
    }
  });
}
方案 B:在 FastAPI 用 python-docx 替代

如果你更倾向于把逻辑集中在 FastAPI,可以用 python-docx 替代 docx-js

python
# FastAPI 后端
from docx import Document
from docx.shared import Pt
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import io

app = FastAPI()

@app.post("/generate-docx")
async def generate_docx(title: str, content: str):
    doc = Document()
    doc.add_heading(title, level=1)
    doc.add_paragraph(content)

    buffer = io.BytesIO()
    doc.save(buffer)
    buffer.seek(0)

    return StreamingResponse(
        buffer,
        media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        headers={"Content-Disposition": "attachment; filename=document.docx"}
    )
方案 C:独立 Node.js 微服务

如果需要复杂的文档生成逻辑,可以部署独立的 Node.js 服务:

text
┌─────────────────────────────────────────────────────────────┐
│                       方案 C 架构                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Next.js 前端 ──> FastAPI 后端 ──> Node.js 文档服务         │
│                         │                │                  │
│                         │                ▼                  │
│                   Claude API       docx-js 生成文档          │
│                   (内容生成)       (文件生成)                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

方案选择建议

你的情况推荐方案原因
简单文档生成方案 ANext.js 本身就是 Node.js,零额外配置
逻辑集中在 Python方案 Bpython-docx 功能完整,无需跨语言调用
需要 docx-js 高级特性方案 C独立服务,便于维护和扩展
追踪修改/红线审阅方案 B必须用 Python,docx-js 不支持此功能

典型使用场景示例

场景 1:从 Markdown 生成专业报告

用户需求:"帮我把这份 Markdown 格式的周报转成 Word 文档,要有目录、页眉页脚"

Claude 执行流程

text
用户提供 Markdown ──> Claude 读取 docx-js.md 学习 API


                    生成 JavaScript 代码


    new Document({
      sections: [{
        headers: { default: new Header({...}) },
        children: [
          new TableOfContents("目录"),
          new Paragraph({ heading: HeadingLevel.HEADING_1, ... }),
          ...
        ]
      }]
    })


              Packer.toBuffer(doc) ──> 输出 .docx 文件

场景 2:法律合同红线审阅

用户需求:"审阅这份合同,把付款期限从 30 天改成 45 天,保留修改痕迹"

Claude 执行流程

text
收到合同 .docx ──> 用 pandoc 转 Markdown 理解内容


              python unpack.py contract.docx ./unpacked


    使用 Document 类定位文本:
    node = doc["word/document.xml"].get_node(contains="30 days")


    创建追踪修改:
    <w:del><w:delText>30</w:delText></w:del>
    <w:ins><w:t>45</w:t></w:ins>


              python pack.py ./unpacked reviewed.docx

Word 中的效果

  • 30 天 → 45 天(带修改痕迹,可接受/拒绝)

场景 3:批量添加审阅批注

用户需求:"帮我审阅这份技术文档,在有问题的地方添加批注"

Claude 执行流程

python
doc = Document('unpacked', author="Technical Reviewer")

# 找到有问题的段落
para1 = doc["word/document.xml"].get_node(tag="w:p", contains="deprecated API")
doc.add_comment(start=para1, end=para1, text="这个 API 已废弃,建议使用 v2 版本")

para2 = doc["word/document.xml"].get_node(tag="w:p", contains="hardcoded value")
doc.add_comment(start=para2, end=para2, text="建议将硬编码改为配置项")

doc.save()

场景 4:提取文档内容进行分析

用户需求:"帮我总结这份 50 页 Word 文档的要点"

Claude 执行流程

bash
# 提取文本(保留结构)
pandoc document.docx -o content.md

# 如果需要看批注
pandoc --track-changes=all document.docx -o content_with_comments.md

然后 Claude 阅读 Markdown 内容,生成摘要。

场景 5:文档可视化对比

用户需求:"帮我对比修改前后的文档差异"

Claude 执行流程

bash
# 将两个版本转为图片
soffice --headless --convert-to pdf original.docx
soffice --headless --convert-to pdf modified.docx

pdftoppm -jpeg -r 150 original.pdf original-page
pdftoppm -jpeg -r 150 modified.pdf modified-page

# Claude 可以直接查看图片进行可视化对比

场景适用性速查表

你想做什么使用哪个功能关键命令/API
Markdown → Word创建新文档new Document({ sections: [...] })
修改合同条款追踪修改doc.replace_node() + <w:ins>/<w:del>
添加审阅意见添加批注doc.add_comment(start, end, text)
提取文档文本文本提取pandoc file.docx -o output.md
查看文档样式原始 XMLunpack.py → 查看 word/styles.xml
批量替换内容编辑文档doc.get_node() + doc.replace_node()
文档截图转换图片soffice + pdftoppm

核心问题解答:为什么在不同环境中效果差异巨大?

问题现象

在 claude.ai 官方聊天界面中使用 docx skill 转换 Markdown 文档效果非常好,但在 FastAPI + Next.js 的应用环境中调用 Claude API 时,效果却特别差。

根本原因分析

这个问题的本质在于:Skill 不仅仅是提示词,它是「提示词 + 可执行代码 + 运行时环境」的完整组合。

1. claude.ai 环境的特殊能力

在 claude.ai 官方界面中,Claude 具备以下能力:

text
┌─────────────────────────────────────────────────────────────┐
│                    claude.ai 环境                            │
├─────────────────────────────────────────────────────────────┤
│  ✓ Computer Use 功能 - 可以执行终端命令                       │
│  ✓ Artifacts 功能 - 可以创建和下载文件                        │
│  ✓ 代码执行沙箱 - 可以运行 Python/JavaScript                  │
│  ✓ 完整的文件系统访问                                         │
│  ✓ 预装的依赖环境(docx、pandoc 等)                          │
└─────────────────────────────────────────────────────────────┘

当你在 claude.ai 中要求转换文档时,Claude 实际上会:

  1. 读取 Skill 文档了解 docx-js 库的 API
  2. 生成并执行 JavaScript 代码
  3. 调用 Packer.toBuffer() 生成真正的 .docx 二进制文件
  4. 通过 Artifacts 提供下载

2. FastAPI + Next.js API 环境的局限

text
┌─────────────────────────────────────────────────────────────┐
│               FastAPI + Next.js API 环境                     │
├─────────────────────────────────────────────────────────────┤
│  ✗ 无代码执行能力 - Claude 只能生成代码文本                   │
│  ✗ 无文件系统访问 - 无法创建或操作文件                        │
│  ✗ 纯文本输入输出 - 无法处理二进制数据                        │
│  ✗ 无运行时环境 - 没有 Node.js/Python 执行器                  │
└─────────────────────────────────────────────────────────────┘

在 API 调用场景中,Claude 只能:

  1. 理解你的需求
  2. 生成转换代码的文本
  3. 返回代码字符串——但无法执行

这就是为什么"效果差"的真正原因:你得到的只是代码,而不是转换后的文件。

3. 正确的解决方案架构

要在 FastAPI + Next.js 环境中实现类似效果,需要采用以下架构:

text
┌─────────────────────────────────────────────────────────────┐
│                    推荐的解决方案架构                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   用户请求                                                   │
│      │                                                      │
│      ▼                                                      │
│   ┌──────────────────┐                                      │
│   │   Next.js 前端    │                                      │
│   └────────┬─────────┘                                      │
│            │                                                │
│            ▼                                                │
│   ┌──────────────────┐      ┌──────────────────┐           │
│   │   FastAPI 后端    │──────│  Claude API      │           │
│   │                  │      │  (内容结构生成)   │           │
│   └────────┬─────────┘      └──────────────────┘           │
│            │                                                │
│            │  Claude 返回结构化内容(JSON/Markdown)          │
│            │                                                │
│            ▼                                                │
│   ┌──────────────────┐                                      │
│   │  文档转换服务     │  ← 使用 python-docx 或 docx-js        │
│   │  (后端执行代码)   │                                      │
│   └────────┬─────────┘                                      │
│            │                                                │
│            ▼                                                │
│      .docx 文件输出                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

关键点:将 Claude 的角色定位为「内容结构生成器」,而非「文件转换执行器」。

4. 具体实现建议

方案 A:Python 后端实现
python
# FastAPI 后端示例
from fastapi import FastAPI
from docx import Document
from docx.shared import Inches, Pt
import anthropic

app = FastAPI()

@app.post("/convert-md-to-docx")
async def convert_md_to_docx(markdown_content: str):
    # 1. 使用 Claude 解析 Markdown 结构
    client = anthropic.Anthropic()
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        messages=[{
            "role": "user",
            "content": f"""将以下 Markdown 解析为结构化 JSON 格式:
            {markdown_content}

            返回格式:{{"elements": [{{"type": "heading1|paragraph|list", "content": "..."}}]}}"""
        }]
    )

    # 2. 使用 python-docx 创建实际文档
    doc = Document()
    structure = json.loads(response.content[0].text)

    for element in structure["elements"]:
        if element["type"] == "heading1":
            doc.add_heading(element["content"], level=1)
        elif element["type"] == "paragraph":
            doc.add_paragraph(element["content"])
        # ... 处理其他类型

    # 3. 返回文件
    doc.save("output.docx")
    return FileResponse("output.docx")
方案 B:Node.js 中间服务
javascript
// 使用 docx-js 库
const { Document, Packer, Paragraph, TextRun } = require('docx');

async function convertMarkdownToDocx(markdownContent, claudeGeneratedStructure) {
    const doc = new Document({
        sections: [{
            children: claudeGeneratedStructure.elements.map(elem => {
                if (elem.type === 'paragraph') {
                    return new Paragraph({
                        children: [new TextRun(elem.content)]
                    });
                }
                // ... 处理其他类型
            })
        }]
    });

    return await Packer.toBuffer(doc);
}

Skill 概述

目标用途

Claude 官方 DOCX Skill 是一个全面的 Word 文档处理工具包,专门设计用于让 Claude 能够:

功能类别具体能力
创建文档从零开始生成专业格式的 .docx 文件
编辑文档修改现有 Word 文档的内容和格式
追踪修改实现法律/商务文档的红线审阅(Redlining)
添加批注在文档中添加评论和回复
格式保持在编辑过程中保持原有格式不被破坏
文本提取从 Word 文档中提取纯文本内容

核心价值

这个 Skill 解决了一个关键问题:Word 文档(.docx)本质上是 ZIP 压缩包内的 XML 文件集合,直接操作非常复杂。这个 Skill 封装了所有底层细节,让 Claude 可以像专业文档处理软件一样工作。


架构分析

文件结构总览

text
docx/
├── SKILL.md              # 主入口文档,定义工作流程和决策树
├── LICENSE.txt           # 许可证文件
├── docx-js.md            # JavaScript/TypeScript 文档创建教程
├── ooxml.md              # Office Open XML 技术参考和 Python 库文档
├── ooxml/
│   ├── schemas/          # XML Schema 定义文件
│   └── scripts/
│       ├── pack.py       # 将目录打包为 .docx 文件
│       ├── unpack.py     # 将 .docx 文件解包为目录
│       ├── validate.py   # 文档验证脚本
│       └── validation/   # 验证器模块
└── scripts/
    ├── __init__.py
    ├── document.py       # 核心 Python 库(Document 类)
    ├── utilities.py      # XML 编辑工具(XMLEditor 类)
    └── templates/        # XML 模板文件

工作流程决策树

text
                    ┌─────────────────────────────────┐
                    │        用户请求处理文档          │
                    └─────────────────────────────────┘

                    ┌───────────────┴───────────────┐
                    │         任务类型是什么?        │
                    └───────────────────────────────┘
                    /           |           \
                   /            |            \
                  ▼             ▼             ▼
         ┌──────────┐   ┌──────────┐   ┌──────────┐
         │ 读取/分析 │   │  创建新   │   │ 编辑现有 │
         └──────────┘   └──────────┘   └──────────┘
              │              │              │
              ▼              ▼              │
         ┌──────────┐   ┌──────────┐       │
         │  pandoc  │   │ docx-js  │       │
         │  转 MD   │   │ (JS/TS)  │       │
         └──────────┘   └──────────┘       │

              ┌────────────────────────────┤
              │                            │
              ▼                            ▼
    ┌─────────────────────┐    ┌─────────────────────┐
    │    自己的文档 +      │    │  他人的文档 / 法律  │
    │    简单修改          │    │  / 商务 / 政府文档  │
    └─────────────────────┘    └─────────────────────┘
              │                            │
              ▼                            ▼
    ┌─────────────────────┐    ┌─────────────────────┐
    │   基础 OOXML 编辑    │    │   红线审阅工作流    │
    │   (Document 类)     │    │   (Redlining)       │
    └─────────────────────┘    └─────────────────────┘

核心组件详解

1. SKILL.md - 主入口文档

这是整个 Skill 的"大脑",定义了:

  • 工作流程决策树:根据任务类型选择正确的工具
  • 文本提取方法:使用 pandoc 转换为 Markdown
  • 文档创建流程:指向 docx-js.md
  • 文档编辑流程:指向 ooxml.md
  • 红线审阅流程:详细的追踪修改实现步骤

关键指令特点:

markdown
# 强制性阅读要求
1. **MANDATORY - READ ENTIRE FILE**: Read [`docx-js.md`](docx-js.md) (~500 lines)
   completely from start to finish. **NEVER set any range limits when reading this file.**

这种设计确保 Claude 在执行任务前完整理解技术细节。

2. docx-js.md - JavaScript 文档创建库

这份约 350 行的技术文档教会 Claude 如何使用 docx npm 包创建 Word 文档。

核心导入

javascript
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
        ImageRun, Header, Footer, AlignmentType, PageOrientation, LevelFormat,
        ExternalHyperlink, InternalHyperlink, TableOfContents, HeadingLevel,
        BorderStyle, WidthType, TabStopType, UnderlineType, ShadingType,
        VerticalAlign, SymbolRun, PageNumber, FootnoteReferenceRun,
        Footnote, PageBreak } = require('docx');

关键编码规则

规则正确做法错误做法
换行符使用单独的 Paragraph 元素使用 \n 字符
列表使用 LevelFormat.BULLET 常量使用 Unicode 符号
分页符new Paragraph({ children: [new PageBreak()] })单独的 new PageBreak()
表格阴影ShadingType.CLEARShadingType.SOLID(导致黑色背景)
图片必须指定 type: "png"省略 type 参数

样式系统

javascript
const doc = new Document({
  styles: {
    default: { document: { run: { font: "Arial", size: 24 } } },
    paragraphStyles: [
      { id: "Heading1", name: "Heading 1", basedOn: "Normal",
        run: { size: 32, bold: true },
        paragraph: { spacing: { before: 240, after: 240 }, outlineLevel: 0 } },
      // outlineLevel 对目录功能至关重要
    ]
  }
});

3. ooxml.md - Office Open XML 技术参考

约 610 行的深度技术文档,涵盖:

DOCX 文件的本质结构

text
document.docx (实际是 ZIP 文件)
├── [Content_Types].xml     # 内容类型声明
├── _rels/
│   └── .rels              # 关系定义
└── word/
    ├── document.xml       # 主文档内容
    ├── styles.xml         # 样式定义
    ├── settings.xml       # 文档设置
    ├── comments.xml       # 批注内容
    ├── numbering.xml      # 列表编号定义
    ├── media/             # 嵌入的图片等媒体
    └── _rels/
        └── document.xml.rels  # 文档关系

XML 元素排序规则

OOXML 有严格的元素顺序要求:

xml
<!-- w:pPr 内的元素必须按此顺序 -->
<w:pPr>
  <w:pStyle>      <!-- 1. 段落样式 -->
  <w:numPr>       <!-- 2. 编号属性 -->
  <w:spacing>     <!-- 3. 间距 -->
  <w:ind>         <!-- 4. 缩进 -->
  <w:jc>          <!-- 5. 对齐方式 -->
</w:pPr>

追踪修改的 XML 模式

xml
<!-- 插入内容 -->
<w:ins w:id="1" w:author="Claude" w:date="2025-01-15T10:00:00Z">
  <w:r><w:t>inserted text</w:t></w:r>
</w:ins>

<!-- 删除内容 -->
<w:del w:id="2" w:author="Claude" w:date="2025-01-15T10:00:00Z">
  <w:r><w:delText>deleted text</w:delText></w:r>
</w:del>

4. scripts/document.py - 核心 Python 库

这是一个约 1277 行的高级封装库,提供了操作 DOCX 文件的完整 API。

Document 类

python
from scripts.document import Document

# 初始化(自动创建临时工作目录、设置基础设施)
doc = Document('unpacked_directory')
doc = Document('unpacked_directory', author="John Doe", initials="JD")
doc = Document('unpacked_directory', track_revisions=True)

# 通过下标访问任何 XML 文件
node = doc["word/document.xml"].get_node(tag="w:p", contains="some text")
node = doc["word/comments.xml"].get_node(tag="w:comment", attrs={"w:id": "0"})

# 添加批注
doc.add_comment(start=node1, end=node2, text="这里需要修改")
doc.reply_to_comment(parent_comment_id=0, text="同意这个修改")

# 保存(自动验证)
doc.save()

DocxXMLEditor 类

继承自 XMLEditor,添加了自动属性注入功能:

python
# 自动注入的属性包括:
# - w:rsidR, w:rsidRDefault, w:rsidP (段落和文本运行)
# - w:id, w:author, w:date (追踪修改元素)
# - xml:space="preserve" (含空格的文本)

关键方法:

方法用途
get_node()通过标签、属性、行号、文本内容查找节点
replace_node()替换节点内容
insert_after()在节点后插入内容
insert_before()在节点前插入内容
suggest_deletion()将内容标记为删除(追踪修改)
revert_insertion()拒绝他人的插入
revert_deletion()拒绝他人的删除

追踪修改示例

python
# 最小化编辑:将 "30 days" 改为 "60 days"
node = doc["word/document.xml"].get_node(tag="w:r", contains="within 30 days")
rpr = tags[0].toxml() if (tags := node.getElementsByTagName("w:rPr")) else ""

replacement = f'''
<w:r w:rsidR="00XYZ789">{rpr}<w:t>within </w:t></w:r>
<w:del><w:r>{rpr}<w:delText>30</w:delText></w:r></w:del>
<w:ins><w:r>{rpr}<w:t>60</w:t></w:r></w:ins>
<w:r w:rsidR="00XYZ789">{rpr}<w:t> days</w:t></w:r>
'''

doc["word/document.xml"].replace_node(node, replacement)

5. scripts/utilities.py - XML 编辑工具

约 375 行的底层 XML 操作工具。

XMLEditor 类核心功能

python
class XMLEditor:
    def __init__(self, xml_path):
        """解析 XML 并跟踪每个元素的行号位置"""

    def get_node(self, tag, attrs=None, line_number=None, contains=None):
        """多条件节点查找"""

    def replace_node(self, elem, new_content):
        """替换节点"""

    def insert_after(self, elem, xml_content):
        """节点后插入"""

    def save(self):
        """保存修改"""

特色功能:行号追踪解析器

python
def _create_line_tracking_parser():
    """
    创建一个 SAX 解析器,为每个元素记录原始行号和列号。
    这使得可以通过 Read 工具输出的行号精确定位元素。
    """

6. ooxml/scripts/ - 打包解包工具

unpack.py - 解包 DOCX

bash
python ooxml/scripts/unpack.py document.docx ./unpacked

功能:

  • 将 .docx ZIP 归档解压到目录
  • 格式化 XML 文件便于阅读
  • 建议使用的 RSID 值

pack.py - 打包 DOCX

bash
python ooxml/scripts/pack.py ./unpacked output.docx

功能:

  • 将目录重新打包为 .docx 文件
  • 可选的 Schema 验证

红线审阅(Redlining)工作流

这是这个 Skill 最复杂也最有价值的功能,专为法律、商务、政府文档设计。

完整流程

text
1. 获取 Markdown 表示
   └─> pandoc --track-changes=all input.docx -o current.md

2. 识别并分组修改
   └─> 按章节、类型或复杂度分批(每批 3-10 个修改)

3. 读取文档并解包
   └─> python ooxml/scripts/unpack.py input.docx ./unpacked

4. 分批实现修改
   └─> 创建 Python 脚本使用 Document 类
   └─> 测试每批修改后再继续

5. 打包文档
   └─> python ooxml/scripts/pack.py ./unpacked reviewed.docx

6. 最终验证
   └─> pandoc --track-changes=all reviewed.docx -o verification.md
   └─> 检查所有修改是否正确应用

修改原则:最小化、精确

python
# 错误做法 - 替换整句
'<w:del><w:delText>The term is 30 days.</w:delText></w:del>'
'<w:ins><w:t>The term is 60 days.</w:t></w:ins>'

# 正确做法 - 只标记变化的部分
'<w:r><w:t>The term is </w:t></w:r>'
'<w:del><w:r><w:delText>30</w:delText></w:r></w:del>'
'<w:ins><w:r><w:t>60</w:t></w:r></w:ins>'
'<w:r><w:t> days.</w:t></w:r>'

依赖项

工具安装命令用途
pandocsudo apt-get install pandoc文本提取和格式转换
docx (npm)npm install -g docxJavaScript 创建新文档
defusedxmlpip install defusedxml安全的 XML 解析
LibreOfficesudo apt-get install libreofficePDF 转换
Popplersudo apt-get install poppler-utilsPDF 转图片

设计亮点总结

  1. 分层架构:高级 Python API → 底层 XML 操作 → 原始文件打包
  2. 自动化基础设施:Document 类自动处理 RSID、命名空间、关系文件
  3. 验证机制:Schema 验证 + 红线验证确保文档完整性
  4. 渐进式学习:SKILL.md 作为入口,按需深入具体技术文档
  5. 防错设计:详尽的"错误做法 vs 正确做法"对比示例

在自定义应用中的最佳实践

如果你希望在 FastAPI + Next.js 应用中实现类似功能,建议:

  1. 将 Claude 用于内容生成,而非文件操作
  2. 在后端实现文件转换逻辑(使用 python-docx 或 docx-js)
  3. 定义清晰的 JSON 中间格式作为 Claude 输出和后端转换之间的桥梁
  4. 参考这个 Skill 的 docx-js.md 学习正确的 docx 库用法
  5. 考虑使用 pandoc 作为通用文档转换器
python
# 推荐的 FastAPI 服务架构
@app.post("/generate-docx")
async def generate_docx(content_request: ContentRequest):
    # Step 1: Claude 生成结构化内容
    structure = await claude.generate_document_structure(content_request)

    # Step 2: 后端执行实际转换
    docx_bytes = document_service.create_docx(structure)

    # Step 3: 返回文件
    return Response(
        content=docx_bytes,
        media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
    )

这样可以充分利用 Claude 的语言理解能力,同时规避 API 调用环境无法执行代码的限制。

基于 MIT 许可证发布。内容版权归作者所有。