mcpField
O
officecli-xlsx

officecli-xlsx

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

关于 officecli-xlsx

officecli-xlsx 是面向使用 officecli 命令行工具构建和分析 Excel 工作簿的 Agent 技能,介绍单元格与公式操作、批量导入 CSV、格式规范及公式和视觉检查。

主要功能

  1. 01设置单元格值和公式
  2. 02导入 CSV 与 TSV 数据
  3. 03批量处理工作簿操作
  4. 04设置工作表格式和打印布局
  5. 05验证公式与渲染效果

适用场景

  1. 01构建由公式驱动的财务模型
  2. 02批量加载并格式化 CSV 数据
  3. 03准备供审阅或打印的工作簿

安装

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

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

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

详细介绍

OfficeCLI XLSX 技能

设置

如果缺少 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 下载二进制文件。

⚠️ 优先查阅帮助

此技能介绍优质 xlsx 应该是什么样,而不是列出每个命令标志。对属性名称、枚举值或别名不确定时,请先查阅帮助,再做判断。

officecli help xlsx                         # List all xlsx elements
officecli help xlsx <element>               # Full element schema (e.g. pivottable, chart, cf)
officecli help xlsx <verb> <element>        # Verb-scoped (e.g. add chart, set cell)
officecli help xlsx <element> --json        # Machine-readable schema

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

Shell 与执行规范

Shell 引号(zsh / bash)。 Excel 路径中包含 [],数字格式中包含 $。二者都是 Shell 元字符。规则如下:

  • 始终为元素路径加引号:"/Sheet1/row[1]",不要写成 /Sheet1/row[1]。
  • 属性值包含 $ 时,使用单引号:numFmt='$#,##0'。
  • 对于包含跨工作表 ! 引用的公式,请使用带 <<'EOF' heredoc 的 batch(参见已知问题)。
  • CLI 会解析属性值中的 \n 和 \t:\n 是单元格内的实际换行符(搭配 --prop wrapText=true),\t 是制表符——在 xlsx / docx / pptx 中行为一致。将它们写成双倍形式(\\n),即可表示字面量反斜杠-n(通常不需要)。($ 属于上层 Shell,需要用单引号括起来。)

逐条执行。 每次只运行一条命令,并检查其退出代码。officecli 每次调用都会修改文件;包含 50 条命令的脚本若在第 3 条命令处失败,后续命令可能悄无声息地连锁失败。运行一条命令 → 检查输出 → 继续。

输出要求

运行命令前,先了解优质 xlsx 应该是什么样。以下是所有工作簿都必须满足的交付标准。

所有 Excel 文件

公式错误为零。 每个交付的工作簿都必须确保 #REF!、#DIV/0!、#VALUE!、#NAME?、#N/A 均为零。不得例外——请使用 IFERROR 或 IF(x=0,...) 保护分母。

使用公式,而非硬编码值。 如果某个数字可以通过其他单元格计算得出,就应使用公式。在应使用 =SUM(B2:B9) 的地方硬编码 5000,会破坏工作簿在输入变化时保持动态的约定。这是本技能最重要的一条规则。

使用专业字体。 整个工作簿统一使用一种专业字体(Arial / Calibri / Times New Roman)。不要因为某个工作表来自 CSV,就混用四种字体。

明确设置列宽。 不支持自动调整列宽。用户需要查看的每一列都必须设置 width——默认的 8.43 个字符会导致内容被截断。合理的起始值:标签列 20-25,数字列 12-15,日期列 12,短代码列 8-10。

保留现有模板。 编辑已有样式的文件时,请保持样式一致。现有规范优先于这些指南。

视觉交付标准(适用于每个工作簿)

在宣布完成之前,运行 officecli view "$FILE" html,并阅读返回的 HTML 路径,确认以下各项:

  • 任何单元格中都不能有 ###。 ### 表示某列过窄,无法显示其最宽的值。用户需要查看的每一列都必须明确设置 width。交付文件中出现 ### 就说明工作尚未完成,绝不是“一个小小的视觉问题”。
  • 标题不得被截断。 工作表标题、分节标题和较长的标签都必须完整显示。加宽列,或在单元格上设置 wrapText=true。
  • 不得将占位符标记渲染为数据。 $fy$24、{var}、<TODO>、xxxx 绝不能出现在单元格、图表标题、系列名称或图例中。这些是构建时标记,尚未替换就被带入了输出。
  • 饼图/圆环图的扇区必须使用不同的填充颜色。 如果渲染后扇区颜色相同,请改用 bar/column,或明确设置 colors=...。
  • 不得有空白的末尾页面/空图表锚点。 将 anchor=D2:J18 放在空的源数据单元格上,会让图表看起来像是损坏的。

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

