> ## Documentation Index
> Fetch the complete documentation index at: https://docs.profy.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Word 文档

> profy-docx — 创建、编辑、分析 .docx：docx-js 生成、拆包改 XML、跨 run 文本替换、修订与批注

# Word 文档（profy-docx）

创建、编辑、分析 Word 文档。理解这个能力的关键是先接受一个事实：**`.docx` 是一个装着 XML 的 ZIP 包**。所有看起来奇怪的约束，都来自这个结构。

## 激活方式

`profy-docx` 是 `user_selectable: false`——**自动可用，不需要勾选**。

```json theme={null}
{ "id": "profy-docx", "activation": { "user_selectable": false } }
```

`contracts` 只有 `skills: ["skills/"]`，**没有 tools**。专家在沙箱里用 `bash` 跑脚本，技能文档规定跑法。

触发词包括：Word 文档、`.docx`、要求产出带目录/标题/页码/信头的正式文档，以及从 docx 提取或重排内容、图片替换、查找替换、修订与批注处理。**PDF、电子表格、Google Docs 不走这条路径。**

## 三条主路径

| 任务     | 做法                    |
| ------ | --------------------- |
| 读取分析内容 | `pandoc`，或拆包读原始 XML   |
| 新建文档   | `docx-js`（JavaScript） |
| 编辑已有文档 | 拆包 → 改 XML → 重新打包     |

### 读取

```bash theme={null}
# 带修订标记的文本提取
pandoc --track-changes=all document.docx -o output.md

# 原始 XML 访问
python scripts/office/unpack.py document.docx unpacked/
```

### 旧版 .doc 转换

```bash theme={null}
python scripts/office/soffice.py --headless --convert-to docx document.doc
```

`.doc` 是完全不同的二进制格式，必须先转换才能编辑。

### 转成图片（用于视觉检查）

```bash theme={null}
python scripts/office/soffice.py --headless --convert-to pdf document.docx
pdftoppm -jpeg -r 150 document.pdf page
```

### 接受修订

```bash theme={null}
python scripts/accept_changes.py input.docx output.docx
```

需要 LibreOffice。产出的是所有修订均已接受的干净文档。

## 文本替换：用现成脚本，别自己写

```bash theme={null}
# 替换第一处
python scripts/office/docx_replace.py --file document.docx --search "旧文本" --replace "新文本"

# 替换全部
python scripts/office/docx_replace.py --file document.docx --search "旧" --replace "新" --all

# 输出到新文件
python scripts/office/docx_replace.py --file document.docx --search "旧" --replace "新" --output result.docx

# 限定段落（0 起）
python scripts/office/docx_replace.py --file document.docx --search "旧" --replace "新" --paragraph 3
```

退出码：

| 码   | 含义                |
| --- | ----------------- |
| `0` | 成功且已验证            |
| `1` | 未找到文本（stderr 有提示） |
| `2` | 验证失败              |

<Warning>
  **不要为简单查找替换手写 python-docx 脚本。** Word 会把一句话拆进多个 `run`（比如中间有一个字加粗，或者拼写检查插了标记），你搜索的字符串在 XML 里根本不是连续的。手写脚本因此**静默失败**——不报错，就是没替换成功。`docx_replace.py` 处理了跨 run 边界并在替换后验证结果，退出码 `2` 就是这道验证在起作用。
</Warning>

## 新建文档：docx-js 的关键约束

```bash theme={null}
npm install -g docx
```

这些约束不是风格建议，每一条都对应一种"生成出来打不开或者显示错乱"的具体故障。

### 结构类

| 约束                             | 说明                                                                                   |
| ------------------------------ | ------------------------------------------------------------------------------------ |
| 显式设置页面尺寸                       | docx-js 默认 A4；美式文档要用 US Letter（12240 × 15840 DXA）                                    |
| 横向要传纵向尺寸                       | docx-js 内部会交换宽高：短边传 `width`、长边传 `height`，再设 `orientation: PageOrientation.LANDSCAPE` |
| 绝不使用 `\n`                      | 换行要用独立的 `Paragraph` 元素                                                               |
| `PageBreak` 必须包在 `Paragraph` 里 | 独立放置会生成非法 XML                                                                        |
| `ImageRun` 必须指定 `type`         | png / jpg 等，不能省                                                                      |

