# 飞书表格核心操作：分析、编辑与可视化

## 概览

面向"已有飞书表格"的核心工作流，核心原则：**先了解，再分析或写入，最后验证**。本文是方法论总纲；具体工具的参数细节、边界陷阱在对应 reference，本文用指针引到那里，不重复展开。

**三份「通用方法与规范」如何分工**（都不含 shortcut，按主题单一归属）：

- **本文（core-operations）= 流程与铁律**：端到端工作流 + 全局铁律 + 横切陷阱，是读取入口与枢纽。
- **`lark-sheets-visual-standards` = 样式知识**：配色 / 表头 / 数值格式 / 斑马纹 / 美化决策等"正确视觉输出"的全部标准。
- **`lark-sheets-formula-translation` = 公式知识**：飞书公式书写与 Excel 迁移的全部正确性规则（绝对引用、范围语法、数组语义、不支持函数等）。

> **下面的铁律对所有任务一律生效**，即使你是被索引直接路由进 visual 或 formula 而没经过本文——编辑类任务务必先回到这里过一遍铁律。

## 铁律（所有编辑类任务必须满足，各 reference 不得放宽）

1. **最小改动**：除用户明示要改的单元格 / 列外，原表其它单元格、行列结构、Sheet 名、合并区、格式必须 1:1 保持。中间结果优先放原数据**右侧**；会与原数据混淆或要承载透视表 / 图表时才**新建空白 Sheet**。**禁止**擅自删 / 改名 / 隐藏 / 移动**已存在**的 Sheet（新建允许，节制使用）。**改写 / 转换类任务要精确圈定适用行列**：只对任务真正要求的对象做变换，**不该转的行 / 列保持原值 1:1**（典型反例：要求"统一翻译"时把本就是中文、应原样保留的评论也重新翻译；要求"改写某列格式"时连原始测量值也一并改动 → 应保留的原文被篡改）。
2. **真实写回 + 回读校验**：交付必须是对在线表格的真实写入，并 `+csv-get` / `+cells-get` / `+<对象>-list` 回读校验。**严禁**只在文本里描述"已完成"、用普通公式 / 文本假装结构化对象、或只给占位而无真实写入。**收尾前必须确认产物文件真实存在 / 可导出**——别在没真正生成产物时只凭文本"已完成"就结束（反例：文本称已完成，实际没生成产物文件，等于没交付）。
3. **读全再写，禁止只探前 N 行**：批量填充 / 补齐 / 修正类任务必须先确认**真实数据末行**再写，否则会漏写表尾。完整的"按表格形态分流读取 + `current_region` / `has_more` 兜底 + 真实末行确认"流程见 `lark-sheets-read-data` 的「确定数据范围的正确流程」。
4. **公式优先于硬编码**：能用飞书公式表达的计算（总计 / 占比 / 增长率 / 提取 / 查找等）一律写公式而非静态值，源数据变化才能自动重算。用户口头的"分列 / 排序 / 求和 / 提取"也要落地为公式或原生工具（SORT / `TEXTBEFORE` / `MID` / 透视表 等）。Excel 公式迁移、数组语义、不支持函数清单一律以 `lark-sheets-formula-translation` 为唯一权威。**即使用户没说"联动 / 自动更新"，凡是可由表内其它单元格推导的派生值（年龄=当年-出生年、占比=本类数/总数、达标=阈值判断、排名、各类分组汇总）默认就必须用公式**——用户默认期望派生列能随源数据重算，**离线 Python / 脚本算完写静态值，即便当前数值正确，改了源数据也不会自动更新，等于没满足"派生"的本意**（反例：年龄、月度汇总、占比、分组求和等派生列写死值，源数据一改结果就过时）。
5. **续写 / 扩展必须继承样式**：续写、补齐、复制区块、新增行列时，**禁止**只读值只写值。必须连带 `cell_styles` + `border_styles` + 合并 + 行高一起继承。完整继承清单与做法见 `lark-sheets-write-cells` 的「新增列 / 新增行的样式继承」（`border_styles` 四边最易漏）。
6. **多步写入优先 `+batch-update`**：多个连续写入、或同一工具对多个区域重复调用（多次 merge / resize / cells-set），必须合并为单次原子 `+batch-update`。语义与不可嵌套的限制见 `lark-sheets-batch-update`。
7. **分组汇总必须用透视表**："按 X 统计 Y / 分组汇总 / 各部门数量金额"必须用 `+pivot-{create|update|delete}`（推荐省略 sheet_id 自动新建子表），**禁止**用 SUMIF / COUNTIF 或本地脚本覆盖原表替代。
8. **任务拆成可验证 checklist**：落地前把指令拆成所有"独立可验证子要点"，每点一个 `assert`，全部通过才交付：多维度操作（按部门一/二/三级排序）每维一个 assert；多目标（删 N 行）每目标一个；多格式兼容（多种日期格式）每种至少一个样本；范围类（A1:H11 加边框）起 / 末行 / 末列三边界都核。只完成第一个要点（只排一级、只删 1 行）属违规。**题面 / 表头里写明的格式规范也是子要点**：表头注明"需标注某字段"就必须给对应单元格加规定前缀并逐条 assert 前缀存在（反例：漏加规定前缀，该要点即不达标）；"相同编号连续行合并"必须遍历所有相同编号组全部合并（反例：只合并了其中一部分组）。
9. **全量处理要前置断言条数**：翻译 / 打标 / 批量公式落地等逐条任务，落地前把"预期处理条数"硬编码进代码，处理完 `assert actual == expected`。**严禁**输出"已完成前 N 条，剩余将继续"的半成品。