打印版式。 任何用户可能打印或作为董事会资料包发送的工作表都需要设置页面。默认纵向布局且不适应页面,会导致宽表和图表在中间分页。根据工作表的形状选择适应方式:

# Summary / chart / dashboard sheet (small, ≤ ~40 rows): fit to a single page.
officecli set "$FILE" "/Summary" --prop orientation=landscape --prop fitToPage=true
# Tall data table (dozens+ rows): fit WIDTH only, let height paginate naturally.
# fitToPage=true here crushes every row onto one page → unreadable (### dates, 5px rows).
officecli set "$FILE" "/Data" --prop orientation=landscape --prop fitToPage=1x0

fitToPage=true == 1x1 == 宽度和高度均适应为一页——仅当工作表本身较短时才正确。1x0 = 宽度适应为 1 页,高度不限。触发条件:工作表包含图表,或列数 > 8,或用户的要求提到打印/董事会/投资者。

仅适用于财务模型——如果你要创建模板、跟踪表、CSV 导入表或运营表,请跳过本节

范围:预算、预测、三表模型、估值,以及任何大量使用 $ 的分析型工作簿。客户支持跟踪表或入职模板不需要遵循本节。

颜色编码——行业标准。 五种核心颜色作为一种语言使用,而非装饰。审核者应能仅凭颜色判断单元格的类型,无需先阅读公式。

颜色用途示例
蓝色文本 0000FF硬编码输入、情景变量font.color=0000FF
黑色文本 000000所有公式和计算默认
绿色文本 008000此工作簿内的跨工作表链接font.color=008000
红色文本 FF0000指向外部文件/工作簿的链接font.color=FF0000
黄色填充 FFFF00需要审核的关键假设fill=FFFF00

审核者应能仅凭颜色判断单元格的类型,无需先阅读公式。这是一项沟通约定,而非对外观的偏好。

数字格式——标准,而非偏好。

  • 年份应设为文本,而非数字。格式应为 2026,而不是 2,026——使用 numFmt="@" 或设置 type=string。
  • 货币单位应放在标题中(Revenue ($mm)),而非每个单元格中。
  • 零应显示为 -,而非 0。使用 $#,##0;($#,##0);"-"。
  • 百分比默认保留一位小数:0.0%。
  • 负数使用括号:(1,234),而不是 -1,234。
  • 估值倍数使用 0.0x 格式(EV/EBITDA、P/E 等)。

假设应放在单元格中,而非写在公式里。 =B5*(1+$B$6) 正确;=B5*1.05 是错误。每个蓝色的硬编码输入都应在相邻单元格中注明来源,或通过单元格批注注明来源:

Source: Company 10-K, FY2024, Page 45, Revenue Note
Source: Bloomberg, 2026-05-02, AAPL US Equity
Source: Management guidance, Q2 2026 earnings call

任何没有注明来源的硬编码数字都是未经记录的假设——审核者无法审计。

常见工作流

六个步骤。每个非简单构建都遵循此流程。

  1. 打开/保存生命周期。 开始时使用 officecli open <file>,结束时使用 officecli save <file> 将更改写入磁盘——save 只负责写入,并让常驻实例保持就绪,以便后续编辑;只有在一次性交接时需要释放常驻实例,才使用 officecli close <file>。这两个命令始终安全(不会报错或丢失工作)。处理大量单元格时,使用 batch:建议每个块 ≤ 50 个操作;纯值写入负载每块经测试可达 80 多个操作,且零失败。跨工作表公式批处理是例外——应以非常驻模式运行,使用单个 heredoc(见已知问题)。仅在离开 officecli 的边界处刷新: officecli 自身的读取始终能看到你的编辑;只有在非 officecli 程序读取文件之前(openpyxl/pandas、Excel、渲染器、交付),才运行 save/close。
  2. 创建或加载。 使用 officecli create "$FILE"(新建),或 officecli view "$FILE" outline(现有文件——先了解整体布局)。
  3. 逐步构建。 每次运行一条命令,读取输出后再继续。执行任何结构性操作(新建工作表、图表、命名区域、数据透视表)后,先对其运行 get,确认结构,再继续添加内容。
  4. 设置格式。 列宽、数字格式、冻结窗格、工作表标签颜色、标题填充。格式不是可有可无的润色——根据“输出要求”,它是交付内容的一部分。
  5. 保存,然后处理缓存。 officecli save <file> 会将内容写入磁盘。新添加的公式不会附带缓存值;用户在电子表格应用中打开文件时,应用会重新计算并填充这些值。但是,你后续的 INDEX/MATCH、SUMPRODUCT 或任何引用上游公式的公式,都会缓存上游在写入时的缓存值——通常是 0 或过时的值——而这个缓存中的错误值会留在不会重新计算的读取器中。 构建涉及数组公式(SUMPRODUCT、带动态条件的 SUMIFS)或跨工作表公式链的多公式表格后,重新触碰每个下游单元格(再次运行 set,使用相同公式),让引擎根据已更新缓存的上游值重新计算其缓存。⚠️ 通过常驻实例重新触碰跨工作表公式链不可靠(见批处理/常驻实例注意事项)——重新触碰时优先使用非常驻模式运行 set。然后用 officecli get 检查几个下游单元格,确认其 cachedValue= 看起来合理。常驻实例打开时运行 validate 是安全的,而且会自行将待处理的编辑刷新到磁盘(与 docx / pptx 相同)。
  6. 质量检查——假设存在问题。 参见质量检查部分。最后一条命令以 0 退出,并不代表工作已完成;只有经过一轮修复和验证,且未发现新问题,才算完成。

