@wecom/wecom-openclaw-plugin 2026.9.15 → 2026.10.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/package.json +2 -2
  2. package/skills/wecomcli-sheet/SKILL.md +64 -107
  3. package/skills/wecomcli-sheet/references/sheet-conditional-formatting.md +211 -0
  4. package/skills/wecomcli-sheet/references/sheet-filter.md +187 -0
  5. package/skills/wecomcli-sheet/references/sheet-float-image.md +248 -0
  6. package/skills/wecomcli-sheet/references/sheet-formulas.md +73 -0
  7. package/skills/wecomcli-sheet/references/sheet-history.md +125 -0
  8. package/skills/wecomcli-sheet/references/sheet-protection.md +180 -0
  9. package/skills/wecomcli-sheet/references/sheet-range-operations.md +323 -0
  10. package/skills/wecomcli-sheet/references/sheet-read-data.md +153 -0
  11. package/skills/wecomcli-sheet/references/sheet-search-replace.md +111 -0
  12. package/skills/wecomcli-sheet/references/sheet-structure-operations.md +416 -0
  13. package/skills/wecomcli-sheet/references/sheet-style.md +246 -0
  14. package/skills/wecomcli-sheet/references/sheet-validation.md +243 -0
  15. package/skills/wecomcli-sheet/references/sheet-workbook.md +271 -0
  16. package/skills/wecomcli-sheet/references/sheet-write-cells.md +332 -0
  17. package/skills/wecomcli-sheet/references/xlsx-process.md +328 -0
  18. package/skills/wecomcli-sheet/scripts/collect.py +868 -0
  19. package/skills/wecomcli-sheet/scripts/recalc.py +403 -0
  20. package/skills/wecomcli-sheet/references/sheet-contents-update.md +0 -49
  21. package/skills/wecomcli-sheet/references/sheet-ranges-get.md +0 -47
  22. package/skills/wecomcli-sheet/references/sheet-rows-append.md +0 -47
  23. package/skills/wecomcli-sheet/references/sheet-subsheets-add.md +0 -28
  24. package/skills/wecomcli-sheet/references/sheet-subsheets-delete.md +0 -22
