Word 文档

.docx 创建、编辑、读取及视觉验证

默认启用:是docx 技能默认可用,当您提到 Word 文档、.docx 文件、报告、备忘录、信函或模板时会自动触发。无需手动加载。

概述

docx 技能涵盖 Word 文档的完整生命周期:从零创建、编辑现有文件、读取与分析、基于模板生成、修订管理,以及强制性视觉 QA 验证。该技能仅适用于 .docx 文件 — 不包括 PDF、电子表格、HWPX 或 Google Docs。

主要工具是 officecli,一个位于 PATH 上的命令行工具,可处理约 80% 的任务(add、set、remove、validate、query、track-change accept/reject)。对于 officecli 无法处理的任务 — 修订的创建、OMML 公式、批量模式匹配 — 该技能会回退到 scripts/ 中的 Python OOXML 脚本

触发条件

模式示例
文件扩展名.docx、Word 文档
文档类型报告、备忘录、信函、提案、合同
关键词"Word doc"、"template"、"tracked changes"、"table of contents"
韩语触发词"워드 문서"、"보고서 만들어줘"、"문서 작성해줘"

快速参考

任务工具命令模式备注
按现有文档格式化shell + officeclicp source.docx target.docx && officecli open target.docx继承样式/页眉/页脚
创建空白 DOCXofficecliofficecli create report.docx从真实 Office 文件开始
添加段落officecliofficecli add FILE /body --type paragraph --prop text="..."主要写入路径
编辑段落/运行officecliofficecli set FILE /body/p[N] --prop ...精确路径定位
读取文本/大纲/统计officecliofficecli view FILE text模式:text、annotated、outline、stats、issues、html
查询文档officecliofficecli query FILE "p[style=Heading1]"类 CSS 选择器
模板替换officecliofficecli set FILE / --prop find="{{X}}" --prop replace="Y"保留模板结构
验证/问题扫描officecliofficecli validate FILE配合 view FILE issues 使用
接受/拒绝修订officecliofficecli set FILE / --prop accept-changes=all也支持 reject-changes=all
创建修订Python (L3/L4)scripts/docx_cli.py + ooxml/redline_diff.pyofficecli 无法创建 — 只能接受/拒绝
OMML 公式Python (L4)解压 → 注入 <m:oMath> → 重新打包officecli 无法生成 OMML
复杂锚定批注Python (L3)python3 scripts/comment.py IN OUT --text "..." --anchor "..."用于超出 officecli 能力的批注
PDF 转换/视觉 QAsofficesoffice --headless --convert-to pdf FILE基于截图的 QA

"~해줘" 用法示例

"분기 보고서 만들어줘"
从零创建季度报告文档,包含正确的标题层级、目录、表格和专业排版。使用 officecli create → 添加结构 → 验证 → PDF 确认。
"이 문서 형식에 맞춰서 새로 작성해줘"
基于参考文件编辑:复制源文件以继承所有样式、页眉和页脚,然后替换正文内容同时保留文档的视觉标识。请参阅下方的"基于参考文件编辑"工作流。
"이 워드 문서 내용 요약해줘"
使用 officecli view FILE textview FILE outline 读取并分析文档,然后提供标题、关键内容和文档统计信息的结构化摘要。
"변경사항 추적해서 수정해줘"
通过 Python OOXML 脚本创建修订(红线标记),因为 officecli 只能接受/拒绝修订而无法创建修订。会自动升级到 L3/L4。
"문서 템플릿에 데이터 채워줘"
使用 officecli set FILE / --prop find="{{X}}" --prop replace="Y" 进行模板安全替换,在保留模板格式和结构的同时填充占位符。

基于参考文件编辑

当用户说"按照 X.docx 的格式"、"匹配现有样式"、"基于模板",或提供源文件时 — 始终从源文件开始。切勿从零重建。