快速入门

最小可用的 xlsx:3 个月的收入 + 一个总计公式 + 列宽 + 货币格式。根据实际情况调整,不要直接复制粘贴——文件是你的,数据也是你的。

officecli create "$FILE"
officecli open "$FILE"
officecli set "$FILE" /Sheet1/A1 --prop value=Month --prop bold=true
officecli set "$FILE" /Sheet1/B1 --prop value=Revenue --prop bold=true
officecli set "$FILE" /Sheet1/A2 --prop value=Jan
officecli set "$FILE" /Sheet1/A3 --prop value=Feb
officecli set "$FILE" /Sheet1/A4 --prop value=Mar
officecli set "$FILE" /Sheet1/B2 --prop value=42000 --prop numFmt='$#,##0'
officecli set "$FILE" /Sheet1/B3 --prop value=45000 --prop numFmt='$#,##0'
officecli set "$FILE" /Sheet1/B4 --prop value=48000 --prop numFmt='$#,##0'
officecli set "$FILE" /Sheet1/A5 --prop value=Total --prop bold=true
officecli set "$FILE" /Sheet1/B5 --prop formula="SUM(B2:B4)" --prop bold=true --prop numFmt='$#,##0'
officecli set "$FILE" "/Sheet1/col[A]" --prop width=12
officecli set "$FILE" "/Sheet1/col[B]" --prop width=15
officecli close "$FILE"
officecli validate "$FILE"

验证结果:validate 返回 no errors found,B5 的结果为 135000。每次构建都遵循这一流程:打开 → 设置单元格/公式 → 设置格式 → 关闭 → 验证。

CSV / 批量导入

原生 import 命令(CSV/TSV 首选)。 这是最快的方式;只需一次调用,即可将 CSV 加载到工作表中。--header 会在第 1 行设置自动筛选和冻结窗格。仍需后续设置列宽和 numFmt(参见 Dashboard skill 中的 D-12)。

officecli import "$FILE" /Sheet1 --file data.csv --header
officecli import "$FILE" /Sheet1 --file data.tsv --format tsv --header
officecli import "$FILE" /Sheet1 --stdin --start-cell B2 < data.csv

Python + batch 备用方案——需要自定义类型强制转换、注入公式,或 CSV 位于另一个数据流水线中时使用。适用于 600-6000 多个单元格的操作流程:

# gen_batch.py — produces batch chunks of 80 value-set ops each
import csv, json
ops = []
with open("data.csv") as f:
    reader = csv.reader(f)
    for r, row in enumerate(reader, start=1):
        for c, val in enumerate(row):
            col = chr(ord('A') + c)
            ops.append({"command":"set","path":f"/Data/{col}{r}",
                        "props":{"value": val}})
for i in range(0, len(ops), 80):
    print(json.dumps(ops[i:i+80]))
python gen_batch.py | while IFS= read -r chunk; do
  printf '%s\n' "$chunk" | officecli batch "$FILE"
done

结果:包含 649 行的零售 CSV(6490 个单元格)约 30 秒即可加载完成,且零失败。调整建议:从每个块 80 个操作开始;如果任何块失败,则降至 40。数值类型推断和公式稍后通过定向 set 添加——此流程中的 batch 仅用于写入纯值。

阅读与分析

先从整体入手,再逐步聚焦。先用 outline 查看有哪些工作表以及数据所在位置;确定查找范围后,再使用 view / get / query。

打开渲染后的工作簿,目视检查自己的成果。

  • officecli view $FILE html — 阅读返回的 HTML,检查渲染结果。每个工作表都可单独查看,图表会内嵌渲染。可发现 ###、占位符泄漏、数据透视表布局和行高裁切等问题。
  • officecli watch $FILE 会持续运行实时预览,供用户自行打开查看。用户想要同步观看时使用;Agent 自检请使用上方的 view html。 批量编辑后,首次视觉检查请使用 view html——从源头修复问题。最终视觉验证时,由用户在 Excel / WPS / Numbers 查看器中打开 .xlsx。