@@ -0,0 +1,323 @@
1
+ # 表格区域范围操作
2
+
3
+ 对指定 A1 区域执行操作:插入空白单元格并移位、删除单元格并回填、清除内容或样式、按多列排序、自动填充,以及复制或剪切区域。
4
+
5
+ ## 使用场景
6
+
7
+ | 操作需求 | CLI | 说明 |
8
+ | --- | --- | --- |
9
+ | 插入空白单元格 | `sheet ranges insert` | "在 B2 到 D2 插入空格,把原区域往下挪" |
10
+ | 删除单元格块 | `sheet ranges delete` | "删掉 A4 到 E6 这片区域,把下面内容往上挪" |
11
+ | 清除内容或全部内容与样式 | `sheet ranges clear` | "清空这块的值"、"这片区域全部清空还原默认" |
12
+ | 区域排序 | `sheet ranges sort` | "按 E 列降序排"、"先按部门升序再按金额降序" |
13
+ | 自动填充区域 | `sheet ranges autofill` | "根据 A1:A2 的规律填充 A3:A10"、"只复制样式" |
14
+ | 复制或剪切区域 | `sheet ranges copy` | "把 A1:B2 复制到 D1"、"剪切并只粘贴值" |
15
+
16
+ ## 批量局部区域操作的串行与索引规则
17
+
18
+ 当一个用户请求包含多个独立的局部单元格插入、删除或剪切操作时,前一次操作可能使后续区域的 A1 坐标失效,必须按以下规则执行:
19
+
20
+ 1. **直接调用时每轮只执行一个坐标变更 CLI**:模型直接调用 CLI 时,一次响应中最多调用一个 `sheet ranges insert`、`sheet ranges delete`,或一个 `mode=cut` 的 `sheet ranges copy`。禁止在同一轮并发调用多个坐标变更 CLI;取得当前调用结果后,下一轮才能继续处理剩余目标。
21
+ 2. **沿位移维度从大到小执行**:
22
+ - `ranges insert` 使用 `shift=down` 时,按区域起始行从大到小执行;
23
+ - `ranges insert` 使用 `shift=right` 时,按区域起始列从右到左执行;
24
+ - `ranges delete` 使用 `shift=up` 时,按区域起始行从大到小执行;
25
+ - `ranges delete` 使用 `shift=left` 时,按区域起始列从右到左执行。
26
+ 3. **相邻且规则一致的区域优先合并**:只有合并后仍准确表达用户目标且 `shift` 相同时,才合并为一次调用;不连续区域必须拆分并串行执行。
27
+ 4. **每次执行后校验剩余区域**:不得让多个调用继续使用操作前缓存的全部 A1 地址。若区域存在重叠、同行同列依赖,或前一次操作可能影响后续目标,应重新读取或重新计算下一目标。
28
+ 5. **剪切操作必须重新定位**:多个 `mode=cut` 操作不能简单套用倒序。每完成一次剪切后,应重新确认剩余源区域和目标锚点;源区域、目标区域或移动路径相互影响时,先处理依赖关系。
29
+
30
+ ### 目标较多时使用 Python 串行调用
31
+
32
+ 当独立的插入或删除区域较多、逐轮直接调用效率过低时,可以针对当前任务临时生成 Python 脚本批量调用 CLI。Python 只用于串行编排,不改变以上位移与索引规则:
33
+
34
+ - 只批量处理同一命令、同一子表、相同 `shift` 且相互独立的区域;先合并可安全合并的相邻区域,再沿位移维度从大到小排序。
35
+ - 逐个同步调用 CLI;等待当前调用结束并检查退出状态与返回结果后,才能执行下一个。禁止使用线程池、进程池、`asyncio`、后台进程或其他并发方式。
36
+ - 任意一步失败时立即停止,明确列出已完成、失败和未执行的区域;不得自动重试写操作,也不得从头重跑完整列表。继续处理前,先按最新表格状态重新生成剩余计划。
37
+ - Python 批量串行只适用于可按位移方向稳定倒序处理的独立 `ranges insert` / `ranges delete` 区域。`mode=cut` 仍须逐步执行,并在每次剪切后重新定位,不得按初始坐标写入循环批量执行。
38
+
39
+ 示例:以 `shift=up` 删除 `B3:D4` 和 `B10:D11` 时,先删除 `B10:D11`,取得结果后再删除 `B3:D4`;目标较多时也只能由 Python 按该顺序逐个同步调用。
40
+
41
+ 反例:在同一轮并发删除 `B3:D4` 和 `B10:D11`。若前者先完成,下方区域会上移,后一个调用仍使用旧坐标,可能删除错误内容。
42
+
43
+ ## 插入空白单元格
44
+
45
+ 在指定区域插入空白单元格,并将原有单元格向下或向右移动。不要用于插入整行或整列;整行整列操作请读 `sheet-structure-operations.md`
46
+
47
+ ### 命令
48
+
49
+ 使用 wecom-cli 工具按照下面格式调用
50
+
51
+ ```
52
+ wecom-cli sheet ranges insert --json '<JSON>'
53
+ ```
54
+
55
+ ### 入参
56
+
57
+ | 字段 | 类型 | 必填 | 说明 |
58
+ | --- | --- | --- | --- |
59
+ | `docid` | `string` | 是 | 工作簿定位 |
60
+ | `sheet` | `string` | 是 | 子表 ID 或名称 |
61
+ | `range` | `string` | 是 | 待插入空白单元格的纯 A1 区域 |
62
+ | `shift` | `string` | 是 | 原有单元格的移动方向:`down`(下移)/ `right`(右移) |
63
+ | `dry_run` | `bool` | 否 | 仅预览参数与影响区域,不执行插入 |
64
+
65
+ ### 出参
66
+
67
+ | 字段 | 类型 | 说明 |
68
+ | --- | --- | --- |
69
+ | `affected_range` | `string` | 实际插入的空白区域 A1 |
70
+ | `shift` | `string` | 实际使用的移动方向 |
71
+
72
+ ### 使用规则
73
+
74
+ - **`shift` 描述原内容的移动方向**:`down` 表示区域内及其下方相关内容向下移动,`right` 表示向右移动
75
+ - **多个插入区域必须分轮串行执行**:`shift=down` 时按区域起始行从大到小,`shift=right` 时按区域起始列从右到左;一次模型响应中只调用一次本命令,禁止并发插入。
76
+ - **预览后正式执行**:需要确认影响范围时先传 `dry_run=true`;正式执行时去掉 `dry_run` 或传 `false`。本命令没有 `yes` 参数,不要自行添加。
77
+
78
+ ## 删除单元格块
79
+
80
+ 删除指定区域内的单元格,并让下方或右侧单元格回填。破坏性操作。建议先传 `dry_run=true` 预览;正式执行时必须传 `yes=true`。
81
+
82
+ ### 命令
83
+
84
+ 使用 wecom-cli 工具按照下面格式调用
85
+
86
+ ```
87
+ wecom-cli sheet ranges delete --json '<JSON>'
88
+ ```
89
+
90
+ ### 入参
91
+
92
+ | 字段 | 类型 | 必填 | 说明 |
93
+ | --- | --- | --- | --- |
94
+ | `docid` | `string` | 是 | 工作簿定位 |
95
+ | `sheet` | `string` | 是 | 子表 ID 或名称 |
96
+ | `range` | `string` | 是 | 待删除单元格块的纯 A1 区域 |
97
+ | `shift` | `string` | 是 | 删除后的回填方向:`up`(下方内容上移)/ `left`(右侧内容左移) |
98
+ | `yes` | `bool` | 条件必填 | 正式执行时必须为 `true`;`dry_run=true` 时可省略 |
99
+ | `dry_run` | `bool` | 否 | 仅预览参数与影响区域,不执行删除 |
100
+
101
+ ### 出参
102
+
103
+ | 字段 | 类型 | 说明 |
104
+ | --- | --- | --- |
105
+ | `deleted_range` | `string` | 实际删除的区域 A1 |
106
+ | `shift` | `string` | 实际使用的回填方向 |
107
+
108
+ ### 使用规则
109
+
110
+ - **多个删除区域必须分轮串行执行**:`shift=up` 时按区域起始行从大到小,`shift=left` 时按区域起始列从右到左;一次模型响应中只调用一次本命令,禁止并发删除。
111
+ - **删除后会改变结构**:`up` 让下方单元格上移,`left` 让右侧单元格左移。要保留单元格位置、只清内容时使用 `sheet ranges clear`。
112
+
113
+ ## 清除区域内容或样式
114
+
115
+ 清除指定区域的内容、样式或两者,但不删除单元格,也不移动周边数据。破坏性操作。建议先传 `dry_run=true` 预览;正式执行时必须传 `yes=true`。
116
+
117
+ ### 命令
118
+
119
+ 使用 wecom-cli 工具按照下面格式调用
120
+
121
+ ```
122
+ wecom-cli sheet ranges clear --json '<JSON>'
123
+ ```
124
+
125
+ ### 入参
126
+
127
+ | 字段 | 类型 | 必填 | 说明 |
128
+ | --- | --- | --- | --- |
129
+ | `docid` | `string` | 是 | 工作簿定位 |
130
+ | `sheet` | `string` | 是 | 子表 ID 或名称 |
131
+ | `range` | `string` | 是 | 待清除的纯 A1 区域 |
132
+ | `scope` | `string` | 否 | 清除范围:`content`(仅内容)/ `style`(仅样式)/ `all`(内容和样式),默认 `content` |
133
+ | `yes` | `bool` | 条件必填 | 正式执行时必须为 `true`;`dry_run=true` 时可省略 |
134
+ | `dry_run` | `bool` | 否 | 仅预览参数与影响区域,不执行清除 |
135
+
136
+ ### 出参
137
+
138
+ | 字段 | 类型 | 说明 |
139
+ | --- | --- | --- |
140
+ | `cleared_range` | `string` | 实际清除的区域 A1 |
141
+ | `cleared_count` | `int32` | 清除的单元格数 |
142
+ | `scope` | `string` | 实际使用的清除范围 |
143
+
144
+ ### 使用规则
145
+
146
+ - **`clear` 不改变结构**:单元格位置和行列布局保持不变。需要删除单元格并回填时使用 `sheet ranges delete`。
147
+
148
+ ## 区域数据排序
149
+
150
+ 在原区域内按一个或多个排序键重排行。排序会原地移动整行中的值、公式、样式和空值。
151
+
152
+ ### 命令
153
+
154
+ 使用 wecom-cli 工具按照下面格式调用
155
+
156
+ ```
157
+ wecom-cli sheet ranges sort --json '<JSON>'
158
+ ```
159
+
160
+ ### 入参
161
+
162
+ | 字段 | 类型 | 必填 | 说明 |
163
+ | --- | --- | --- | --- |
164
+ | `docid` | `string` | 是 | 工作簿定位 |
165
+ | `sheet` | `string` | 是 | 子表 ID 或名称 |
166
+ | `range` | `string` | 是 | 待排序的纯 A1 区域,排序键列必须位于该区域内 |
167
+ | `columns` | `SortColumn[]` | 是 | 排序键列表;按数组顺序依次作为第一、第二等排序键 |
168
+ | `has_header` | `bool` | 否 | `true` 表示 `range` 首行为表头且不参与排序,默认 `false` |
169
+ | `dry_run` | `bool` | 否 | 仅预览参数与影响区域,不执行排序 |
170
+
171
+ ### `SortColumn` 入参
172
+
173
+ | 字段 | 类型 | 必填 | 说明 |
174
+ | --- | --- | --- | --- |
175
+ | `column` | `string \| int` | 是 | 子表中的绝对列:推荐使用列字母(如 `"E"`),也接受从 1 开始的列序号;不是 `range` 内的相对偏移 |
176
+ | `order` | `string` | 是 | 排序方向:`asc`(升序)/ `desc`(降序) |
177
+
178
+ ### 出参
179
+
180
+ | 字段 | 类型 | 说明 |
181
+ | --- | --- | --- |
182
+ | `sorted_range` | `string` | 实际参与排序的数据区域 A1;`has_header=true` 时不包含表头行 |
183
+ | `sorted_rows` | `int` | 实际参与排序的数据行数 |
184
+
185
+ **示例:**
186
+
187
+ 多级排序:先按 A 列升序,再按 E 列降序。
188
+
189
+ ```
190
+ wecom-cli sheet ranges sort --json '{
191
+ "docid": "e3_ABC123",
192
+ "sheet": "销售",
193
+ "range": "A1:F100",
194
+ "columns": [
195
+ {"column": "A", "order": "asc"},
196
+ {"column": "E", "order": "desc"}
197
+ ],
198
+ "has_header": true
199
+ }'
200
+ ```
201
+
202
+ ### 使用规则
203
+
204
+ - **排序键是子表绝对列**:若 `range` 从 C 列开始,`column: "E"` 仍表示子表 E 列,不表示 `range` 内第 E 列。
205
+ - **明确表头语义**:区域包含表头时传 `has_header=true`,否则默认值 `false` 会让首行参与排序。
206
+ - **排序区域包含合并单元格**:若 CLI 返回此错误,停止处理并告知用户手动排序。
207
+ - **排序区域与表格样式重叠**:若 CLI 返回此错误,停止处理并告知用户手动排序。
208
+ - **必须使用原生排序**:禁止通过“读取 → 本地排序 → 写回”模拟。写空值可能不覆盖目标单元格,且样式不会随行移动。
209
+
210
+ ## 自动填充区域
211
+
212
+ 根据源区域的内容或规律填充目标区域。用于扩展序列、复制单元格或仅延续样式;精确搬运一个固定区域时使用 `sheet ranges copy`。
213
+
214
+ ### 命令
215
+
216
+ 使用 wecom-cli 工具按照下面格式调用
217
+
218
+ ```
219
+ wecom-cli sheet ranges autofill --json '<JSON>'
220
+ ```
221
+
222
+ ### 入参
223
+
224
+ | 字段 | 类型 | 必填 | 说明 |
225
+ | --- | --- | --- | --- |
226
+ | `docid` | `string` | 是 | 工作簿定位 |
227
+ | `sheet` | `string` | 是 | 子表 ID 或名称 |
228
+ | `source_range` | `string` | 是 | 用于推断填充内容或规律的纯 A1 源区域 |
229
+ | `fill_range` | `string` | 是 | 实际要写入的纯 A1 目标区域,不包含 `source_range` |
230
+ | `fill_type` | `string` | 否 | `default` / `sequence` / `only_fill_style` / `fill_without_style` / `copy_cells`,默认 `default` |
231
+
232
+ ### 出参
233
+
234
+ | 字段 | 类型 | 说明 |
235
+ | --- | --- | --- |
236
+ | `source_range` | `string` | 实际使用的源区域 A1 |
237
+ | `fill_range` | `string` | 实际写入的目标区域 A1 |
238
+
239
+
240
+ ### 使用规则
241
+
242
+ - **源区域与目标区域分开填写**:`source_range` 是原始样本,`fill_range` 只写待填充区域。不要把源区域重复包含进目标区域。
243
+ - **按意图选择 `fill_type`**:自动判断复制或序列用 `default`;明确扩展序列用 `sequence`;只延续样式用 `only_fill_style`;填充内容但不带源样式用 `fill_without_style`;复制源单元格用 `copy_cells`。
244
+ - **自动填充与复制不同**:需要依据样本扩展规律时使用 `autofill`;需要把固定矩形区域原样搬到指定左上角时使用 `copy`。
245
+
246
+ ## 复制或剪切区域
247
+
248
+ 将一个固定矩形源区域复制或剪切到目标位置。源与目标可以位于同一子表、同一文档的不同子表,或不同文档;目标区域大小根据源区域自动确定。
249
+
250
+ ### 命令
251
+
252
+ 使用 wecom-cli 工具按照下面格式调用
253
+
254
+ ```
255
+ wecom-cli sheet ranges copy --json '<JSON>'
256
+ ```
257
+
258
+ ### 入参
259
+
260
+ | 字段 | 类型 | 必填 | 说明 |
261
+ | --- | --- | --- | --- |
262
+ | `docid` | `string` | 是 | 源 Sheet 文档 URL 或 docid |
263
+ | `sheet` | `string` | 是 | 源子表 ID 或名称 |
264
+ | `range` | `string` | 是 | 要复制或剪切的纯 A1 源区域 |
265
+ | `target_docid` | `string` | 否 | 目标 Sheet 文档 URL 或 docid |
266
+ | `target_sheet` | `string` | 否 | 目标子表 ID 或名称 |
267
+ | `to` | `string` | 是 | 目标子表中的左上角锚点单元格,如 `D1`;目标区域大小由源区域自动确定 |
268
+ | `mode` | `string` | 否 | `copy`(保留源区域)/ `cut`(搬运后清除源区域),默认 `copy` |
269
+ | `paste_type` | `string` | 否 | `all`(全部)/ `values`(仅值)/ `formats`(仅格式),默认 `all` |
270
+ | `dry_run` | `bool` | 否 | 仅预览源区域、目标位置及操作影响,不实际执行 |
271
+ | `yes` | `bool` | 条件必填 | `mode=cut` 正式执行时必须为 `true`;`dry_run=true` 时可省略 |
272
+
273
+ ### 出参
274
+
275
+ | 字段 | 类型 | 说明 |
276
+ | --- | --- | --- |
277
+ | `copied_range` | `string` | 实际处理的源区域 A1;字段名固定,`mode=cut` 时也返回该字段 |
278
+ | `pasted_range` | `string` | 根据源区域大小计算出的实际目标区域 A1 |
279
+ | `copied_cells` | `int32` | 搬运的单元格数量 |
280
+ | `mode` | `string` | 实际使用的操作模式:`copy` / `cut` |
281
+ | `paste_type` | `string` | 实际使用的粘贴类型:`all` / `values` / `formats` |
282
+ | `note` | `string` | 本次操作的保真度限制说明 |
283
+
284
+ **示例:**
285
+
286
+ 同一文档跨子表复制:把“销售”子表 A1:B2 复制到“汇总”子表 D1:E2:
287
+
288
+ ```
289
+ wecom-cli sheet ranges copy --json '{
290
+ "docid": "e3_ABC123",
291
+ "sheet": "销售",
292
+ "range": "A1:B2",
293
+ "target_sheet": "汇总",
294
+ "to": "D1",
295
+ "mode": "copy",
296
+ "paste_type": "all"
297
+ }'
298
+ ```
299
+
300
+ 跨文档复制:`target_docid` 和 `target_sheet` 共同定位目标。
301
+
302
+ ```
303
+ wecom-cli sheet ranges copy --json '{
304
+ "docid": "e3_SOURCE123",
305
+ "sheet": "销售",
306
+ "range": "A1:B2",
307
+ "target_docid": "e3_TARGET456",
308
+ "target_sheet": "归档",
309
+ "to": "A1",
310
+ "mode": "copy",
311
+ "paste_type": "values"
312
+ }'
313
+ ```
314
+
315
+ ### 使用规则
316
+
317
+ - **分别定位源和目标**:`docid`、`sheet`、`range` 描述源;`target_docid`、`target_sheet`、`to` 描述目标。不要把目标子表填入 `sheet`。未传 `target_docid` 时目标仍在源文档,未传 `target_sheet` 时目标仍在源子表。
318
+ - **`to` 属于目标子表且只传左上角单元格**:源 `A1:B2` 搬到目标 `D1` 时,实际目标区域为 `D1:E2`;不要把 `to` 写成 `D1:E2`。
319
+ - **根据用户意图选择模式**:用户说“复制”“拷贝”时使用 `mode=copy`;说“剪切”“移动”“搬到……并删除原内容”时使用 `mode=cut`。命令名虽然是 `copy`,仍通过 `mode` 决定实际操作。
320
+ - **根据用户意图选择粘贴内容**:完整保留内容和格式用 `all`;只要单元格值用 `values`;只要格式用 `formats`。用户未指定时使用默认值 `all`。
321
+ - **剪切必须经过确认门禁**:先用 `mode=cut, dry_run=true` 核对源区域、目标文档、目标子表和自动推导出的完整目标区域;正式执行时去掉 `dry_run` 或传 `false`,并传 `yes=true`。`yes` 仅用于 `cut` 门禁,不要因普通 `copy` 自行添加。
322
+ - **多个剪切任务必须分轮串行执行**:一次模型响应中只执行一个 `mode=cut` 调用;每次剪切完成后,重新确认剩余源区域和目标锚点,不得只按初始坐标并发或连续提交。普通 `mode=copy` 不适用索引倒序规则,但目标存在覆盖关系时仍应串行执行。
323
+ - **关注保真度说明**:执行后检查返回的 `note`;若其中存在限制,向用户说明本次复制或剪切未能保真的内容。
@@ -0,0 +1,153 @@
1
+ # 读取表格数据
2
+
3
+ ## 前置必做
4
+
5
+ ### 获取工作簿全局结构
6
+
7
+ 读取 `sheet-workbook.md`,通过 `wecom-cli sheet workbook get` 获取全部子表的 `sheet_id`、名称和范围。后续读取优先使用稳定的 `sheet_id`。
8
+
9
+ - 用户明确指定唯一子表,且全部要求均可由该子表回答时,可只读取该子表;
10
+ - 用户只提供工作簿链接、使用“这张表/整个表格/全部数据”等工作簿级表达,或一次要求多个不同指标时,不得默认第一个业务子表就是唯一数据源;
11
+ - 无法唯一确定目标子表,且不同选择会改变结果时,先向用户确认;能够通过字段、分类值或记录内容定位时(读取 `sheet-search-replace.md`,使用 `wecom-cli sheet cells find`),先执行工作簿级搜索,不要先追问。
12
+
13
+ ### 探查候选子表结构
14
+
15
+ 将候选子表的 `sheets[].range` 作为探查上界,按以下规则预读数据:
16
+
17
+ - **必须读取公式**:结构探查必须使用 `cells get` 并传入 `include:["formula"]`;不得使用与 `include` 互斥的 `csv` 模式探查,否则无法识别公式列;
18
+ - 总行数不超过 20 行时,读取全部数据;
19
+ - 总行数超过 20 行时,首次至少读取前 20 行;预读范围必须覆盖完整列跨度。例如工作簿返回 `A1:Z301`,首次探查至少为 `A1:Z20`;
20
+
21
+ 根据预读数据判断表头位置和数据展开方向,不要默认第一行就是表头:
22
+
23
+ - **横向表头**:字段位于前一行或前几行,数据按行向下展开;
24
+ - **纵向表头**:字段、指标或分类位于前一列或前几列,数据按列向右展开;
25
+ - **交叉表头**:前几行和前几列共同构成表头,数据由行标签与列标签的交点定位;
26
+ - **多级表头**:一个字段可能由多行或多列标签共同表达,需要结合上下级标签理解完整含义。
27
+
28
+ 同时区分表格标题、说明、单位、空行空列、父级分组行、汇总行与真正的字段标签和明细记录。结合相邻数据的类型和分布确定表头边界、数据起始位置和记录粒度。
29
+
30
+ 写入任务中,必须根据上述带 `include:["formula"]` 的预读结果识别公式列;仅有单元格值的探查结果不能用于判断。后续新增或补写公式列时,沿用相邻记录的公式结构并调整相对引用,禁止自行计算后写入静态值。公式写入与校验按 `sheet-write-cells.md` 执行。
31
+
32
+ ### 映射字段并确定实际读取范围
33
+
34
+ 根据识别出的表头,将用户提到的字段、时间、人员、分类或指标映射到实际行列,计算最终 A1 `range`:
35
+
36
+ - 20 行数据不足以判断表头、记录粒度或目标标签时,沿数据展开方向继续扩大探查范围;
37
+ - 需要完整统计时,读取范围必须覆盖全部参与计算的记录和字段,不能只读取样本;
38
+ - 多轮对话中出现新字段、新维度、新时间范围、新分类或新指标时,重新执行需求覆盖检查。当前子表无法覆盖新增要求时,重新做工作簿级定位,不得机械复用上一轮的 `sheet_id`、缓存文件或读取范围。
39
+
40
+ ## 先判断:局部查询还是完整统计
41
+
42
+ | 任务类型 | 典型请求 | 完整性要求 | 数据获取方式 |
43
+ |---|---|---|---|
44
+ | 已知小范围局部查询 | 查看 `B2:D10`、读取已定位记录的相邻列、确认某个单元格值 | 只需覆盖明确 A1 范围 | 可用 `cells get` |
45
+ | 结构探查 | 识别表头、字段列、数据展开方向、记录粒度 | 只需样本,不得输出完整统计结论 | 用 `cells get` 小范围采样 |
46
+ | 完整统计分析 | 实际多少行/人数/订单数、计数、分组、汇总、去重、排序、TopN、占比、趋势、跨子表比较、完整列表 | 必须覆盖全部参与计算的记录 | 按下方当前环境对应的“完整统计执行流程”处理 |
47
+
48
+ **硬门禁**:只要结论会因漏掉任意后续记录而变化,就属于完整统计分析。
49
+
50
+ ## 读取单元格数据
51
+
52
+ ### 命令
53
+
54
+ 使用 wecom-cli 工具按照下面格式调用
55
+
56
+ ```
57
+ wecom-cli sheet cells get --json '<JSON 参数>'
58
+ ```
59
+
60
+ ### 参数
61
+
62
+ | 字段 | 类型 | 必填 | 说明 |
63
+ |---|---|---|---|
64
+ | `docid` | string | 是 | 工作簿定位 |
65
+ | `sheet` | string | 是 | 子表 ID 或名称;大表和自动化任务优先传子表 ID |
66
+ | `range` | string | 否 | 纯 A1 区域,如 `A1:B3`;大表读取必须显式传入分批后的范围 |
67
+ | `include` | array(string) | 否 | 要额外返回的维度,可任意组合:`formula` / `style` |
68
+ | `csv` | bool | 否 | 以 CSV 文本返回;与 `include` 互斥 |
69
+
70
+ > 当前协议没有定义省略 `range` 时的精确读取边界。需要完整读取子表时,先通过 `sheet-workbook.md` 获取 `sheets[].range`,再自行分批读取,不要直接省略 `range`。
71
+
72
+ ### 返回
73
+
74
+ | 字段 | 类型 | 必填 | 说明 |
75
+ |---|---|---|-------------------------------------------------|
76
+ | `cells` | array(2D) | 条件 | 2D 单元格数组;未截断时维度与请求区域一致,截断时维度与 `actual_range` 一致 |
77
+ | `csv_data` | string | 条件 | CSV 文本(`csv=true` 时返回,此时不返回 `cells`) |
78
+ | `actual_range` | string | 否 | 实际读取的区域 A1 |
79
+ | `truncated` | bool | 否 | 是否因单次读取上限而截断(单次读区上限 8,000 格) |
80
+
81
+ ### `cells` 中的单元格格式
82
+
83
+ `cells` 是二维数组,每个元素为一个 `Cell` 对象;无内容或未请求的字段会省略。
84
+
85
+ | 字段 | 类型 | 说明 |
86
+ |---|---|---|
87
+ | `value` | any | 单元格值,自动推断类型 |
88
+ | `formula` | string | 公式,仅在 `include` 包含 `formula` 时返回 |
89
+ | `link` / `link_text` | string | 超链接 URL / 展示文本 |
90
+ | `image` | string | 图片 URL |
91
+ | `rich_string` | array | 富文本分段,按顺序组成单元格内容 |
92
+ | `style` | object | 单元格样式,仅在 `include` 包含 `style` 时返回 |
93
+
94
+ `rich_string` 的每段使用 `value` 表示文本,或使用 `link` + `link_text` 表示链接,可带独立的 `style`。
95
+
96
+ `style` 可能包含:
97
+
98
+ - 字体:`font_family`、`font_size`、`bold`、`italic`、`underline`、`strike`、`font_color`
99
+ - 单元格:`bg_color`、`horizontal_align`、`vertical_align`、`wrap`
100
+ - 数字显示:`number_format`(Excel 格式代码)
101
+
102
+ 颜色使用 8 位 ARGB hex,如 `"FFFF0000"`;返回对象只包含实际存在的样式字段。
103
+
104
+ ### 响应示例(`include: ["formula","style"]`)
105
+
106
+ ```json
107
+ {
108
+ "cells": [
109
+ [{"value": "名称", "style": {"bold": true, "bg_color": "FFFFFF00"}}, {"value": "详情"}],
110
+ [{"value": "苹果"}, {"formula": "=SUM(C2:C10)", "value": 1560, "style": {"number_format": "0.00"}}]
111
+ ],
112
+ "actual_range": "A1:B2",
113
+ "truncated": false
114
+ }
115
+ ```
116
+
117
+ ### 使用原则
118
+
119
+ - 只看值、不需要公式和样式时,使用 `csv` 模式,减少返回体和模型上下文占用。
120
+ - 需要保留值类型、公式、链接、图片、富文本或样式时,使用 `cells` 模式。
121
+ - `cells get` 的核心用途是局部查询与结构探查;完整统计分析按下方“完整统计执行流程”处理。
122
+ - 原始表格数据不得复制进模型上下文或 Python 命令;脚本应直接读取落盘文件。
123
+
124
+ ### 将回包直接落盘
125
+
126
+ 需要把 CLI 回包保存为 JSON 文件时,无需先将完整回包载入模型上下文后再另行写入文件。使用 wecom-cli 工具按照下面格式调用:
127
+
128
+ ```
129
+ wecom-cli sheet cells get --json '<JSON 参数>' --output '<文件路径>'
130
+ ```
131
+
132
+ **落盘格式必须正确理解**:
133
+
134
+ - `--output` 保存的是 CLI 的 **JSON 响应外壳**,不是可直接交给 pandas 的原始 CSV 文件;
135
+ - 请求使用 `"csv":true` 时,真正的表格数据只在 JSON 的 `csv_data` 字段中;必须解析 JSON 后提取 `csv_data`,不能对整个 `.json` 文件执行 `pd.read_csv()`;
136
+ - 未使用 `csv` 模式时,真正的表格数据在 `cells` 字段中;`actual_range` 和 `truncated` 是元数据,不是业务数据;
137
+ - 每个落盘响应都必须先检查 `truncated`。若为 `true`,该文件只含被截断的数据,禁止用于完整统计;
138
+ - 分块读取时,每批单独落盘,并由脚本从各 JSON 文件中提取 `csv_data` 或 `cells` 后按范围顺序合并。
139
+
140
+ ## 数据统计分析执行流程
141
+
142
+ 1. 基于 `sheets[].range` 预先生成覆盖全部目标行列的分块读取计划,每批不超过 8,000 格;
143
+ 2. 每批使用 `--output '<批次文件>.json'` 落盘,并逐批校验 `truncated:false` 与 `actual_range`;
144
+ 3. 由脚本直接读取全部批次 JSON,从 `csv_data` 或 `cells` 提取并按范围合并数据,形成数据最终文件;
145
+ 4. 编写 Python 脚本对最终数据文件进行统计分析
146
+ 5. 校验计划范围无缺口、无重复,所有目标子表均已处理后,才能输出统计结论
147
+
148
+ ## 读取与搜索的边界
149
+
150
+ - `cells get` 用于理解表头、读取已知 A1 区域,以及在已定位单元格后读取其所在行或相邻上下文。它不是按内容查找目标位置的接口。
151
+ - 当待查找的目标文本已知,但其所在子表、单元格地址或行号未知时:读取 `sheet-search-replace.md`,使用 `wecom-cli sheet cells find` 定位。
152
+ - 分析任务中当前子表缺少所需字段、分类值或记录时,先省略 `sheet` 做工作簿级搜索,再读取命中位置上下文;不要直接改为读取当前子表的更大范围。
153
+ - `cells find` 返回分页结果时必须读取到 `next_cursor` 为空;只读取首页不能用于完整统计或工作簿级否定结论。
@@ -0,0 +1,111 @@
1
+ # 单元格搜索与替换
2
+
3
+ 在子表(或整个工作簿)中搜索文本命中位置,或在指定子表区域内查找并替换文本。
4
+
5
+ ## 使用场景
6
+
7
+ | 操作需求 | CLI | 说明 |
8
+ | --- | --- | --- |
9
+ | 搜索文本并返回命中位置 | `sheet cells find` | 只读搜索,可搜索指定子表或整个工作簿 |
10
+ | 在指定区域查找并替换文本 | `sheet cells replace` | 写操作,可先用 `dry_run` 预览替换结果 |
11
+
12
+ ## 单元格搜索
13
+
14
+ ### 命令
15
+
16
+ 使用 wecom-cli 工具按照下面格式调用
17
+
18
+ ```
19
+ wecom-cli sheet cells find --json '<JSON>'
20
+ ```
21
+
22
+ ### 入参
23
+
24
+ | 字段 | 类型 | 必填 | 说明 |
25
+ | --- | --- | --- |-----------------------------------------|
26
+ | `docid` | `string` | 是 | 工作簿定位 |
27
+ | `sheet` | `string` | 否 | 子表 ID 或名称。**不传则搜索整个工作簿** |
28
+ | `keyword` | `string` | 是 | 搜索关键字 |
29
+ | `range` | `string` | 否 | 限定搜索 A1 区域,缺省整表。**跨表搜索时不传 `sheet`,本字段无效** |
30
+ | `match_case` | `bool` | 否 | 大小写敏感,默认 `false` |
31
+ | `match_entire_cell` | `bool` | 否 | 整单元格完整匹配,默认 `false` |
32
+ | `use_regex` | `bool` | 否 | 按正则表达式搜索,默认 `false` |
33
+ | `match_formulas` | `bool` | 否 | 搜索公式字符内容,默认 `false` |
34
+ | `include` | `string[]` | 否 | 是否返回公式内容:`formula` |
35
+ | `cursor` | `string` | 否 | 分页游标。首页传空字符串或不传;后续页传上一页的 `next_cursor` |
36
+ | `limit` | `int32` | 否 | 每页条数,默认 `50`,最大 `100` |
37
+
38
+ ### 出参
39
+
40
+ | 字段 | 类型 | 说明 |
41
+ | --- | --- | --- |
42
+ | `matches` | `Match[]` | **当前页**命中项,结构见下 |
43
+ | `total` | `int` | 命中总数(**所有页合计**)|
44
+ | `next_cursor` | `string` | 下一页游标。**为空字符串表示已是最后一页** |
45
+
46
+ **`Match` 结构:**
47
+
48
+ | 字段 | 类型 | 说明 |
49
+ | --- | --- | --- |
50
+ | `sheet_id` | `string` | 命中所在的子表 ID |
51
+ | `address` | `string` | A1 地址,如 `"A2"` |
52
+ | `cell` | `Cell` | 命中单元格的内容,结构同读写 `Cell`(见 `sheet-write-cells.md` 的 `Cell` 定义)|
53
+
54
+ ### 大数据直接落盘
55
+
56
+ 支持把回包内容保存为 JSON 文件,无需先将完整回包载入模型上下文后再另行写入文件。使用 wecom-cli 工具按照下面格式调用:
57
+
58
+ ```
59
+ wecom-cli sheet cells find --json '<JSON 参数>' --output '<文件路径>'
60
+ ```
61
+
62
+ ### 使用规则
63
+
64
+ - 跨表搜索时 `range` 无效:不传 `sheet` 即搜索整个工作簿,此时 `range` 字段被忽略;要限定区域必须同时传 `sheet`。
65
+ - 统计或分析任务中,若当前子表缺少某个必需字段、分类值或记录,省略 `sheet` 执行工作簿级搜索;不得在单一子表未命中后直接断言整个工作簿不存在。
66
+ - `matches` 只代表当前页。存在 `next_cursor` 时持续翻页直到为空;只读取第一页不能用于全量计数或负向结论。
67
+
68
+ ## 查找替换单元格内容
69
+
70
+ ### 命令
71
+
72
+ 使用 wecom-cli 工具按照下面格式调用
73
+
74
+ ```
75
+ wecom-cli sheet cells replace --json '<JSON>'
76
+ ```
77
+
78
+ ### 入参
79
+
80
+ | 字段 | 类型 | 必填 | 说明 |
81
+ | --- | --- |----|------------------------------------|
82
+ | `docid` | `string` | 是 | 工作簿定位 |
83
+ | `sheet` | `string` | 是 | 子表 ID 或名称 |
84
+ | `range` | `string` | 否 | 查找替换的纯 A1 区域,不填默认全子表 |
85
+ | `find_text` | `string` | 是 | 要查找的文本 |
86
+ | `replace_text` | `string` | 是 | 替换后的文本 |
87
+ | `match_case` | `bool` | 否 | 是否区分大小写;`true` 表示区分,默认 `false` |
88
+ | `match_entire_cell` | `bool` | 否 | 是否要求整单元格完整匹配,默认 `false` |
89
+ | `find_in_formula` | `bool` | 否 | 是否匹配公式表达式;`true` 表示匹配公式,默认 `false` |
90
+ | `dry_run` | `bool` | 否 | 预览替换结果但不执行,默认 `false` |
91
+
92
+ ### 出参
93
+
94
+ | 字段 | 类型 | 说明 |
95
+ | --- | --- | --- |
96
+ | `replaced_cells` | `int` | 完成替换的单元格数 |
97
+ | `replacements` | `Replacement[]` | 替换明细,结构见下 |
98
+ | `replacements_truncated` | `bool` | `true` 表示替换明细因数量限制被截断 |
99
+
100
+ **`Replacement` 结构:**
101
+
102
+ | 字段 | 类型 | 说明 |
103
+ | --- | --- | --- |
104
+ | `sheet_id` | `string` | 替换所在的子表 ID |
105
+ | `address` | `string` | 被替换单元格的 A1 地址 |
106
+ | `cell` | `string` | 替换后的单元格文本 |
107
+
108
+ ### 使用规则
109
+
110
+ - 替换是写操作;范围较大或匹配条件可能过宽时,先传 `dry_run=true` 查看影响范围,再正式执行。
111
+ - `find_in_formula=true` 时匹配公式表达式;否则按单元格显示文本查找。