## 推荐工作流程

1. **规划 reference 清单**：开工前一次性列出本任务要读的 reference（避免读一个调一个），本轮已读过的不重复读。本文 + `lark-sheets-workbook` 几乎每次都要。
2. **了解结构**：先 `+workbook-info` 拿子表列表 / 行列数 / 冻结位置（不可猜测，猜错会越界覆盖）；涉及合并 / 隐藏 / 分组 / 行高列宽再用 `lark-sheets-sheet-structure` 的 `+sheet-info`。
3. **读取数据（按任务类型选路径，细则见 `lark-sheets-read-data`）**：

   | 用户需求语义 | 路径 |
   |---|---|
   | "完善 / 补齐 / 填空 / 修正所有 XX" / 数据分析 / 清洗 / 大数据集 | **A：原生优先**（公式 / `+pivot` / `+filter`，见第 5 步）；原生表达不了或更复杂时**分批 `+csv-get` 导出 + 本地脚本处理 + 分批回写**（默认覆盖所有对应数据行，不以用户选区为准；脚本与 CLI 配合见下方「CLI 配合要点」） |
   | "查一下 / 看看 / 统计 / 汇总" 等只读 | B：`+csv-get` 读到上下文 |
   | 需要公式 / 样式 / 批注 | C：`+cells-get` |
   | 续写 / 扩展 / 完善已有内容 | D：`+csv-get` 看结构 + `+cells-get` 读源区样式 + `+sheet-info --include row_heights,merges`（见铁律 5） |

   **注意**：对"完善 / 补齐 / 填空"类任务用路径 B 探 10 行就写入，实测会漏写表尾多行。写入前必须按 `lark-sheets-read-data`「确定数据范围的正确流程」确认真实数据末行。按关键字定位区域用 `lark-sheets-search-replace` 的 `+cells-search`。

4. **理解数据语义（写入前必做）**：读表头 + 3-5 行样本确认各列含义与格式（文本 / 数字 / 日期 / 混合）；写公式前先分析样本值格式模式再选提取策略；建透视表前先列清"行字段=分组维度、值字段=聚合指标"。需求模糊时（如"加入加减乘除"未说逻辑）基于表头与已有公式推断，不确定就问用户，禁止臆造业务逻辑。