了解概况。 工作表、维度、公式数量。

officecli view "$FILE" outline

提取内容。 将内容转储为纯文本,用于内容 QA 或大模型上下文;对于大文件,可使用 --start / --end / --cols 限定范围。

officecli view "$FILE" text --start 1 --end 50 --cols A,B,C

其他值得了解的 view 模式:annotated(单元格值 + 类型/公式 + 警告)、stats(数值摘要)、issues(损坏的公式、空工作表、缺失的引用)。

往返转储。 officecli dump "$FILE" [path] 可序列化工作簿,也可以序列化单个工作表(/Sheet1、/sheet[N]),生成可重放的批处理 JSON;officecli batch new.xlsx --input dump.json 可重放该 JSON。可用它了解现有工作簿的结构,或克隆/改编模板,而不必读取原始 OOXML。支持范围见 dump --help;子树转储不会携带工作簿级资源(设置、命名区域)——重放目标必须已定义这些资源。

officecli dump "$FILE" -o blueprint.json            # whole workbook
officecli dump "$FILE" /Sheet1 -o sheet.json        # one worksheet
officecli batch new.xlsx --input blueprint.json

检查单个元素。 使用 XPath 风格的路径。务必加引号——shell 会对 [N] 进行通配符展开。

officecli get "$FILE" "/Sheet1/A1"            # one cell
officecli get "$FILE" "/Sheet1/A1:D10"        # range
officecli get "$FILE" "/Sheet1/chart[1]"      # chart
officecli get "$FILE" "/Sheet1/table[1]"      # ListObject
officecli get "$FILE" "/namedrange[1]"        # workbook-level named range

添加 --depth N 可展开子级;添加 --json 可输出机器可读内容。完整元素列表:officecli help xlsx。

跨工作簿查询。 使用类似 CSS 的选择器。用于系统性检查(公式覆盖情况、错误单元格、空表头),而不是逐项手动遍历。

officecli query "$FILE" 'cell:has(formula)'       # every formula cell
officecli query "$FILE" 'cell:contains("#REF!")'  # broken references
officecli query "$FILE" 'cell[type=Number]'       # typed filter
officecli query "$FILE" 'Sheet1!B[value!=0]'      # sheet-scoped

运算符:=、!=、~=(包含)、>=、<=、[attr](存在)。

合并单元格快捷方式。 officecli query $FILE merge 或 mergedrange——二者都是 mergeCell 的别名。无需手动遍历 <mergeCell> 条目,即可返回工作簿中的所有合并区域。

数据量大到逐行遍历毫无用处时,请使用 Excel 自带的分析元素:

  • 使用 officecli add(--type pivottable)创建数据透视表,进行分组/汇总,无需编写 20 个 SUMIF。添加切片器(--type slicer),为读者提供筛选界面。
  • 在行中添加迷你图(--type sparkline),展示逐行趋势——比每行创建一个折线图更省资源,而且会内嵌打印。type 是严格枚举:line | column | stacked(另有别名 winloss / win-loss → stacked)。无效的 type= 值会直接报错——不再静默回退为 line。
  • 运行 officecli help xlsx pivottable、officecli help xlsx slicer、officecli help xlsx sparkline,查看准确的属性名称。

创建与编辑

构建工作簿时,90% 的工作涉及单元格、公式、格式设置,以及一两个图表。可用动词:add(新增元素)、set(更改属性)、remove、move、swap、batch。

单元格与公式

一次调用即可设置值和格式。公式开头不要写 =——CLI 会将其去掉。

officecli set "$FILE" /Sheet1/B5 --prop formula="SUM(B2:B4)" --prop numFmt='$#,##0'
officecli set "$FILE" /Sheet1/C5 --prop formula="B5/A5" --prop numFmt="0.0%"

结构属性(宽度、高度、冻结、tabColor)位于行 / 列 / 工作表节点上:

officecli set "$FILE" "/Sheet1/col[A]" --prop width=20
officecli set "$FILE" "/Sheet1/row[1]" --prop height=22
officecli set "$FILE" "/Sheet1" --prop freeze=A2 --prop tabColor=1F4E79
命名范围

公式中优先使用命名范围,而不是 $B$6。命名范围具有自说明性(GrowthRate 比 $B$6 更直观),还可让你移动假设单元格而不破坏公式。由于 ref 值同时包含 ! 和 $,请通过批量 heredoc 添加:

