mcpField
O
officecli-docx

officecli-docx

github.com/iofficeai文档处理32.7k178 次安装今天更新
代码仓库

关于 officecli-docx

officecli-docx 是指导 Agent 使用 officecli 创建、读取和编辑 DOCX 文档的技能,面向需要制作或检查 Word 文档的工作流。它强调先查 CLI 帮助、逐步执行修改,并通过结构、文本和 HTML 视图进行质量检查。

主要功能

  1. 01创建和编辑 DOCX 内容与结构
  2. 02用语义路径读取并修改元素
  3. 03通过查询和视图检查文档
  4. 04遵循格式层级与排版规范
  5. 05逐步执行并验证每项修改

适用场景

  1. 01从头制作格式清晰的报告
  2. 02检查并修改已有 DOCX 文档
  3. 03查找空段落、格式问题或缺失替代文本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/iofficeai/officecli --skill officecli-docx

安装后在 Claude Code 中输入/officecli-docx确认已加载。

详细介绍

OfficeCLI DOCX 技能

设置

如果缺少 officecli:

  • macOS / Linux:curl -fsSL https://d.officecli.ai/install.sh | bash
  • Windows (PowerShell):irm https://d.officecli.ai/install.ps1 | iex

使用 officecli --version 验证(如果 PATH 尚未更新,请打开新的终端)。如果安装失败,请从 https://github.com/iOfficeAI/OfficeCLI/releases 下载二进制文件。

⚠️ 先查帮助规则

本技能介绍优质 docx 的特点,而非每个命令标志的用法。如果不确定属性名称、枚举值或别名,请先查阅帮助,再进行猜测。

officecli help docx                         # List all docx elements
officecli help docx <element>               # Full element schema (e.g. paragraph, field, numbering, watermark, toc)
officecli help docx <verb> <element>        # Verb-scoped (e.g. add field, set section)
officecli help docx <element> --json        # Machine-readable schema

帮助内容与已安装的 CLI 版本绑定。如果本技能与帮助内容不一致,以帮助内容为准。

思维模型

.docx 是一个包含 XML 部件的 ZIP 文件(document.xml、styles.xml、numbering.xml、header*.xml、footer*.xml、comments.xml,……)。用户看到的一切内容——标题、表格、页码、目录、修订——都是该 ZIP 文件中的 XML。officecli 提供了一个语义路径 API(/body/p[1]/r[2]),因此你几乎不必接触原始 XML;必须操作原始 XML 时,请使用 raw-set(见 XML 附录)。

Shell 与执行规范

docx 路径包含 [];一些属性值包含 $。两者都是 Shell 元字符。转义分为三个层次——请分别处理。

  1. Shell。 始终为元素路径加引号:"/body/p[1]",不要写成 /body/p[1](zsh/bash 会将 [N] 视为通配符)。包含 $ 的值一律使用单引号:--prop text='$50M'——无论值有多长,整个值都要放在一对单引号内。未加引号的 $50M 会被截掉,只剩下 M;在一个长字符串中混用 '…$var…' 和 "…$50…",就会导致 $50 悄悄消失。
  2. CLI(text=)。 --prop text= 会解析两个字符的转义序列 \n、\v 和 \t(规则与 pptx 相同):\n 会开始新段落(每个新 <w:p> 都会继承源段落的样式),\v 是同一段落内的软换行(<w:br/>),\t 表示 <w:tab/>。将反斜杠加倍(\\n)可表示字面量反斜杠-n(通常很少需要)。行级表格快捷方式 c1…cN 是例外:其中的 \n 表示单元格内的 <w:br/> 换行(见配方 (e))。
  3. JSON(批处理)。 批处理不会解析两个字符的转义序列——JSON "\\n" 或 "\\v" 会作为字面文本写入。要表示实际字符,请使用 JSON 转义:"\n"(换行)会开始新段落,"\u000b" 是软换行。

如有疑问,写入后运行 view text,逐字符比对。

增量执行。 officecli 每次调用都会修改文件。请逐条运行命令,并检查每条命令的退出码——包含 50 条命令的脚本若在第 3 条失败,之后的错误会悄然连锁发生。每次结构操作(新样式、表格、目录、分节符)后,都先对其运行 get,再继续操作。

打开/保存生命周期: 开始时运行 officecli open <file>,最后运行 officecli save <file>,将更改写入磁盘——save 只负责写入,并让常驻进程保持就绪,以便后续编辑;只有在一次性交接时,才使用 officecli close <file> 释放常驻进程。两者始终安全(不会报错或丢失工作)。对于多个使用同一样式的段落,请使用 batch(一次处理整个数组)。仅在跨出 officecli 的边界时刷新: officecli 自身的读取始终能看到你的更改;只有在非 officecli 程序要读取文件之前(例如 python-docx、Word、渲染器或交付)才运行 save/close。

$FILE 约定。 所有命令都使用 "$FILE"——设置一次即可(FILE="your-doc.docx")。不要将字面量 doc.docx / review.docx 直接复制到输出中——务必替换为你的实际目标文件。

输出要求

每份文档都必须达到的交付标准——运行命令前请先了解这些要求。

层次清晰。 每份非简单文档都应有标题 → 一级标题 → 二级标题 → 正文,而不是一整页未设置样式的 Normal 段落。如果 view outline 显示的是一串扁平列表,就说明缺少层次结构。

明确设置标题字号(Word 默认样式的字号会因模板而异):H1 ≥ 18pt(长篇报告使用 20pt),H2 = 14pt 加粗,H3 = 12pt 加粗,正文 = 11–12pt,行距为 1.15–1.5 倍。优先使用 style=Heading1,而非行内字号设置,这样更换主题时只需修改一次样式定义;但如果无法信任模板样式,就要明确设置字号。