工作流

  1. 复制源文件: cp source.docx target.docx — 继承所有样式、边距、编号、页眉、页脚
  2. 打开: officecli open target.docx — 守护进程启动;命令立即返回
  3. 仅删除正文内容 — 保留 /styles/numbering/header/footer
  4. 使用现有样式名称添加新段落(例如 --prop style=Heading1)— 样式会自动应用

为什么这很重要

Pandoc 生成的和 Word 生成的文档具有特定的样式 ID(例如 Heading1BodyTextFirstParagraph),这些 ID 对该文档来说是唯一的。添加同名的新样式会导致:

模板优先级

  1. 用户提供的源文件 — 一等模板
  2. tests/fixtures/*.docx — 技能自带的预构建工作示例
  3. officecli create 空白文件 — 仅在无其他选择时使用
# 正确做法:继承 Pandoc 样式
cp Assignment1.docx Assignment2.docx
officecli open Assignment2.docx
officecli remove Assignment2.docx "/body/p[1]"   # 删除旧正文(保留样式/页眉/页脚)
# ... 删除更多段落 ...
officecli add Assignment2.docx /body --type paragraph --prop text="New title" --prop style=Heading1
officecli close Assignment2.docx

# 错误做法:重新创建已存在的样式 -- validate 会失败
officecli add doc.docx /styles --type style --prop name=Heading1 --prop size=20pt ...

升级阶梯

当 officecli 无法完成任务时,按以下顺序升级:

级别何时使用工具
L1 officecli 高层级典型的 add/set/remove 操作officecli add/set/remove/query/view
L2 officecli raw-setXML 注入 — PAGE 字段、fldChar、超链接锚点、自定义属性officecli raw-set FILE PATH --xpath X --action A --xml ...
L3 Python 脚本批量修订操作、添加批注、合并 run、红线验证python3 scripts/*.py
L4 解压 → 编辑 XML → 重新打包OMML 公式、自定义样式注入、模式匹配编辑scripts/docx_cli.py open FILE work/ → 编辑 XML → scripts/docx_cli.py save work/ OUT.docx

升级信号

核心工作流

执行模型

逐条执行命令。不要将所有命令写入 shell 脚本并作为单个块执行。OfficeCLI 是增量式的:每个 addsetremove 都会立即修改文件并返回输出。

  1. 逐条执行命令,然后查看输出。在继续之前检查退出码。
  2. 非零退出码 = 立即停止并修复。不要在损坏状态上继续构建。
  3. 在结构性操作后进行验证。添加样式、表格、图表或节之后,先运行 getvalidate 再在其上继续构建。

读取与分析

officecli view doc.docx text                    # 完整文本提取
officecli view doc.docx text --max-lines 200    # 截断提取
officecli view doc.docx text --start 1 --end 50 # 范围提取
officecli view doc.docx outline                 # 结构:统计、标题、页眉/页脚
officecli view doc.docx annotated               # 每个 run 的样式/字体/大小,公式显示为 LaTeX
officecli view doc.docx stats                   # 段落数、样式/字体分布

元素检查

officecli get doc.docx /                        # 文档根节点(元数据、页面设置)
officecli get doc.docx /body --depth 1           # 列出正文子元素
officecli get doc.docx "/body/p[1]"              # 指定段落
officecli get doc.docx "/body/p[1]/r[1]"         # 指定 run
officecli get doc.docx "/body/tbl[1]" --depth 3  # 表格结构
officecli get doc.docx /styles                   # 样式定义
officecli get doc.docx "/styles/Heading1"        # 指定样式
officecli get doc.docx "/header[1]"              # 页眉/页脚
officecli get doc.docx /numbering                # 编号定义
officecli get doc.docx "/body/p[1]" --json       # 用于脚本的 JSON 输出

类 CSS 查询

officecli query doc.docx 'paragraph[style=Heading1]'            # 按样式
officecli query doc.docx 'p:contains("quarterly")'              # 按文本内容
officecli query doc.docx 'p:empty'                              # 空段落
officecli query doc.docx 'image:no-alt'                         # 无替代文本的图片
officecli query doc.docx 'p[align=center] > r[bold=true]'      # 复合选择器
officecli query doc.docx 'paragraph[size>=24pt]'                # 按大小
officecli query doc.docx 'field[fieldType!=page]'               # 按类型筛选字段

页眉与页脚

已知 CLI 缺陷:add --type footer 命令中 --prop field=page 会被静默忽略。页脚只会创建静态文本。您必须在创建页脚后使用 raw-set 注入 PAGE 字段。
# 步骤 1:为封面页创建空页脚(自动启用 differentFirstPage)
officecli add doc.docx / --type footer --prop type=first --prop text=""

# 步骤 2:带有静态 "Page " 文本的默认页脚
officecli add doc.docx / --type footer --prop text="Page " \
  --prop type=default --prop align=center --prop size=9pt --prop font=Calibri

# 步骤 3:通过 raw-set 注入 PAGE 字段
# (footer[2] = 当首页页脚也存在时的默认页脚)
officecli raw-set doc.docx "/footer[2]" \
  --xpath "//w:p" \
  --action append \
  --xml '<w:r ...><w:fldChar w:fldCharType="begin"/></w:r>
         <w:r ...><w:instrText xml:space="preserve"> PAGE </w:instrText></w:r>
         <w:r ...><w:fldChar w:fldCharType="end"/></w:r>'

页脚索引规则:当同时添加了首页页脚和默认页脚时,默认页脚是 /footer[2]。如果没有首页页脚,默认页脚是 /footer[1]。始终使用 officecli get doc.docx "/footer[2]" 进行验证。

驻留模式(性能优化)

始终使用 open/close — 这是明智的默认做法。每条命令都无需重复文件 I/O。

officecli open doc.docx           # 一次性加载到内存(立即返回)
officecli add doc.docx ...        # 所有命令在内存中运行 -- 速度快
officecli set doc.docx ...
officecli close doc.docx          # 一次性写入磁盘
警告:不要将 officecli open 作为后台 shell 任务运行(例如通过 run_in_background)。它会立即返回,守护进程自动在后台运行。将其作为受监控的 shell 运行会产生僵尸进程和文件锁。

批处理模式

在单个 open/save 周期内执行多个操作:

cat <<'EOF' | officecli batch doc.docx
[
  {"command":"add","parent":"/body","type":"paragraph",
   "props":{"text":"Introduction","style":"Heading1"}},
  {"command":"add","parent":"/body","type":"paragraph",
   "props":{"text":"This report covers Q4 results.","font":"Calibri","size":"11pt"}}
]
EOF

批处理支持:addsetgetqueryremovemoveswapviewrawraw-setvalidate

子技能参考

更多细节存放在按需加载的伴随文件中:

子技能使用场景
officecli-academic-paper学术论文、引用、参考文献、论文目录
creating.md详细的创建方法(从零创建新文档)
editing.md详细的编辑指南(修改现有文档)

决策流程

文档是否为学术论文(毕业论文、期刊、会议论文)?
  是 --> 阅读 officecli-academic-paper/SKILL.md
  否 --> 继续使用主技能

用户是否提供了要匹配的源文件?
  是 --> 基于参考文件编辑 + editing.md
  否 --> creating.md

Python OOXML 脚本

当 officecli 达到其极限时,该技能会回退到以下 Python 脚本:

脚本用途命令
scripts/docx_cli.py统一 Python CLI — 解压、保存、验证、修复、搜索、目录、分块、批注、接受修订、合并 runpython3 scripts/docx_cli.py {open|save|validate|repair|text|search|...}
scripts/accept_changes.py接受所有修订python3 scripts/accept_changes.py IN.docx OUT.docx
scripts/comment.py添加符合 W3C 规范的 OOXML 批注并锚定到文本python3 scripts/comment.py IN.docx OUT.docx --text "..." --anchor "..."
scripts/ooxml/merge_runs.py合并格式相同的相邻 runpython3 scripts/ooxml/merge_runs.py unpacked/
scripts/ooxml/redline_diff.py验证修订与原始文档的正确性python3 scripts/ooxml/redline_diff.py unpacked/ original.docx
scripts/ooxml/simplify_tracked.py简化同一作者的相邻修订python3 scripts/ooxml/simplify_tracked.py unpacked/

参考材料

文件何时阅读包含内容
references/cjk-handling.md韩文文本/东亚字体/换行问题rFonts 东亚字体、lang 标签、无障碍性
references/tracked-changes.md修订/批注/红线标记工作w:insw:del、批注 XML、脚本使用示例

商务文档设计原则

标题层级

# 验证标题层级
officecli view report.docx outline

配色方案

用途允许的颜色十六进制示例
标题、强调海军蓝#003366#1B2A4A
正文装饰、边框炭灰色#333333#4A4A4A
高亮、标注森林绿#2E5E3F#1A4731

切勿在单个文档中使用彩虹色、亮原色或超过 3 种强调色。

字体选择

文字类型主要字体备用字体
韩文Malgun GothicPretendard
英文/拉丁文CalibriAptos

排版规范

正文:11-12pt。标题递增:H1 = 最小 18pt(长文档推荐 20pt),H2 = 14pt 加粗H3 = 12pt 加粗。正文行距 1.15x-1.5x。

内容到元素的映射

内容类型推荐元素原因
顺序项目无序列表(listStyle=bullet比行内逗号分隔更易浏览
逐步流程有序列表(listStyle=numbered数字传达顺序
对比数据带表头行的表格列式布局便于并排比较
趋势数据嵌入图表(chartType=line/column视觉化模式识别
关键定义悬挂缩进段落将术语与定义分离
法律/合同条款带书签的有序列表通过书签进行交叉引用
数学内容公式元素(formula=LaTeX正确的 OMML 渲染
引用/参考脚注或尾注保持正文简洁
引述/标注带边框和底纹的段落与正文形成视觉区分
多节布局分节符与分栏按节控制分栏

强制性验证

切勿跳过验证。在任何 DOCX 创建或编辑之后,以下两个步骤都是强制性的。
# 步骤 1:结构验证
officecli validate output.docx

# 步骤 2:视觉 PDF 验证
soffice --headless --convert-to pdf --outdir /tmp output.docx
# 打开/检查 PDF 以确认:格式、表格、图片、页眉/页脚

QA 检查清单

假设存在问题。你的工作就是找到它们。

问题检测

officecli view doc.docx issues
officecli view doc.docx issues --type format
officecli view doc.docx issues --type content
officecli view doc.docx issues --type structure

内容 QA

officecli view doc.docx text
officecli view doc.docx outline
officecli query doc.docx 'p:empty'
officecli query doc.docx 'image:no-alt'

# 检查残留占位符
officecli query doc.docx 'p:contains("lorem")'
officecli query doc.docx 'p:contains("placeholder")'

交付前检查清单

验证循环

  1. 生成文档
  2. 运行 view issues + view outline + view text + validate
  3. 列出发现的问题(如果没有,更严格地再查一遍)
  4. 修复问题
  5. 重新验证 — 一个修复往往会产生另一个问题
  6. 重复直到完整的一轮检查没有发现新问题

在至少完成一个"修复-验证"循环之前,不要宣布成功。

常见陷阱

陷阱正确做法
--name "foo"使用 --prop name="foo" — 所有属性都通过 --prop 传递
猜测属性名称运行 officecli help docx set paragraph --json 获取准确名称
shell 字符串中的 \n--prop text="line1\\nline2" 中使用 \\n 表示换行
# 的十六进制颜色使用 FF0000 而非 #FF0000 — 无井号前缀
路径从 1 开始/body/p[1]/body/tbl[1] — XPath 惯例
--index 从 0 开始--index 0 = 第一个位置 — 数组惯例
zsh/bash 中未加引号的 [N]Shell 会对 /body/p[1] 进行通配符展开 — 始终给路径加引号:"/body/p[1]"
用空段落做间距在段落上使用 spaceBefore/spaceAfter 属性
--prop text= 中的 $使用单引号:--prop text='$50M'
页脚中的 --prop field=page被静默忽略。必须使用 raw-set 注入 <w:fldChar>
从模板重建样式cp source.docx target.docx — 不要添加已有 ID 的样式
officecli open 作为后台 shell在前台运行 — open 立即返回,守护进程自动在后台运行
批处理 JSON 解析错误使用 heredoc:cat <<'EOF' | officecli batch FILE.docx
创建 OMML 公式officecli 无法生成 OMML — 升级到 L4
在 run 上使用 listStylelistStyle 是段落属性,不是 run 属性
行级 bold/color/shd行的 set 仅支持 heightheaderc1/c2/c3 文本快捷方式 — 使用单元格级 set
节与根属性名称混淆节使用 pagewidth/pageheight(小写)。文档根使用 pageWidth/pageHeight(驼峰式)
错误的边框格式使用 style;size;color;space 格式:single;4;FF0000;1
通过空格缩进代码块使用 ind.left 段落属性(例如 --prop ind.left=720
LibreOffice 中的 chartType=pie/doughnut扇区在 PDF 中不可见 — 改用 columnbar

已知问题

问题解决方法
无视觉预览与 pptx(SVG/HTML)不同,docx 没有内置渲染。使用 view text/outline/annotated/issues 进行验证。在 Word 中打开进行视觉检查。
创建修订需要原始 XMLOfficeCLI 可以接受/拒绝但无法创建修订。使用 raw-set 或 Python 脚本 (L3)。
制表位可能需要原始 XML制表位创建未在高级命令中暴露。使用 raw-set
创建后无法添加图表系列set --prop data= 只能更新现有系列。删除并重建图表。
复杂编号定义listStyle=bullet/numbered 涵盖简单情况。多级列表请使用 numId/numLevel
批处理间歇性失败约每 15 次批处理操作中有 1 次可能失败。重试或 close/reopen 文件。将大批量拆分为 10-15 个块。
表格级 padding 产生无效 XML不要使用 set tbl[N] --prop padding=N。使用单元格级 padding.top/padding.bottom
不支持内部超链接hyperlink 只接受绝对 URI。使用 raw-set 配合 <w:hyperlink w:anchor="...">
表格 --index 定位不可靠add /body --type table 上的 --index N 可能被忽略。按所需顺序添加内容。
view text 所有编号项都显示 "1."仅为显示限制。Word/LibreOffice 中渲染的输出显示正确编号。

反模式(必须避免)

工具发现

在猜测之前始终从帮助中确认语法:

officecli --help
officecli help docx
officecli help docx add
officecli help docx set
officecli help docx query
officecli help docx add paragraph --json
officecli help docx set run --json

依赖项

工具用途状态
officecli (PATH)主要 DOCX CLI — 全局安装包含 CJK 分支必需
dotnetofficecli 的运行时/构建分支构建时必需
python3回退脚本(scripts/*.pyL3/L4 时必需
lxmlscripts/ooxml/* 的 Python XML 处理L3/L4 时必需
sofficePDF 转换/.doc 迁移/宏工作流可选回退
pdftoppmPDF 渲染后的基于图像的 QA可选回退

前置条件检查

# 必需
python3 -c "import docx, lxml" || echo "MISSING: pip install python-docx lxml"

# 按需:LibreOffice
which soffice >/dev/null 2>&1 || echo "INFO: LibreOffice not installed"

# 按需:OfficeCLI
which officecli >/dev/null 2>&1 || echo "INFO: OfficeCLI not installed"