cat <<'EOF' | officecli batch "$FILE"
[
  {"command":"add","parent":"/","type":"namedrange","props":{"name":"GrowthRate","ref":"Sheet1!$B$6"}}
]
EOF

完整架构请参阅 officecli help xlsx namedrange。

批量 JSON 不接受 shell 别名。 在批量 props 中,始终使用完整的点分隔名称——"font.color": "FF0000"、"font.size": 14,绝不要使用 "color": "FF0000"(含义不明确:文本颜色还是填充颜色)。对于裸单元格,shell 格式也会被拒绝:--prop color=1F4E79 会报错 ambiguous in cell context — use 'font.color' (text) or 'fill' (bg)。规则:在任何批量 JSON 或单元格属性中,都要明确写出 font.color / fill。工作簿级元素的 parent 应为 "/",工作表范围内的元素应为 "/SheetName";空字符串并不等同于此。

图表

图表类型可在 officecli help xlsx chart 中查看——枚举值很多(20 多种)。根据表达目的选择合适的类型:类别比较用柱形图,时间序列用折线图,只有当各扇区的比例关系一目了然时才用饼图,相关性用散点图。除非能回答特定问题,否则避免使用特殊图表类型。

向图表提供数据有三种方式。每张图表选一种——添加时混用是常见陷阱。

形式格式适用场景
(a) 内联 data--prop data="Sales:100,200,300" --prop categories="Jan,Feb,Mar"小型演示图表、不需要编辑的数字。数据源位于图表 XML 中,而不是单元格中。
(b) 二维 dataRange--prop dataRange="Sheet1!A1:B4"(首列 = 类别,首行 = 标题 / 系列名称)常见情况。必须为 二维——单列会报错 "Chart requires data"。
(c) 按系列指定点分隔属性--prop series1.name=Sales --prop series1.values="Sheet1!B2:B4" --prop series1.categories="Sheet1!A2:A4"多系列图表中,每个系列指向不连续的范围,或需要显式指定系列名称。仅设置 series1.values(不设置 categories)会生成一张以 1,2,3 为 X 轴的图表。

单列陷阱。 dataRange="Sheet1!B2:B13" 看起来像是“值列”,但引擎会报错 Chart requires data。你可以扩大范围,将类别列也包括进来(A2:B13),或者改用形式 (c),显式设置 series1.categories。

创建后移动 / 调整图表大小: set chart[N] --prop anchor="F5:N25"(也可使用 --prop x= --prop y= --prop width= --prop height=)。系列仍不可变——要添加 / 更改系列,请使用 officecli remove 删除图表,再通过 officecli add 添加包含完整系列列表的图表。请注意,remove chart[1] 会让 chart[2] → chart[1],重新添加的图表则会追加到末尾——若要保持图表顺序,请全部删除后按顺序重建。

锚点尺寸。 不会自动适应大小。包含 5-6 个类别和 2 个系列的柱形图,大约需要 A5:L22(12 列 × 18 行)才能完整显示所有标签。范围更窄时,X 轴标签会被截断;范围更宽时,打印 / 导出时图表可能会跨页。如有疑问,先从较窄的范围开始,通过 view html 预览(读取返回的 HTML 路径),再逐步加宽。页面布局(见下文)也是解决此问题的另一部分。

图表的 dataRange——始终加上工作表前缀。 即使图表位于同一工作表,也应写成 dataRange="Summary!A17:C22",而不是 A17:C22。不带工作表前缀的形式有时有效、有时无效;带前缀的形式始终可靠。

officecli 还支持经典 Excel 对象模型不具备的扩展图表类型:boxWhisker、waterfall、funnel、histogram、treemap、sunburst、pareto。适合数据时即可使用。

图表标题 / 系列名称 / 图例 / 坐标轴标题中绝不可保留未替换的模板标记。 $fy$24、{var}、<TODO>、$VAR、{{placeholder}} 会在图例中原样显示——验证虽然会通过,但 CFO 看到的却是 $fy$24,而不是应有的 "FY2024"。始终绑定最终文本或单元格引用(title="FY2024 Revenue" 或 series1.name="Sheet1!A1")。

条件格式

有三种常见类型,每种都有各自的属性形状(请参阅 officecli help xlsx cf):

  • 色阶:根据数值为单元格填充渐变色——使用 type=colorscale,并设置 minColor / midColor / maxColor。
  • 数据条:在单元格内显示数值大小的条形——使用 type=databar。设置明确的 min / max,以便在整列范围内保持一致的缩放;省略时默认值也有效。
  • 公式规则(formulacf 元素):条件为真时突出显示整行——使用 type=formula,并设置 formula="$C2>1000" 以及填充色/字体。

规则:谨慎应用条件格式。如果工作簿中的每个单元格都着了色,读者就什么也看不出来。