5. **分析与计算（原生工具优先，代码兜底）**：飞书原生能力能随数据自动更新，**必须优先**：

   | 用户需求 | 必须用的原生工具 | 禁止用代码替代 |
   |---|---|---|
   | 按 X 统计 Y、分组汇总 | `+pivot-{create\|update\|delete}` | pandas groupby → `+cells-set` |
   | 求和 / 计数 / 平均 / 占比 | 公式（SUM/COUNT/AVERAGE） | Python 算 → 写静态值 |
   | 画图表 / 可视化 | `+chart-{create\|update\|delete}` | matplotlib 画图 |
   | 条件高亮 / 色阶 | `+cond-format-{create\|update\|delete}` | 逐单元格设样式 |
   | 数据筛选 | `+filter-{create\|update\|delete}` | pandas filter → 覆盖写入 |
   | 文本提取 / 转换 | 公式（REGEXEXTRACT/TEXT/VALUE） | Python 正则 → 写静态值 |
   | 查找匹配 | 公式（VLOOKUP/INDEX+MATCH） | pandas merge → 写静态值 |

   **只有以下才用代码**：多步清洗流水线、统计建模、公式试错 3 次仍失败的降级。代码结果回写：大块纯值用 `+csv-put`（+ `--start-cell`，必要时自动扩容）；少量或需公式 / 样式用 `+cells-set`；能用飞书公式表达的写飞书公式。

6. **写入与修改（细节见 `lark-sheets-write-cells`）**：`+cells-set` 的 `range` 必须落在已有行列范围内、`cells` 二维数组与 `range` 严格同维；表尾追加先用 `+dim-insert` 插行列再写；整列 / 整行同结构的值 / 公式 / 格式用模板单元格 + `--copy-to-range`，禁止逐行 `+cells-set`；多步写入合并为 `+batch-update`；改尺寸先读相邻可见行列当前尺寸再决定 `pixel` / `standard` / `auto`，不要猜数值。

7. **验证**：重新读取受影响区域确认值 / 公式 / 样式 / 批注符合预期；对象类（图表 / 透视表 / 条件格式 / 筛选 / 迷你图 / 浮动图片）重新读对象配置确认；出错先定位错误类型 / 受影响区域 / 根因再修复重验。

## 用本地代码 / 脚本时的 CLI 配合要点

复杂处理——多步清洗、统计建模、批量转换、语义任务的分批编排等——用代码（`python` / `node` 等）解决是完全正当的。原生能力（公式 / `+pivot` / `+filter`）能表达就优先用（可随源数据自动重算）；原生表达不了或逻辑更复杂时，放手用代码。下面几条让脚本与 CLI 顺畅配合：

- **解析输出时只读 stdout**：CLI 把数据 JSON 写到 stdout、把诊断与警告写到 stderr。解析 JSON 时**不要合并这两条流**（即不要 `2>&1`），否则警告行混进 JSON 会让解析失败。用管道（`lark-cli … | jq …`）或先把 stdout 单独重定向到文件再读；需要诊断信息时把 stderr 另导到一个文件。
- **喂给 CLI 的 CSV / JSON 用 UTF-8、不带 BOM**：BOM 会污染首格的值或触发 `invalid character` 解析错；脚本读写文件时显式指定 `encoding='utf-8'`。
- **临时文件交给运行时的标准库**：用 `tempfile.gettempdir()` / `os.tmpdir()` 等取临时目录，不要硬编码固定路径；放在用户项目目录之外。
- **命令失败先读错误再调整**：同一条命令失败后不要原样重发；先看 stderr 的报错（参数错误、缺依赖、解释器不可用等）定位原因，再决定换写法、补依赖或退回原生工具。
- **写回的必须是纯单元格值，禁止把"值+样式标注"串当值写回**：本地脚本或某些 xlsx 解析库会把单元格渲染成 `甲方支行(V-Align: bottom)` 这种"值(样式)"字符串，CSV 字段还可能带包裹双引号。回写前必须**剥离括号样式标注、去掉残留引号**，只写原始值——否则样式描述会变成单元格的字面文本污染原数据（反例：排序后单元格值里被写进 `(V-Align: bottom)` 这类样式后缀文本，末尾还多一个双引号）。**排序本身优先用 `+range-sort` 原生工具**，不要"读出来本地排完再整列写回"，从根上避免这类回写污染。