一种正文字体,一种强调色。 选用一种易读的正文字体(Calibri、Cambria、Georgia、Times New Roman);强调色用于突出标题或表头,不要使用彩虹色格式。

通过属性设置间距。 使用段落的 spaceBefore / spaceAfter。连续的空段落会破坏分页,并被 view issues 标记。

排版质量。 新增内容使用弯引号(‘ ’ “ ”),不要使用 ASCII 引号;可直接输入 Unicode 字符,也可在 raw-set 中使用 XML 实体(&#x2018;/&#x2019;/&#x201C;/&#x201D;)。表示范围时使用短横线 –(2024–2026),用于插入说明时使用长破折号 —。

任何超过 1 页的文档都要有页眉、页脚和页码。 页码应通过实时 PAGE 字段(--prop field=page)插入,绝不能直接输入文本“Page 1”——CLI 会为你插入 <w:fldChar>(参见“页眉和页脚”)。

保留现有模板。 编辑已有样式的文件时,应与其风格保持一致;现有惯例优先于本指南。

视觉交付底线(适用于每份文档)

宣布完成前,运行 officecli view "$FILE" html 并读取返回的 HTML 路径,确认以下各项均符合要求:

  • 不得将占位符标记渲染为实际内容。 $xxx$、{var}、{{name}}、<TODO>、lorem、xxxx 绝不能出现在标题、正文、封面、目录、题注、页眉或页脚中。供用户填写的字面量 {name} 应放在醒目的说明段落中(例如“发送前请替换 {name}”),不能作为最终内容直接呈现。
  • 标题不得截断,单元格不得溢出。 加宽列,或设置 wrapText,不要删减内容。
  • 文档有 3 个或更多标题时,必须包含目录(--type toc)。
  • 封面填充率至少为 60%,末页填充率至少为 40%。 封面内容过少时,可补充副标题、作者、日期、范围或重点概述;末页只有“Thank you”时,可补充结论、后续步骤、联系方式或法律信息。
  • 文档文本中不得出现字面量 \$、\t、\n。 如果 view text 显示这些内容,说明 Shell 转义层泄漏了——请删除该段落并重新输入。

若有任何一项不符合要求,请先停止并修正,然后再宣布完成。

常见工作流

共六个步骤。每项非简单构建工作都应遵循以下流程。

  1. 打开文件。 使用 officecli open "$FILE"(默认驻留模式)。创建新文件时,先运行 officecli create "$FILE"。
  2. 了解文件情况。 对于已有文件,运行 officecli view "$FILE" outline,查看标题树、章节数,以及是否已有目录/水印/修订。切勿在不了解文件情况时直接编辑。
  3. 逐步构建。 先处理结构,再添加内容,最后设置格式:样式和编号定义 → 分节/页面设置 → 标题和正文 → 表格/图片/字段/目录 → 页眉/页脚 → 批注。每次结构操作后,都要先用 get 取回结果,再继续添加内容。
  4. 按规格设置格式。 明确设置标题字号、间距、宽度、对齐方式、制表位和列表缩进——格式是交付成果的一部分,不是可有可无的润色。
  5. 先保存,再以结构为准,而非依赖缓存文本。 officecli save "$FILE" 会写入 XML。目录/PAGE/NUMPAGES/SEQ/PAGEREF 字段含有缓存值,在人手动重新计算前(在 Word 中按 F9),这些值可能过期或为空。请确认字段确实存在(get --depth 3 能找到 <w:fldChar>),不要只相信可见文本。
  6. QA——假定存在问题。 只有在一轮修复并验证后确认没有新问题,才算完成;不是最后一条命令退出代码为 0 就算完成。参见 QA。

快速开始

最精简可用的 docx:一个标题、一个正文段落、一个副标题,以及带有实时页码字段的页脚。请根据需要调整,不要直接复制粘贴——文件由你创建,内容由你编写。

FILE="review.docx"
officecli create "$FILE"
officecli open "$FILE"
officecli add "$FILE" /body --type paragraph --prop text="Q4 2026 Review" --prop style=Heading1 --prop size=20pt --prop bold=true --prop spaceAfter=12pt
officecli add "$FILE" /body --type paragraph --prop text="Revenue grew 18% year-over-year, ahead of plan." --prop size=11pt --prop spaceAfter=8pt
officecli add "$FILE" /body --type paragraph --prop text="Key Drivers" --prop style=Heading2 --prop size=14pt --prop bold=true --prop spaceBefore=12pt --prop spaceAfter=6pt
officecli add "$FILE" /body --type paragraph --prop text="Enterprise renewals, upsell, and a new EMEA region." --prop size=11pt
officecli add "$FILE" / --type footer --prop type=default --prop size=9pt --prop text="Page " --prop field=page
officecli set "$FILE" "/footer[1]/p[1]" --prop align=center
officecli save "$FILE"
officecli validate "$FILE"

已验证:validate 返回 no errors found;get /footer[1] --depth 3 显示包含 5 个 run 的 PAGE 字段链(begin / instrText / separate / cached value / end)。

阅读与分析

先纵览,再深入。outline 会告诉你文档已有的内容;确定查看位置后,再使用 view text / get / query。

officecli view "$FILE" outline            # heading tree, section count, table/image counts, watermark, tracked-changes presence — orient here first
officecli view "$FILE" html               # Read the returned HTML path: first visual check after a batch of edits (hierarchy, empty-para spacing, missing TOC)
officecli view "$FILE" text --start 1 --end 80   # text for content QA; paths shown as [/body/p[N]] so you can jump back with get
officecli view "$FILE" annotated          # values + style/font/size + warnings per run
officecli view "$FILE" stats              # paragraph counts, font usage, style distribution
officecli view "$FILE" issues             # empty paras, missing alt text, spacing anomalies

officecli watch "$FILE" 会持续运行实时预览,供用户按需打开;Agent 自检使用 view html。最终视觉验证由用户在 Word / WPS / Pages 中打开 .docx 完成。

检查单个元素。 类 XPath 语义路径(从 1 开始计数)。始终加引号——shell 会对 [N] 执行 glob 匹配。使用 [last()](带括号)表示最后一个元素;[last] 会报错。添加 --json 可输出机器可读结果。

officecli get "$FILE" /                          # document root: metadata, page setup
officecli get "$FILE" "/body/p[1]"                # one paragraph
officecli get "$FILE" "/body/p[1]/r[1]"           # one run (character-level formatting)
officecli get "$FILE" "/body/tbl[1]" --depth 3    # table with rows and cells
officecli get "$FILE" "/footer[1]" --depth 3      # footer — check for fldChar
officecli get "$FILE" "/styles/Heading1"          # style definition
officecli get "$FILE" /numbering --depth 2        # numbering abstractNum + num bindings

查询整个文档。 类 CSS 选择器,适用于系统化检查,而非逐项手动查看。运算符:=、!=、~=(包含)、>=、<=、[attr](存在)。完整参考:officecli query --help。

officecli query "$FILE" 'paragraph[style=Heading1]'       # all H1s
officecli query "$FILE" 'p:contains("quarterly")'         # text match
officecli query "$FILE" 'p:empty'                         # empty paragraphs (clutter)
officecli query "$FILE" 'image:no-alt'                    # accessibility gaps
officecli query "$FILE" 'paragraph[size>=24pt]'           # numeric comparison
officecli query "$FILE" 'field[fieldType!=page]'          # fields other than PAGE

query --json 会将结果封装在 .data.results[] 中——使用 jq '.data.results | length' 计数。

大型文档。 使用 view outline 按标题导航,并通过 query 跳转;不要将整个正文都导入上下文。

创建与编辑

动词:add(新建元素)、set(更改属性)、remove、move、swap、batch、raw-set(最后手段,直接操作 XML)。文档构建中 90% 的内容是段落、run、表格、少量图片、目录和页脚。

段落、run 和样式

段落(p)是一个块;run(r)是其中字符格式一致的一段文字。在 p 上设置段落级属性(样式、对齐方式、间距、缩进);在 r 上设置字体 / 大小 / 颜色 / 粗体。

officecli add "$FILE" /body --type paragraph --prop text="Executive Summary" --prop style=Heading1 --prop size=18pt --prop bold=true --prop spaceAfter=12pt
officecli set "$FILE" "/body/p[1]/r[1]" --prop color=1F4E79

使用 spaceBefore / spaceAfter 设置垂直间距——不要连续插入空段落。左缩进使用 --prop indent=720(twips),首行缩进使用 firstLineIndent=360,悬挂缩进使用 hangingIndent=720;行首空格会触发 view issues。

表格

表格路径为 /body/tbl[N],包含行 tr[N] 和单元格 tc[N]。添加表格时指定行数 / 列数,然后填充内容。

officecli add "$FILE" /body --type table --prop rows=4 --prop cols=3 --prop width=100%
officecli set "$FILE" "/body/tbl[1]/tr[1]" --prop header=true --prop c1=Quarter --prop c2="Revenue" --prop c3="Growth"
officecli set "$FILE" "/body/tbl[1]/tr[1]/tc[1]/p[1]/r[1]" --prop bold=true

行级 set 支持 height、header 和 c1 / c2 / … / cN 文本快捷方式(cN 可泛化为任意列数)。单元格格式(粗体、填充、颜色)应设置在单元格的段落 / run 上,而不是行级属性。若要设置单元格边框,请在 tc 上设置单元格级 border.*(--prop border.bottom="single;6;000000;0"),或在内部段落上设置段落级 pbdr.*。

水平线 = 段落底部边框,绝不能用单行表格。 用表格充当分隔线会渲染成带最小高度的空框(在页眉 / 页脚中尤其明显)。应在段落上使用 pbdr.bottom(STYLE;SIZE;COLOR):

officecli set "$FILE" "/body/p[3]" --prop pbdr.bottom="single;6;2E75B6"
列表(项目符号、编号、多级列表)

对于单级项目符号 / 编号列表,在段落上设置 listStyle(listStyle 是段落属性,不是 run 属性——这是常见错误):

officecli add "$FILE" /body --type paragraph --prop text="First item" --prop listStyle=bullet

对于多级列表(法律文书样式的 1 / 1.1 / 1.1.1),先添加 abstractNum,再添加 num,然后在每个段落中引用 numId:

officecli add "$FILE" /numbering --type abstractnum --prop format=decimal     # → abstractNum id=0
officecli add "$FILE" /numbering --type num --prop abstractNumId=0             # → num id=1
officecli add "$FILE" /body --type paragraph --prop text="Section one" --prop numId=1 --prop ilvl=0

ID 从 0 开始:第一个 abstractNum 的 id=0;num 通过 abstractNumId=0 引用它,而 num 自身分配的 id=1。若 abstractNumId 不存在,则会报错,因此创建后请检查 ID。使用 officecli query "$FILE" 'paragraph[numId>0]' 验证。级别和格式选项请参阅 help docx abstractnum / help docx num。

制表位(签名行、前导符行)

制表位是段落的一级 tab 子元素;pos 接受 6in/6cm/twips,val ∈ left/center/right,leader ∈ none/dot/hyphen/underscore。参见 help docx tab。

officecli add "$FILE" "/body/p[1]" --type tab --prop pos=6in --prop val=right --prop leader=dot

前导符注意事项。 仅设置 leader=dot 不会显示点线——只有当文本与制表位之间的某个 run 中有实际的 <w:tab/> 字符时,前导符才会呈现。可在文本中使用 \t 插入:先定义制表位(add tab --prop pos=6in --prop val=right --prop leader=dot),再设置 --prop text="Chapter 1\t12"——\t 会变成 <w:tab/>,点线会延伸至右对齐的页码。(也可以直接使用 text="Chapter 1 ......... 12",但实际的制表位能实现整齐对齐。)

域(PAGE / NUMPAGES / DATE / MERGEFIELD / REF)

域是在渲染时计算的动态值。fieldType 用于选择域;name 用于指定目标(合并名称或 ref 书签);format / instr 用于添加开关。

域用途示例
page当前页码在页脚中使用 --prop field=page,或在行内使用 --prop fieldType=page
numpages总页数--prop field=numpages / --prop fieldType=numpages
date今天的日期--prop fieldType=date --prop format='yyyy-MM-dd'
mergefield模板合并标记--prop fieldType=mergefield --prop name=CustomerName
ref对书签的交叉引用--prop fieldType=ref --prop name=bookmarkName

完整的 fieldType 枚举(包含 pageref、seq、styleref、docproperty、createdate 等 30 多个值)请参见 help docx field。不存在 fieldInstr 这一 fieldType——当类型化快捷方式无法满足需求时,请使用 instruction 属性传入原始域指令文本。图片开关(MERGEFIELD Amount \# "#,##0.00"、DATE \@ "yyyy年MM月")通过 --prop instruction='…' 设置(mergefield 的 format 属性会被忽略并显示警告——请使用 instruction)。

officecli add "$FILE" "/body/p[3]" --type field --prop fieldType=mergefield --prop name=customer_name
# Renders «customer_name» — visible placeholder, replaced in Word at mail-merge time.

MERGEFIELD 模板:不要渲染占位符文本。 将 {{customer_name}} 或 $NAME$ 作为正文文本显示,是失败的模板,收件人会看到这些内容——请插入真实的 MERGEFIELD(见上文),或将字面标记限制在明显的说明段落中。使用 query 'field[fieldType=mergefield]' 确认。

SEQ / PAGEREF / TOC 域值。 officecli 在写入时不会存储已渲染的域值。请根据各路径的需求重新计算:

  • SEQ 编号(Figure 1/2/3):officecli set "$FILE" / --prop recalcFields=seq 会按正文文档顺序统计 SEQ 域并写入缓存值(evaluated 会变为 true;开关和格式请参见 help docx document)。相对于标题的 \s 和页眉/页脚中的 SEQ 会交由 Word 处理。
  • PAGE / PAGEREF / NUMPAGES / TOC 页码需要分页,而 officecli 没有分页引擎——officecli set "$FILE" /settings --prop updateFields=true 会将其交由 Word 在打开文件时处理。

多图表文档请同时使用两者。学术论文:参见 officecli-academic-paper 技能。

页眉和页脚(页码)

单命令模式——CLI 会插入 <w:fldChar>,因此无需手动编写域:

# Empty first-page footer — auto-enables differentFirstPage so the cover has no page number
officecli add "$FILE" / --type footer --prop type=first --prop text=""
# Default footer with live page number
officecli add "$FILE" / --type footer --prop type=default --prop align=center --prop size=9pt --prop text="Page " --prop field=page

如果页眉和页脚都存在,默认页脚为 /footer[2];如果只有页脚,则为 /footer[1]。验证:get --depth 3 必须显示 fldChar 子元素,而不能只是包含字面文本 "Page" 的 run(view outline 对动态域和静态文本都会打印“Footer: Page”,不要依赖它)。不要执行 set --prop differentFirstPage=true——该属性不受支持(退出码为 2,并显示 WARNING: UNSUPPORTED;但元素仍会创建——请检查 --json 中的 success);添加 first 类型的页脚会切换该标志。对于组合页码 Page X of Y,请参见配方 (b)。

目录

对于包含 3 个或更多标题的文档,先确认请求范围内确实存在有效来源。目录来源必须使用内置标题样式,或带有 outlineLvl 的自定义段落样式;加粗或字号较大的普通文本不算来源。如果没有符合条件的来源,请先修正标题结构,而不是插入一个会显示“Error! No table of contents entries found.”的目录。

# Built-in Heading styles are TOC sources.
officecli add "$FILE" /body --type paragraph --prop text="Introduction" --prop style=Heading1
# Custom paragraph styles need an outline level (0 = Heading 1).
officecli add "$FILE" /styles --type style --prop id=ThesisH1 --prop type=paragraph --prop outlineLvl=0
# Add the TOC only after its sources exist.
officecli add "$FILE" /body --type toc --prop levels="1-3" --prop title="Table of Contents" --prop hyperlinks=true --index 0

页码需要分页才能确定;OfficeCLI 无法自行计算目录页码。设置 updateFields=true,让 Word 在打开文档时重新计算目录(以及所有域)。如果没有兼容 Word 的域引擎,请说明目录是动态且尚未计算的;不要声称页码已就绪,也不要猜测静态目录。

officecli set "$FILE" /settings --prop updateFields=true

使用 /toc[1] 或 /tableofcontents,通过 get/set/remove 直接操作目录。

图片

图片必须放在运行中。为确保无障碍访问,必须提供替代文本——创建时直接传入 alt:

officecli add "$FILE" "/body/p[5]" --type picture --prop src=logo.png --prop width=1.5in --prop alt="Acme logo"

交付前,确认 officecli query "$FILE" 'image:no-alt' 的结果为空。

图表

对于数据,添加原生图表——可编辑、可应用主题、支持无障碍访问,并能在 Word 中重新渲染;切勿使用扁平化的图表 PNG 截图。每个系列使用 data="Label:v1,v2,…";每个系列设置一个 data=(或使用 series1=/series2=)。

officecli add "$FILE" /body --type chart --prop chartType=bar --prop title="Revenue by Region" --prop categories="EMEA,APAC,Americas" --prop data="2026:120,150,180"

chartType ∈ bar / column / line / pie / area / scatter(使用 help docx chart 查看坐标轴/图例/系列样式设置)。对于 officecli 无法创建的特殊图表,PNG 配合 --type picture 只能作为后备方案。

超链接和书签

外部链接通过 hyperlink 添加:

officecli add "$FILE" "/body/p[2]" --type hyperlink --prop url="https://example.com" --prop text="our site"

内部链接(指向书签)使用 --prop anchor=bookmarkName——不要在 url 中使用 #fragment:

officecli add "$FILE" "/body/p[2]" --type hyperlink --prop anchor=chapter1 --prop text="See Chapter 1"

另一种方式是将 PAGEREF 域与可见文本配对。请参阅 help docx hyperlink / help docx bookmark。

分节和页面设置

文档根节点 / 携带页面设置(pageWidth、pageHeight、页边距,单位为 twip)。多分节文档(横向页面、分栏)需添加 section 分节符——请参阅 help docx section。camelCase(pageWidth,规范形式)和小写别名(pagewidth)均可使用;建议使用 camelCase。

officecli set "$FILE" / --prop pageWidth=12240 --prop pageHeight=15840 --prop marginTop=1440 --prop marginLeft=1440
# Newspaper-style multi-column flow (columnSpace in twips; 720 = 0.5in):
officecli set "$FILE" / --prop columns=2 --prop columnSpace=720
强制分页

每个逻辑边界只能使用一种分页机制。默认做法是在目标标题上设置 pageBreakBefore=true。也可以在标题前插入一个显式的 pagebreak。同一边界绝不要同时使用这两种机制:双重分页可能导致出现空白页。添加 pagebreak 后,绝不要在紧接其后的 p[last()] 上设置 pageBreakBefore。

# Default: apply the break directly to the heading.
officecli add "$FILE" /body --type paragraph --prop text="Introduction" --prop style=Heading1 --prop pageBreakBefore=true

--prop break=newPage 是 pageBreakBefore=true 的别名。使用 view html 预览并检查是否有空白页。

报告级配方

每份长篇报告中都会用到的模式。每种模式都已执行并通过 validate 验证。

(a) 丰富的封面 — 达到 ≥ 60% 的填充率下限。 依次添加保密横幅、标题、副标题、客户/项目/日期信息块和关键主题栏,然后强制下一节从新页面开始:

officecli add "$FILE" /body --type paragraph --prop text="CONFIDENTIAL — CLIENT USE ONLY" --prop align=center --prop size=9pt --prop color=C00000 --prop spaceAfter=24pt
officecli add "$FILE" /body --type paragraph --prop text="Strategic Growth Review" --prop style=Title --prop size=32pt --prop bold=true --prop align=center --prop font=Cambria --prop spaceAfter=8pt
officecli add "$FILE" /body --type paragraph --prop text="FY26 Outlook and Scenario Planning" --prop italic=true --prop size=16pt --prop align=center --prop spaceAfter=36pt
officecli add "$FILE" /body --type paragraph --prop text='Prepared for: Acme Corp. Leadership Team' --prop align=center --prop size=11pt
officecli add "$FILE" /body --type paragraph --prop text='Engagement: 2026-04 — 2026-06' --prop align=center --prop size=11pt --prop spaceAfter=36pt
officecli add "$FILE" /body --type paragraph --prop text="Key themes: 1) margin resilience, 2) EMEA expansion, 3) capital allocation." --prop align=center --prop italic=true --prop size=10pt
officecli add "$FILE" /body --type paragraph --prop text="Executive Summary" --prop style=Heading1 --prop pageBreakBefore=true

(b) 第 X 页,共 Y 页页脚 — 组合使用 PAGE + NUMPAGES。 添加页脚段落,然后通过三个子操作动态生成 Page <X> of <Y>。这是官方的 help docx footer 配方。

officecli add "$FILE" / --type footer --prop type=default --prop text="Page " --prop align=center --prop size=9pt
officecli add "$FILE" "/footer[1]/p[1]" --type field --prop fieldType=page
officecli add "$FILE" "/footer[1]/p[1]" --type run --prop text=" of "
officecli add "$FILE" "/footer[1]/p[1]" --type field --prop fieldType=numpages
officecli get "$FILE" "/footer[1]/p[1]" --depth 1 | grep -o fldChar | wc -l   # expect ≥ 4; use grep -o ... | wc -l, NOT grep -c (single-line XML returns 1)

(c) 带底纹和白色粗体文字的表头行。 顺序很重要——先填充表头单元格文本(空单元格中不存在 runs;在空单元格上执行 set …/tc[N]/p[1]/r[1] 会报错 "No r found"),再设置单元格底纹,最后设置 run 格式:

officecli add "$FILE" /body --type table --prop rows=5 --prop cols=4 --prop width=100%
officecli set "$FILE" "/body/tbl[1]/tr[1]" --prop header=true --prop c1=Quarter --prop c2=Revenue --prop c3=Growth --prop c4=Status
for col in 1 2 3 4; do
  officecli set "$FILE" "/body/tbl[1]/tr[1]/tc[$col]" --prop fill=1F4E79
  officecli set "$FILE" "/body/tbl[1]/tr[1]/tc[$col]/p[1]/r[1]" --prop bold=true --prop color=FFFFFF
done
for row in 3 5; do for col in 1 2 3 4; do
  officecli set "$FILE" "/body/tbl[1]/tr[$row]/tc[$col]" --prop fill=D9E2F3      # zebra stripe
done; done

(d) 财务表格 — 数字右对齐、总计加粗、总计行添加底部边框。

for row in 2 3 4 5; do for col in 2 3 4; do
  officecli set "$FILE" "/body/tbl[1]/tr[$row]/tc[$col]/p[1]" --prop align=right
done; done
for col in 1 2 3 4; do
  officecli set "$FILE" "/body/tbl[1]/tr[5]/tc[$col]/p[1]/r[1]" --prop bold=true
  officecli set "$FILE" "/body/tbl[1]/tr[4]/tc[$col]/p[1]" --prop pbdr.bottom="single;6;000000;0"
done

(e) 包含多个项目符号的单元格(SWOT / 风险矩阵)。 c1="a\nb" 会在一个段落中生成 <w:br/> 换行符——适用于纯文本多行内容,但项目符号需要使用独立段落。先通过 set c1= 创建第一项,然后在单元格下为后续每项执行 add paragraph(设置 listStyle=bullet):

officecli set "$FILE" "/body/tbl[1]/tr[1]" --prop c1="Installed base of 18k enterprise seats"
officecli add "$FILE" "/body/tbl[1]/tr[1]/tc[1]" --type paragraph --prop text="Margin structure above peer median" --prop listStyle=bullet
officecli set "$FILE" "/body/tbl[1]/tr[1]/tc[1]/p[1]" --prop listStyle=bullet

如果初始行出现在底部,请重新排序:officecli move "$FILE" "/body/tbl[1]/tr[1]/tc[1]/p[N]" --index 0。

(f) 不使用字段引擎的目录。 仅使用 CLI 的工作流无法计算可靠的页码。保留动态目录,设置 updateFields=true,并告知接收者在 Word 或其他兼容的字段引擎中打开文档。不要用猜测的静态页码替换它。

模板交付 — 将模板备注与面向最终用户的内容分开

HR / 法律 / 供应商模板中包含仅供内部使用的指导("replace {{CompanyName}}"),这些内容绝不能随模板一起交付。以下两种模式均可行:

  • 在明确的 Heading 1("HR 用户的模板备注")下添加末尾的“模板备注”章节,并将所有说明放在该章节中;分发前,从该标题开始向下执行 remove(使用 query 'paragraph[style=Heading1]:contains("Template Notes")' 定位)。
  • 使用 __template_notes_start / _end 书签标记内部章节的边界;交付时,raw-set 会移除锚点之间的所有内容。

模板交付检查:移除内容后,query 'p:contains("Template Notes")' 和 query 'p:contains("{{")' 都应返回空结果。如果有备注段落残留,后续员工就会看到内部内容。

高级/专业主题(如果你在编写报告,可跳过)

报告、备忘录、信函、提案和 HR 模板不需要了解这些内容。只有当你的文档属于学术文档(包含公式、脚注、参考文献)、经过审阅(包含评论、修订记录)或带有标记(水印)时,才继续阅读。

公式和脚注。 --type equation 接受 LaTeX——\frac、\sum、希腊字母、\mathit、\mathcal 均可正常渲染。默认情况下,它会创建独立的 /body/oMathPara[N] 显示块;若要在正文中插入行内 <m:oMath>,请使用段落父路径,并传入 --prop mode=inline(add "/body/p[N]" --type equation --prop formula=… --prop mode=inline)。脚注会按段落索引自动编号。参考文献悬挂缩进:每条条目设置 firstLineIndent=-720 indent=720。

officecli add "$FILE" /body --type equation --prop formula="\\frac{a}{b} + \\sum_{i=1}^{n} x_i"
officecli add "$FILE" "/body/p[3]" --type footnote --prop text="See Appendix A for methodology."

评论和修订记录。 批量接受/拒绝:set "$FILE" /revision --prop revision.action=accept(或 --prop revision.action=reject);也可以使用 /revision[@author=Alice] 或 /revision[@type=ins] 之类的选择器进行筛选。使用 query ins 和 query del 定位单条修订(trackedchange 不是选择器)。使用 --prop revision.type=ins|del --prop revision.author=… 在文本片段上创建修订记录(完整的 revision.* 选项集——包括 format/moveFrom/moveTo——请参阅 help docx run)。添加评论:add "/body/p[4]" --type comment --prop author=… --prop text=…;使用 --prop parentId=N 添加回复,并使用 set "/comments/comment[N]" --prop done=true 将其标记为已解决(将评论标记为已解决而非删除,以保留审计记录——随后运行 query 'comment[done=false]' 可列出仍未解决的评论)。属性模式:help docx comment/help docx run。

水印。 一条命令即可完成:add / --type watermark --prop text="DRAFT" --prop color=BFBFBF --prop opacity=0.8(默认不透明度为 0.5);之后可通过 set /watermark --prop opacity=… 调整。

何时切换技能。 章节草稿、≤ 3 个脚注、≤ 2 个公式,且不含参考文献/交叉引用时,继续使用 docx。需要引用格式(APA/Chicago/IEEE/GB 7714)、正文↔参考文献自动链接、带 \ref 的编号公式、“List of Figures” 或自动更新交叉引用时,切换到 academic-paper。当文档用于数据采集时(可填写表单、带用户填写区域的合同、问卷、邮件合并模板(<w:sdt> 内容控件、<w:ffData>、documentProtection=forms)),切换到 officecli-word-form。

原始设置应急方案(L1/L2/L3)

精度分为三个级别;选择能满足需求的最低级别。

  • L1 — 高级属性(--prop text=…、--prop style=Heading1):默认选项,适用于 80% 的情况。
  • L2 — 点分属性回退方案(pbdr.top=、ind.left=、shd.fill=、padding.top=、font.size=):当 L1 缺少所需选项时使用。示例:--prop pbdr.bottom="single;6;1F4E79;0"。生成符合模式的 XML。
  • L3 — 使用 XML 的 raw-set:最后手段,不提供模式保护。用于内部超链接、复合字段,以及类型化动词无法表达的其他结构(参见 XML 附录)。

边框格式为 style;size;color;space:single;4;FF0000;1。十六进制颜色前面不能带 #:FF0000。方案颜色名称(accent1..6、dark1/dark2、light1/light2、hyperlink)可在任何允许使用十六进制颜色的位置使用;为确保颜色在不同主题间保持一致,建议优先使用十六进制颜色。

QA(必需)

假设文档存在问题——QA 是一场 Bug 搜寻,而不是确认步骤。 你的第一份文档几乎从来都不正确;如果初次检查就没有发现任何问题,说明你检查得还不够仔细。标题看起来没问题,直到 view outline 显示 H3 直接位于 H1 下方;页脚显示“第 1 页”,直到 get --depth 3 显示它是静态文本片段,而不是字段。

在标记“完成”前进行的最少检查周期
  1. officecli view "$FILE" issues — 检查空段落、缺失的替代文本和格式异常。
  2. officecli view "$FILE" outline — 检查标题层级(不得跳过 H1 → H3)、是否存在目录以及章节数量。
  3. officecli view "$FILE" text --max-lines 400 — 检查拼写错误、多余的 \$/\t/\n 字面量和占位符。
  4. officecli validate "$FILE" — 检查架构(交付门会在已关闭并写入磁盘的文件上重新运行此检查)。
  5. 视觉检查——将整份文档作为联系表查看(仅限具备视觉能力的 Agent——如果你无法解读图像,请跳过此步骤:步骤 1–4 就是你的能力上限,并在交接时将文档标记为“未经视觉验证”)。运行 officecli view "$FILE" screenshot --grid auto -o /tmp/sheet.png,然后读取图像。--grid auto 会将所有页面平铺到一张图像中(自动选择列数;使用 --grid 4 强制指定)——你可以看到分页、空白页、标题节奏、页边距是否失衡,以及目录和封面的摆放位置,而不仅仅是 DOM。Windows + Word 会通过真实的 Word 渲染每一页;其他环境则使用 HTML。如果截图失败,请改用 view html,并将跨页断裂、对齐和节奏标记为“未经视觉验证”。缩略图只能用来定位:对任何细节问题(列对齐、行距、缩进、深色背景上的深色文字、题注位置),都要在可疑页面上使用 screenshot --page N 以全分辨率确认(不加 --grid;Windows 上使用真实的 Word)。通过“validate”不等于可以交付;“看起来像一份真正的文档”才算。
  6. 如果有任何项目未通过,请修复,然后重新运行完整周期——一次修复通常会引发另一个问题。
交付门(交接前运行——任何一项失败都将导致拒收,请勿交付)

复制粘贴并设置 FILE;在每项检查都打印 OK 之前,不要声明完成。

FILE="your-file.docx"

# Gate 1 — schema.
officecli close "$FILE" 2>/dev/null
officecli validate "$FILE" | grep -q "no errors found" || { echo "REJECT Gate 1: validate failed"; exit 1; }
echo "Gate 1 OK"

# Gate 2 — token leak (shell-escape / template tokens / literal \$ \t \n). grep -c never false-PASSes.
LEAK=$(officecli view "$FILE" text | grep -cE '(\$[A-Za-z_]+\$|\{\{[^}]+\}\}|<TODO>|xxxx|lorem|\\[\$tn])')
[ "$LEAK" -eq 0 ] && echo "Gate 2 OK" || { echo "REJECT Gate 2: $LEAK leak line(s)"; officecli view "$FILE" text | grep -nE '(\$[A-Za-z_]+\$|\{\{[^}]+\}\}|<TODO>|xxxx|lorem|\\[\$tn])'; exit 1; }
# A TOC placeholder is valid before a Word-compatible field engine updates it; confirm the TOC field and updateFields setting structurally instead.

# Gate 3 — live PAGE field exists when a footer is expected.
FLD=$(officecli query "$FILE" 'field[fieldType=page]' --json | jq '.data.results | length')
[ "$FLD" -ge 1 ] && echo "Gate 3 OK" || { echo "REJECT Gate 3: no live PAGE field"; exit 1; }
echo "Delivery Gate PASS"
字段/缓存值抽查

字段写入时携带的缓存值可能已过时或为空——请通过结构而非文本确认字段是否存在。

  • 页脚 PAGE:get /footer[N] --depth 3 会列出 begin / instrText / separate / cached / end 运行链——单个 PAGE 字段至少需要 5 个运行,组合字段“Page X of Y”至少需要 11 个运行。单个文本为 "Page" 的运行表示字段缺失;请使用 --prop field=page 重新添加。
  • 目录:get /toc[1] --depth 2 会显示字段结构。重新计算前,页码可能显示为 1 1 1 1 或 Update field to see…(参见 §Table of Contents — set updateFields=true)。
  • MERGEFIELD:query 'field[fieldType=mergefield]' — 每个插槽应有一个字段,其他位置不得出现字面量 {{name}}。
能力边界

validate 能捕获架构错误,但不能发现设计错误——文档即使标题层级错误、使用伪造的 Heading 1 字号、正文包含占位符,或无封面文档的首页页脚为空,也可能通过检查。联系表视觉检查(screenshot --grid)和字段结构检查,才能发现验证无法捕获的问题。

QA 显示说明(无需处理)
  • 无论渲染后的编号是什么,view text 对每个编号列表项都显示 "1."——实际输出会正确递增。
  • view issues 会在封面段落、居中标题、列表项和参考文献条目上报告“正文段落缺少首行缩进”——首行缩进仅适用于 APA/学术正文;对于块状排版的专业文档,这些提示属于预期情况。

已知问题与陷阱

遇到某些内容“看起来有问题”时,请先判断原因再着手处理:[AGENT-ERROR] 文档有误(应修复)· [RENDERER-BUG] 文档正确,但查看器的渲染方式不同(无需追查)· [SKILL gap] 技能说明未涵盖此规则(请提交问题)。

渲染器问题(跨查看器,[RENDERER-BUG] — 无需追查)

在判定颜色/字段/图表损坏之前,先在用户指定的查看器中打开文件;如果在那里显示正常,那就是查看器问题。

  • PAGE 字段可能会直接显示字面文本“Page”(没有数字),直到重新计算——应根据是否存在 fldChar 来判断,而不是看数字。
  • 目录缓存的页码可能显示为“1 1 1 1”,直到按下 F9。
  • 饼图/圆环图的填充可能会塌缩为一种颜色,在某些查看器中如此(柱形图/条形图显示正常)。
  • 表单控件复选框可能显示为双框;OMML 公式的基线可能因查看器而异(XML 相同)。
常见陷阱
陷阱正确做法
--index 与 [N]--index 从 0 开始;[N] 路径从 1 开始
多次使用相同的 N 执行 add --index N每次插入都会将后续内容下移;重复使用 N 会使后插入的项目位于先插入的项目之前——按相反顺序插入,或使用以 paraId 为锚点的 move --after/--before
在 zsh/bash 中不加引号的 [N]所有路径都加引号:"/body/p[1]"
将 [last] 用作谓词必须写成 [last()],带括号
间距中使用原始 twips使用带单位的值:12pt、0.5cm、1.5x
使用空段落调整间距使用 spaceBefore / spaceAfter
使用行级 set 设置单元格格式行级 set 仅支持 height、header、c1..cN 文本;格式应设置在单元格段落/文本运行上
在文本运行上设置 listStyle这是段落属性
通过前导空格缩进使用 indent=720 / firstLineIndent=360 / hangingIndent=720(带点号的 ind.left / ind.firstLine 也可以)
通过 set differentFirstPage=true 隐藏封面页码不支持——添加首页类型的页脚:--type footer --prop type=first --prop text=""
需要新章节从新页开始在标题上使用 pageBreakBefore=true;也可改用显式 pagebreak,但两者不可同时使用
一个单元格中有多个项目符号段落c1="a\nb" 会生成 <w:br/> 换行符(仍是一个段落);如需分开的项目符号段落,请使用方案 (e)
dotted-attr 可用时使用 raw-set优先使用 L2 dotted-attr,而不是 L3 raw-set
下一段继承前一段的 Heading 样式在后续段落上明确设置 --prop style=Normal
修改在 Word 中打开的文件先在 Word 中关闭文件
输出到批处理的 Echo 遇到 $/' 会出错使用单引号分隔符的 heredoc:cat <<'EOF' | officecli batch …

Raw-set XML 附录(L3 模式)

raw-set 注入字面 OOXML — 不受架构保护。<w:pPr> 中元素的顺序:pStyle、numPr、spacing、ind、jc、rPr(最后)。智能引号使用实体(&#x2018;/&#x2019;/&#x201C;/&#x201D;)。任何包含前置或尾随空格的 <w:t> 都要添加 xml:space="preserve"。RSID 为 8 位十六进制数。除非用户指定其他作者,否则跟踪更改/评论的作者使用 “Claude”。

跟踪更改中的插入/删除 — 优先对 run 使用高级 --prop revision.type=ins|del;只有在类型化路径无法实现时才使用 raw-set(例如下文中拒绝/还原其他作者的更改)。替换整个 <w:r>…</w:r>,绝不要在 run 内注入标签;将原始 <w:rPr> 复制到两处,以保留格式。在 <w:del> 内使用 <w:delText>(指令使用 <w:delInstrText>):

<w:r><w:t>The term is </w:t></w:r>
<w:del w:id="1" w:author="Claude" w:date="2026-01-01T00:00:00Z"><w:r><w:delText>30</w:delText></w:r></w:del>
<w:ins w:id="2" w:author="Claude" w:date="2026-01-01T00:00:00Z"><w:r><w:t>60</w:t></w:r></w:ins>
<w:r><w:t> days.</w:t></w:r>

删除段落/列表项的所有内容时,也要将段落标记为已删除(在 <w:pPr><w:rPr> 内添加 <w:del/>)— 否则接受更改后会留下空段落。要拒绝其他作者的插入,将你的 <w:del> 嵌套在对方的 <w:ins> 中;要还原对方的删除,在其后添加一个 <w:ins>(不要修改对方的内容)。

指向书签的内部超链接(优先使用高级 --prop anchor= 路径;仅在命令无法实现自定义 run 样式时使用 raw-set):

<w:hyperlink w:anchor="chapter1"><w:r><w:rPr><w:rStyle w:val="Hyperlink"/></w:rPr><w:t>See Chapter 1</w:t></w:r></w:hyperlink>

单个 run 中的复合域(例如,单命令路径无法组合的两个域)— fldChar begin / instrText / separate / value / end 链:

<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="separate"/></w:r>
<w:r><w:t>1</w:t></w:r>
<w:r><w:fldChar w:fldCharType="end"/></w:r>

评论标记是 <w:r> 的同级元素,绝不能位于其内部(回复串联和已解决状态通过高级路径设置 — 使用 --prop parentId=/done=,参见上文“评论”):

<w:commentRangeStart w:id="0"/><w:r><w:t>annotated text</w:t></w:r><w:commentRangeEnd w:id="0"/>
<w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr><w:commentReference w:id="0"/></w:r>

使用 officecli set "$FILE" /settings --prop updateFields=true 强制在打开时重新计算域(写入 <w:updateFields w:val="true"/>;适用于依赖布局的域 PAGE / PAGEREF / NUMPAGES / TOC 页码 — 无需使用 raw-set)。对于 SEQ 编号,优先使用 set / --prop recalcFields=seq,以便立即写入正确的缓存值,无需等待 Word。

帮助指引

不确定时:officecli help docx、officecli help docx <element>、officecli help docx <verb> <element>,Agent 可使用 --json。帮助内容是权威架构;本技能是决策指南。

评论

支持 Markdown