数据验证

跟踪表和模板中的输入单元格 MUST 设置数据验证。这成本很低,还能避免整类下游错误。三种列表来源模式——根据允许值的存放位置选择。

(a) 内联列表——允许值数量少且固定,直接写在规则中。

officecli add "$FILE" /Sheet1 --type validation \
  --prop sqref="C2:C100" --prop type=list \
  --prop formula1="Yes,No,Maybe" \
  --prop showError=true --prop errorTitle="Invalid" --prop error="Select from list"

(b) 命名范围(跨工作表查找时优先使用)——允许值存放在另一个工作表中,且可能会增加。先定义命名范围,再引用它。由于 ref 包含 ! 和 $,请使用批处理 heredoc:

cat <<'EOF' | officecli batch "$FILE"
[
  {"command":"add","parent":"/","type":"namedrange","props":{"name":"StatusList","ref":"Lookups!$A$2:$A$4"}},
  {"command":"add","parent":"/Sheet1","type":"validation","props":{"sqref":"B2:B100","type":"list","formula1":"=StatusList"}}
]
EOF

(c) 直接跨工作表范围——不使用命名范围,直接在 formula1 中写入 Lookups!$A$2:$A$4。同样需要使用批处理 heredoc,以保留 ! 和 $:

cat <<'EOF' | officecli batch "$FILE"
[
  {"command":"add","parent":"/Sheet1","type":"validation","props":{"sqref":"C2:C100","type":"list","formula1":"Lookups!$A$2:$A$4"}}
]
EOF

如果在 shell 中将跨工作表变体写成 --prop formula1=...,shell 会将 ! 错误处理为 \!,下拉列表会悄无声息地退化为无列表。使用 officecli get "$FILE" /Sheet1/validation[N] 验证——formula1= 必须显示普通的 !,不能带反斜杠。

其他常见的 type 值:decimal、whole、date、textLength、custom。运算符和完整属性列表请参阅 officecli help xlsx validation。

其他元素(一行说明)
  • 表格(ListObjects)——使用 add --type table 并指定范围;可添加自动筛选和结构化引用。参阅 officecli help xlsx table。
  • 批注——使用 add --type comment;用于记录硬编码假设。参阅 officecli help xlsx comment。
  • 工作表重新排序——使用 officecli move,而不是 swap。swap 仅适用于行/单元格路径。
  • 沿用相邻项格式的新行/列——add "$FILE" /Sheet1 --from "/Sheet1/row[5]" --index 5 会克隆填充、字体和公式(引用会相应偏移);add --type row 则会插入空白行。

按角色编辑图表轴

直接编辑图表轴比重建图表更省事。按角色(value = Y,category = X)而非索引定位轴——XML 顺序并不稳定。

officecli get "$FILE" "/Sheet1/chart[1]/axis[@role=value]"
officecli set "$FILE" "/Sheet1/chart[1]/axis[@role=value]" --prop min=0 --prop max=100000
officecli set "$FILE" "/Sheet1/chart[1]/axis[@role=category]" --prop title="Month"

安全的属性:title、min、max、majorGridlines、visible、labelRotation。

QA(必做)

假定存在问题。你的工作就是找出它们。

你的第一个工作簿几乎从来都不正确。请把 QA 当作排查 Bug,而不是确认步骤。如果你第一次检查时一个问题都没发现,那就是检查得还不够仔细。公式看起来没问题,直到你拿其中两个与源单元格进行核对。

声明“完成”前的最低检查流程
  1. officecli view "$FILE" issues — 检查空工作表、损坏的公式和缺失的引用。
  2. officecli view "$FILE" annotated(抽查范围)— 检查值、类型和警告。
  3. 针对每种 Excel 错误类型进行查询:
    officecli query "$FILE" 'cell:contains("#REF!")'
    officecli query "$FILE" 'cell:contains("#DIV/0!")'
    officecli query "$FILE" 'cell:contains("#VALUE!")'
    officecli query "$FILE" 'cell:contains("#NAME?")'
    officecli query "$FILE" 'cell:contains("#N/A")'
    
  4. officecli validate "$FILE" — 即使文件已在本地打开,也可以安全运行;validate 会自行将待处理的编辑写入磁盘。
  5. 视觉检查 — 通过 HTML 预览逐一查看每个工作表。 运行 officecli view "$FILE" html,并读取返回的 HTML 路径。每个工作表都会以内嵌图表的形式呈现。检查是否出现 ###、标题被截断、占位符令牌($fy$24、{var}、<TODO>)、图表被裁切、饼图中出现白色扇区、图表锚点为空 — 发现问题时先停止并修复,再宣布完成。“验证通过”不等于交付;“预览看起来像一份真正的工作簿”才算交付。如需人工预览,可运行 officecli watch "$FILE"(由用户自行决定是否打开实时预览),或让用户直接在 Excel / WPS / Numbers 中打开 .xlsx 文件。
  6. 修复打印布局(宽表格 / 多图表工作表)。 如果工作表包含图表或宽表格,且用户将要打印,请设置该工作表的页面布局 — 但要根据工作表的高度选择合适的缩放模式:
    # Short summary / chart sheet → fit to one page.
    officecli set "$FILE" "/Summary" --prop orientation=landscape --prop fitToPage=true
    # Tall data table → fit width only (fitToPage=true would crush all rows onto one unreadable page).
    officecli set "$FILE" "/Data" --prop orientation=landscape --prop fitToPage=1x0
    
    结果:图表 / 宽表格打印时不会从图表中间分页;较长的表格则可在自然分页处保持可读。对每个包含图表或 > 8 列表格的工作表都应用此设置。
  7. 如果有任何检查失败,请修复,然后重新运行完整流程。一次修复往往会带来另一个问题。