## 公式策略

- **公式优先于硬编码**（同铁律 4）：能用公式表达的计算一律写公式，源数据变化才能自动重算。
- **写任何公式前先读 `lark-sheets-formula-translation`**：它是公式正确性的唯一权威，覆盖绝对引用（`$`）、飞书范围语法（`H:H` 与工具 A1 表示法的区别）、ARRAYFORMULA / 数组语义、Excel 迁移、不支持函数清单等全部规则。本文不再单列这些细则。

## 常见陷阱（铁律已覆盖的不再重复，仅列易漏点）

- **合并单元格**：合并区只有左上角存数据，其余读为空是正常行为；写入只能写左上角，写其它位置会报 `cell ... is inside a merged region`。改合并区先取消再操作。安全操作 5 条与"批量取消用大 range 一次调用"见 `lark-sheets-range-operations`。
- **`+dim-insert` 不继承行高**：`--inherit-style before/after` 只继承值 / 公式 / 边框，不继承 `row_height`，新行会回落默认高度截断长文本；中间插行填文本前先读相邻行 `row_height`，用 `+batch-update` 合 `+rows-resize` 补齐。
- **公式容错**：日期 / 查找 / 数值转换公式用 `IFERROR` 包裹；写完读结果列首 5 + 末 5 行查 `#VALUE!` / `#NAME?` / `#REF!` / `#DIV/0!`；同一方案试错上限 3 次，超了改代码以值写入。
- **循环引用**：聚合公式（SUM/AVERAGE）引用范围不能含目标 cell 自身或其传递依赖。
- **NaN / 空值 / 除零**：空值不直接参与运算；除法用 `IF` / `IFERROR` 防零。
- **排序 / 筛选混合文本列**：带货币符 / 单位 / 表达式的文本列直接排序 / 筛选会按字典序出错，先抽数值到辅助列再处理（细则见 `lark-sheets-range-operations` / `lark-sheets-filter`）。
- **隐藏行列**：`+csv-get` 默认 `--skip-hidden=false`（含隐藏行列）；设 `true` 只看可见数据，但返回行序号与实际行号不再对应。
- **行号一律取 `[row=N]` 前缀**：`+csv-get` 的 CSV 中双引号内换行是单元格内换行不是新行；禁止数 `\n`、禁止用"序号列"当行号（细则见 `lark-sheets-read-data`）。
- **列字母取 `col_indices[j]`**：禁止手数表头逗号定位列（>10 列极易 off-by-one）。
- **跨 sheet 对象**：图表 / 条件格式 / 透视表 / 浮动图片可能分布在多个子表，操作前先 `+workbook-info` 掌握全局。
- **`+cells-search` 不是万能**：用户说"汇总金额"是操作动作（求和），不是搜索该文本；只在确需定位某文本位置时才用。

## 特殊场景

### 续写 / 复制已有区块格式

核心要求见铁律 5。机制（带齐哪些样式字段、怎么采样写入）见 `lark-sheets-write-cells` 的「新增列 / 新增行的样式继承」；样式标准（斑马纹奇偶 / 配色 / 边框层级）见 `lark-sheets-visual-standards` 场景二。本文不再展开。

### NLP 任务处理

任务涉及语义理解、翻译、改写、摘要、分类、抽取、多行聚合时，以 NLP 方式处理，不要用纯规则代码替代语义理解（但可用代码做分批、行号映射、结果拼装与写回）。数据量大时**必须**分批（通常 30 行一批），每批处理完立即写回，不要全处理完再一次写入；单批生成通常不超 300 行，超出时按性质抽样或分批并向用户说明范围；多批写入优先用 `+batch-update` 合并为原子提交。

### 格式处理优先公式

"去除多余零 / 提取数字 / 文本格式转换 / 日期格式化"等清洗，**必须优先用公式**（`SUBSTITUTE` / `TEXT` / `VALUE` / `LEFT` / `RIGHT` / `MID` 等）：写一个模板 + `--copy-to-range` 即可整列处理，远比逐行修改高效。