### 列表与表格

| 约束                      | 说明                                                                              |
| ----------------------- | ------------------------------------------------------------------------------- |
| 绝不使用 unicode 项目符号       | 必须用 `LevelFormat.BULLET` 配合 numbering 配置                                        |
| 表格宽度必须用 DXA             | 不要用 `WidthType.PERCENTAGE`，在 Google Docs 里会坏                                    |
| 表格需要双份宽度                | `columnWidths` 数组与单元格 `width` 都要有，且两者必须一致                                       |
| 表格总宽 = 各列宽之和            | DXA 下必须精确相加                                                                     |
| 单元格必须加内边距               | `margins: { top: 80, bottom: 80, left: 120, right: 120 }`                       |
| 底纹用 `ShadingType.CLEAR` | 不要用 SOLID                                                                       |
| **绝不用表格画分隔线**           | 单元格有最小高度，会渲染成空盒子（页眉页脚里同样如此）。要横线就在 `Paragraph` 上加 `border.bottom`；两栏页脚用制表位，不要用表格 |

### 目录

| 约束                  | 说明                        |
| ------------------- | ------------------------- |
| 目录只认 `HeadingLevel` | 标题段落上不能挂自定义样式             |
| 覆盖内置样式要用精确 ID       | `"Heading1"`、`"Heading2"` |
| 必须带 `outlineLevel`  | 目录需要，H1 为 0，H2 为 1，依此类推   |

## 支持的排版能力

页面尺寸、样式覆盖、多级列表、表格、图片、分页符、超链接、脚注、制表位、多栏布局、目录、页眉页脚。

## 边界与失败态

* **`.doc` 必须先转换**，直接编辑会失败。
* **手写替换脚本会静默失败**（见上文 run 边界）。
* **接受修订依赖 LibreOffice**，没有它 `accept_changes.py` 跑不通。
* **拆包改 XML 是有风险的操作**。XML 结构错了 Word 会直接拒绝打开文件而不是宽容降级，所以改完必须验证。
* **表格在不同渲染器上表现不一致**。上面那批约束（DXA、双份宽度、CLEAR 底纹）多数是为了在 Word 之外的 Google Docs、WPS、预览器里也保持正确。

### 排错

| 症状                  | 原因                            | 处理                                  |
| ------------------- | ----------------------------- | ----------------------------------- |
| 替换脚本退出码 1           | 文本没找到，可能被拆进多个 run 或有隐藏字符      | 看 stderr 提示，尝试更短的搜索串                |
| 替换脚本退出码 2           | 替换写入了但验证没通过                   | 文档结构异常，改走拆包路径                       |
| 生成的文档 Word 打不开      | XML 非法，常见于独立的 `PageBreak`     | 把分页符包进 `Paragraph`                  |
| 表格在 Google Docs 里错乱 | 用了百分比宽度                       | 改成 DXA，并确保总宽等于列宽之和                  |
| 目录是空的               | 标题段落挂了自定义样式，或缺 `outlineLevel` | 只用 `HeadingLevel` 并补 `outlineLevel` |
| 页眉里有奇怪的空盒子          | 用表格画了分隔线                      | 换成 `Paragraph` 的下边框                 |

## 验证你的产出

1. 生成后转成图片看一眼：`soffice.py --convert-to pdf` 再 `pdftoppm`。**这一步能抓住绝大多数排版事故**，比读 XML 快得多。
2. 有目录的话，确认目录条目数与实际标题数一致。
3. 有表格的话，在 Google Docs 里也开一次——它对宽度定义最不宽容，能过它基本哪都能过。

## 相关页面

<CardGroup cols={2}>
  <Card title="办公文档总览" href="/zh/documentation/capabilities/office-documents">
    四类文档能力的定位与选型
  </Card>

  <Card title="PDF 文档" href="/zh/documentation/capabilities/office-pdf">
    需要精排交付物时的另一条路径
  </Card>
</CardGroup>

<Note>
  核对日期 2026-08-11。来源：`services/agent-runtime/src/plugins/builtin/docx/plugin.json`、`skills/SKILL.md`、`skills/scripts/office/docx_replace.py`、`skills/scripts/accept_changes.py`、`skills/scripts/office/{unpack,pack,soffice}.py`。
</Note>