officecli view issues + view html 是结构性 QA 检查组合:issues 会捕获损坏的公式和空工作表;view html(读取返回的 HTML 路径)会捕获 ###、截断内容和令牌泄漏。图表填充色 / 主题色调可能因查看器而异 — 颜色准确度很重要时,请在用户指定的查看器中抽查。

公式验证清单
  • 随机挑选 2-3 个公式。对每个公式运行 officecli get。确认公式字符串符合预期,且 cachedValue= 的值也符合预期 — 自己心算核对。
  • 检查每个汇总单元格的缓存值是否合理。 任何执行汇总操作的单元格(COUNTA / COUNTIF / SUMPRODUCT / INDEX&MATCH)都必须具有合理的 cachedValue。如果空白模板中的进度跟踪器显示 199 / 199 / 100%,说明缓存值有误 — 通过 set 重新触碰公式(强制重新计算),或手动设置正确的缓存值。不要交付“验证通过但数字全是编造的”工作簿。
  • 每个数值列至少抽查一个单元格。 如果 % 列始终显示整数 0.0%,说明分母有误或分子缓存过时 — 检查一个单元格并修复这一模式。
  • 范围必须包含所有行:数据到 B13 时,SUM(B2:B12) 漏掉一行是最常见的错误。
  • 跨工作表公式(Sheet1!A1)中不能包含 \!。如果 officecli get 显示 Sheet1\!A1,说明 ! 被 shell 转义破坏了 — 请删除公式,并通过批处理 / heredoc 重新输入。
  • 命名范围(officecli get "$FILE" "/namedrange[1]")必须指向与其名称相符的位置。
  • 每个 / 除数都必须经过保护 — 使用 IFERROR(x/y, 0) 或 IF(y=0, 0, x/y)。
  • 图表数据与源单元格:对于每个包含内嵌数据的图表,将数据点与通过 officecli get 获取的源单元格进行抽查比对。
  • 图表标题 / 系列名称 / 图例中不能包含未替换的令牌($...$、{var}、<TODO>)。使用 officecli get /Sheet1/chart[N] 对图表内容执行 grep 检查。
模板 QA

编辑模板时,请检查是否遗留占位符 — 它们看起来像内容,容易漏过 validate:

officecli query "$FILE" 'cell:contains("{{")'
officecli query "$FILE" 'cell:contains("xxxx")'
officecli query "$FILE" 'cell:contains("TBD")'
重新审视

完成工作簿后,请重新打开它。像新审阅者一样从头到尾阅读 view text / HTML 预览 — 检查公式、看起来不对劲的数字、格式不一致之处和缺失的数据。

能力限制说明

validate 能捕获架构错误,但不能捕获设计错误。工作簿可能通过 validate,但其中每个数字都是错的。上面的清单 — 尤其是将公式与源单元格进行抽查比对 — 能帮助你发现验证无法捕获的问题。

已知问题与注意事项

跨工作表 ! 陷阱(简短版)

Shell(bash 历史扩展、zsh 分词)和 CLI 参数解析会把 Sheet1!A1 中的 ! 错误处理为 \!。包含 \! 的公式会被静默破坏——它会显示为字面文本,且不引用任何内容。

修复方法。 使用带单引号分隔符(<<'EOF')的批处理 heredoc,这样可以禁用所有 Shell 扩展:

cat <<'EOF' | officecli batch "$FILE"
[{"command":"set","path":"/Summary/B2","props":{"formula":"Revenue!B13"}}]
EOF

验证。 写入后,用 officecli get 获取该单元格;formula= 必须显示普通的 !,且没有反斜杠。

CLI 待处理问题(简短版)

需要规避的 CLI 限制和缺口——并非输出文件中的缺陷。

  • 创建后图表系列不可变——要添加或更改系列,请使用完整系列列表执行 remove + add。(位置可变:set chart[N] --prop anchor= / x/y/width/height。)remove chart[N] 会使后续索引依次减小;重新添加的系列会追加到末尾。
  • 跨工作表公式批处理通过常驻进程运行正常——此前关于“即使只有 3-5 个操作也会死锁”的警告已无法复现。仅设置值的批处理在 50-80+ 个操作时也仍然可靠。如果遇到挂起,请改用非常驻模式下的一次性大批处理,或逐条执行 set。同一文件、同一机器上运行的多个常驻进程仍可能相互争用——如果另一个 Agent/会话在同一文件上持有常驻进程,可能会出现不确定的挂起。
  • 条件格式命名不一致——--type 的元素名称为 conditionalformatting;路径后缀为 /cf[N]。使用 officecli help xlsx conditionalformatting 查看架构,路径则使用 /cf[N]。
  • 添加工作表时的 position 属性——帮助信息称 Add 会处理 position,但该属性经常会被忽略。创建工作表后,使用 officecli move --index / --after / --before 调整顺序。
  • remove /sheet[N] 级联保护——如果其他工作表上的验证 / 条件格式 / 迷你图 / 超链接 / 命名范围引用了该工作表,则会拒绝删除或重命名工作表。请先移除这些依赖元素,再删除工作表。
  • 批处理 JSON 不接受单元格的 color 别名——在批处理的 props 中,"color": "FF0000" 会报错 ambiguous in cell context — use 'font.color' (text) or 'fill' (bg)。在 Shell 层级,CLI 会接受非单元格元素上的 --prop color=... / --prop size=14 作为别名;但在批处理 JSON 中设置单元格时,始终写完整的点分隔名称:"font.color"、"font.size"、"font.name"。
渲染器注意事项(跨查看器的颜色保真度)

officecli view html 适用于结构性 QA(溢出、截断、占位文本泄漏、布局)——请读取返回的 HTML 路径。最终用户打开文件时所用的查看器不同,某些图表渲染细节也会有所差异。观察到的差异如下:

  • 某些查看器中,饼图 / 圆环图的填充颜色可能会合并为单一主题色调(切片看起来“全白”或“全是同一种颜色”)。文件在用户的目标查看器中可能完全正常。
  • 某些查看器中,折线图 / 柱形图系列的颜色可能会偏离工作簿主题色。
  • 某些查看器中,窗体控件复选框可能会显示为双层方框。

在称颜色或图表“损坏”之前,请在用户实际使用的目标查看器中打开文件。如果在那里显示正确,问题就在于查看器渲染,而非数据——不要继续追查。CLI 的结构检查(###、截断、占位文本、布局)仍是权威依据。

转义层(Shell 引号规则已在上文说明;以下是额外层级)

$ 属于 Shell 层(如上所述,需用单引号括起来)。属性值中的 \n / \t 会被 CLI 解释为真正的换行 / 制表符。还有两个层级:

  • JSON 层级(批处理)。 标准 JSON 转义——"\n"、"\t"、"\""。最终字符串中的一个实际反斜杠应写成 "\\\\"。
  • Excel 层级。 单元格中的 \n 是实际换行符——请搭配 --prop wrapText=true,以便 Excel 显示换行。直接在 Shell 引号括起来的属性值中也可使用(--prop value='a\nb');批处理 JSON 中的 "\n" 效果相同。如有疑问,请用 officecli get 获取单元格,并逐字符对比。
其他常见问题
问题解决方法
--name "foo"所有属性都通过 --prop 传递:--prop name="foo"
猜测属性名称officecli help xlsx <element> — 不要自行臆测
在单元格上使用 --prop color=...有歧义——文本颜色请使用 font.color,背景色请使用 fill。批量处理 JSON 中也同样适用:始终使用完整的点分隔名称,绝不使用 shell 别名
#FF0000 十六进制颜色去掉 #:FF0000
--index 与 [N]--index 从 0 开始计数(数组);[N] 路径从 1 开始计数(XPath)
在 zsh/bash 中未加引号的 [N]为每个路径加引号:"/Sheet1/row[1]"
包含空格的工作表名称为完整路径加引号:"/My Sheet/A1"
年份显示为 2,026使用 --prop type=string 或 numFmt="@"
修改在 Excel 中打开的文件先在 Excel 中关闭文件
swap 未能重新排序工作表swap 用于行/单元格。工作表请使用 move --after / --before / --index
写入后缺少缓存值人工打开文件时,新公式会生成缓存值;validate 无论是否有缓存值都接受

评论

支持 Markdown