diff --git a/shortcuts/sheets/data/flag-defs.json b/shortcuts/sheets/data/flag-defs.json index ec032f10e..4579f1f91 100644 --- a/shortcuts/sheets/data/flag-defs.json +++ b/shortcuts/sheets/data/flag-defs.json @@ -1,37 +1,4 @@ { - "+recover": { - "risk": "write", - "flags": [ - { - "name": "url", - "kind": "public", - "type": "string", - "required": "xor", - "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)" - }, - { - "name": "spreadsheet-token", - "kind": "public", - "type": "string", - "required": "xor", - "desc": "Spreadsheet token (XOR with `--url`)" - }, - { - "name": "to-revision", - "kind": "own", - "type": "int", - "required": "required", - "desc": "Restore the whole spreadsheet to this revision (a revision number returned by a prior write)" - }, - { - "name": "dry-run", - "kind": "system", - "type": "bool", - "required": "optional", - "desc": "" - } - ] - }, "+workbook-info": { "risk": "read", "flags": [ @@ -87,7 +54,7 @@ "kind": "own", "type": "int", "required": "optional", - "desc": "Insert position; appended to the end when omitted", + "desc": "Insert position (0-based); appended to the end when omitted", "default": "-1" }, { @@ -543,23 +510,12 @@ "required": "optional", "desc": "Target folder token; placed at the drive root when omitted" }, - { - "name": "headers", - "kind": "own", - "type": "string", - "required": "optional", - "desc": "Header row as a JSON array: `[\"Col A\",\"Col B\"]`", - "input": [ - "file", - "stdin" - ] - }, { "name": "values", "kind": "own", "type": "string", "required": "optional", - "desc": "Initial data as a 2D JSON array: `[[\"alice\",95]]`", + "desc": "Untyped initial data as one 2D JSON array (`[[\"alice\",95]]`); values are written as-is with their type auto-detected, through the same batched set_cell_range path as --sheets — pair with --styles for number formats, colors, merges, and row/col sizes", "input": [ "file", "stdin" @@ -570,19 +526,22 @@ "kind": "own", "type": "string", "required": "optional", - "desc": "Typed table payload as JSON (same shape as `+table-put`): a top-level `sheets` array, each item `{name, start_cell?, mode?, header?, allow_overwrite?, columns:[{name,type,format?}], rows:[[...]]}`; column `type` is one of string/number/date/bool. Mutually exclusive with --headers/--values. Creates the workbook, then writes typed type-faithful data (dates land as real dates, numbers keep precision).", + "desc": "Typed table payload as JSON (same shape as `+table-put`): a top-level `sheets` array, each item `{name, start_cell?, mode?, header?, allow_overwrite?, columns:[{name,type,format?}], rows:[[...]]}`; column `type` is one of string/number/date/bool. Mutually exclusive with --values. Creates the workbook, then writes typed type-faithful data (dates land as real dates, numbers keep precision).", "input": [ "file", "stdin" ] }, { - "name": "header-style", + "name": "styles", "kind": "own", - "type": "bool", + "type": "string", "required": "optional", - "desc": "Bold the typed header row (only with --sheets; default true)", - "default": "true" + "desc": "Initial visual operations as JSON: top-level `{styles:[...]}`. Each item corresponds to one target sheet and must include `name`, plus at least one of `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges`. `cell_styles` entries use +cells-set-style fields with a cell range; row/col sizes use dimension ranges plus type/size; merges use cell ranges plus optional merge_type. With --sheets, styles array length/order/name must match --sheets.sheets. With --values, pass exactly one styles item for the initial sheet (its name is ignored).", + "input": [ + "file", + "stdin" + ] }, { "name": "dry-run", @@ -2053,7 +2012,7 @@ "kind": "own", "type": "string", "required": "required", - "desc": "RFC 4180 CSV text; plain values only (no formulas / styles / comments)", + "desc": "RFC 4180 CSV text; values or formulas (a leading = is evaluated as a formula); no styles / comments / images (use +cells-set for those).", "input": [ "file", "stdin" @@ -2112,14 +2071,6 @@ "stdin" ] }, - { - "name": "header-style", - "kind": "own", - "type": "bool", - "required": "optional", - "desc": "Bold the header row written from column names (default true)", - "default": "true" - }, { "name": "dry-run", "kind": "system", @@ -4787,5 +4738,38 @@ "desc": "" } ] + }, + "+recover": { + "risk": "write", + "flags": [ + { + "name": "url", + "kind": "public", + "type": "string", + "required": "xor", + "desc": "Spreadsheet URL (XOR with `--spreadsheet-token`)" + }, + { + "name": "spreadsheet-token", + "kind": "public", + "type": "string", + "required": "xor", + "desc": "Spreadsheet token (XOR with `--url`)" + }, + { + "name": "to-revision", + "kind": "own", + "type": "int", + "required": "required", + "desc": "Restore the whole spreadsheet to this revision (a revision number returned by a prior write)" + }, + { + "name": "dry-run", + "kind": "system", + "type": "bool", + "required": "optional", + "desc": "" + } + ] } } diff --git a/shortcuts/sheets/data/flag-schemas.json b/shortcuts/sheets/data/flag-schemas.json index 53b35eb4a..c5f74def3 100644 --- a/shortcuts/sheets/data/flag-schemas.json +++ b/shortcuts/sheets/data/flag-schemas.json @@ -1730,11 +1730,12 @@ }, "aggregateType": { "type": "string", - "description": "汇总方式,默认为'sum',仅在 aggregate 为 true 时生效", + "description": "汇总方式,默认为'sum',仅在 aggregate 为 true 时生效。count 只统计数值单元格;counta 统计所有非空单元格(含文本),按文本/分类列统计出现次数(如各类别的数量、频次分布)时用 counta。", "enum": [ "sum", "average", "count", + "counta", "min", "max", "median" @@ -2765,11 +2766,12 @@ }, "aggregateType": { "type": "string", - "description": "汇总方式,默认为'sum',仅在 aggregate 为 true 时生效", + "description": "汇总方式,默认为'sum',仅在 aggregate 为 true 时生效。count 只统计数值单元格;counta 统计所有非空单元格(含文本),按文本/分类列统计出现次数(如各类别的数量、频次分布)时用 counta。", "enum": [ "sum", "average", "count", + "counta", "min", "max", "median" @@ -6424,6 +6426,293 @@ } } } + }, + "styles": { + "items": { + "properties": { + "cell_merges": { + "description": "单元格合并操作数组;range 使用 A1 单元格范围,merge_type 默认 all。", + "items": { + "properties": { + "merge_type": { + "enum": [ + "all", + "rows", + "columns" + ], + "type": "string" + }, + "range": { + "type": "string" + } + }, + "required": [ + "range" + ], + "type": "object" + }, + "type": "array" + }, + "cell_styles": { + "description": "单元格样式操作数组;每项用 A1 单元格 range 指定范围,字段名与 +cells-set-style 对齐。", + "items": { + "properties": { + "background_color": { + "type": "string" + }, + "border_styles": { + "type": "object", + "description": "边框配置,结构同 +cells-set-style --border-styles。", + "properties": { + "bottom": { + "properties": { + "color": { + "description": "边框颜色(十六进制,例如 \"#000000\")", + "type": "string" + }, + "style": { + "description": "边框线型;传 \"none\" 表示清除该方向边框(无边框线)", + "enum": [ + "solid", + "dashed", + "dotted", + "double", + "none" + ], + "type": "string" + }, + "weight": { + "description": "边框粗细/线宽", + "enum": [ + "thin", + "medium", + "thick" + ], + "type": "string" + } + }, + "type": "object" + }, + "left": { + "properties": { + "color": { + "description": "边框颜色(十六进制,例如 \"#000000\")", + "type": "string" + }, + "style": { + "description": "边框线型;传 \"none\" 表示清除该方向边框(无边框线)", + "enum": [ + "solid", + "dashed", + "dotted", + "double", + "none" + ], + "type": "string" + }, + "weight": { + "description": "边框粗细/线宽", + "enum": [ + "thin", + "medium", + "thick" + ], + "type": "string" + } + }, + "type": "object" + }, + "right": { + "properties": { + "color": { + "description": "边框颜色(十六进制,例如 \"#000000\")", + "type": "string" + }, + "style": { + "description": "边框线型;传 \"none\" 表示清除该方向边框(无边框线)", + "enum": [ + "solid", + "dashed", + "dotted", + "double", + "none" + ], + "type": "string" + }, + "weight": { + "description": "边框粗细/线宽", + "enum": [ + "thin", + "medium", + "thick" + ], + "type": "string" + } + }, + "type": "object" + }, + "top": { + "properties": { + "color": { + "description": "边框颜色(十六进制,例如 \"#000000\")", + "type": "string" + }, + "style": { + "description": "边框线型;传 \"none\" 表示清除该方向边框(无边框线)", + "enum": [ + "solid", + "dashed", + "dotted", + "double", + "none" + ], + "type": "string" + }, + "weight": { + "description": "边框粗细/线宽", + "enum": [ + "thin", + "medium", + "thick" + ], + "type": "string" + } + }, + "type": "object" + } + } + }, + "font_color": { + "type": "string" + }, + "font_line": { + "enum": [ + "none", + "underline", + "line-through" + ], + "type": "string" + }, + "font_size": { + "type": "number" + }, + "font_style": { + "enum": [ + "normal", + "italic" + ], + "type": "string" + }, + "font_weight": { + "enum": [ + "normal", + "bold" + ], + "type": "string" + }, + "horizontal_alignment": { + "enum": [ + "left", + "center", + "right" + ], + "type": "string" + }, + "number_format": { + "type": "string" + }, + "range": { + "description": "A1 单元格范围,必须落在该子表本次写入区域内;例如 A1:B1、B2。", + "type": "string" + }, + "vertical_alignment": { + "enum": [ + "top", + "middle", + "bottom" + ], + "type": "string" + }, + "word_wrap": { + "enum": [ + "overflow", + "auto-wrap", + "word-clip" + ], + "type": "string" + } + }, + "required": [ + "range" + ], + "type": "object" + }, + "type": "array" + }, + "col_sizes": { + "description": "列宽操作数组;range 使用列范围如 A:C,type 为 pixel/standard,pixel 需要 size。", + "items": { + "properties": { + "range": { + "type": "string" + }, + "size": { + "type": "number" + }, + "type": { + "enum": [ + "pixel", + "standard" + ], + "type": "string" + } + }, + "required": [ + "range", + "type" + ], + "type": "object" + }, + "type": "array" + }, + "name": { + "description": "子表名。--sheets 模式下必须与同位置 --sheets.sheets[].name 一致;--values 模式下建议写 Sheet1(其 name 会被忽略)。", + "type": "string" + }, + "row_sizes": { + "description": "行高操作数组;range 使用行范围如 1:3,type 为 pixel/standard/auto,pixel 需要 size。", + "items": { + "properties": { + "range": { + "type": "string" + }, + "size": { + "type": "number" + }, + "type": { + "enum": [ + "pixel", + "standard", + "auto" + ], + "type": "string" + } + }, + "required": [ + "range", + "type" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" } } } diff --git a/skills/lark-sheets/SKILL.md b/skills/lark-sheets/SKILL.md index 553335321..412df4190 100644 --- a/skills/lark-sheets/SKILL.md +++ b/skills/lark-sheets/SKILL.md @@ -42,7 +42,7 @@ metadata: | 读值 + 公式 / 样式 / 批注 | `+cells-get --include value,formula,style,comment,data_validation` | `--with-styles`、`--with-merges`、`--include-merged-cells` | | 写纯文本值(整块 CSV 平铺,列里没有需保留的数值 / 日期语义) | `+csv-put`(定位用 `--start-cell`,单个左上角锚点格;也接受 `--range` 别名,区间自动取左上角) | — | | 写带类型的数据到**已有**表(列里有数字 / 金额 / 百分比 / 日期 / 计数,要可排序 / 求和 / 入图表 / 透视) | `+table-put`(列显式声明 `type` + `format`,类型保真;来源不限 DataFrame——Counter / dict / list 同理,详见 write-cells) | 在本地把数字拼成 `"$1,234"` / `"30.5%"` 字符串再 `+csv-put`(会落成文本、丢失计算能力) | -| **新建**电子表格并写带类型的数据(类型保真需求同上,但目标表还不存在) | `+workbook-create --sheets`(协议与 `+table-put` 同构、一步建表 + typed 写入,无需先建空表再 `+table-put`;date / number 不丢,详见 workbook) | 用 `--headers` / `--values` 灌日期 / 数字(会落成文本、丢类型) | +| **新建**电子表格并写带类型的数据(类型保真需求同上,但目标表还不存在) | `+workbook-create --sheets`(协议与 `+table-put` 同构、一步建表 + typed 写入,无需先建空表再 `+table-put`;date / number 不丢,详见 workbook) | 用 `--values` 灌日期 / 数字(会落成文本、丢类型) | | 写值 / 公式 / 样式 | `+cells-set`(定位用 `--range`) | — | | 查找单元格 | `+cells-search`(关键字用 `--find`) | `+cells-find`、`+find`、`--query` | | 查找并替换 | `+cells-replace` | — | @@ -90,6 +90,7 @@ metadata: | [Lark Sheet Filter View](references/lark-sheets-filter-view.md) | 管理飞书表格中的筛选视图(filter view)。当用户需要"建一个 XX 视图"、"保存这个筛选状态"、"切换不同筛选"、维护一个 sheet 上多份独立筛选配置时使用。视图与筛选器(filter)相互独立,可在同一 sheet 共存;视图的隐藏行仅在用户进入该视图时本地生效,不影响其他协作者。 | | [Lark Sheet Sparkline](references/lark-sheets-sparkline.md) | 管理飞书表格中的迷你图(折线迷你图、柱形迷你图、胜负迷你图)。当用户需要在单元格内嵌入小型图表来展示数据趋势时使用。也适用于"趋势线"、"单元格内图表"、"迷你图"等场景。注意:不等同于被禁用的 SPARKLINE() 公式函数。 | | [Lark Sheet Float Image](references/lark-sheets-float-image.md) | 管理飞书表格中的浮动图片。当用户需要在表格中插入浮动图片、调整图片位置和大小、查看已有浮动图片、删除图片时使用。也适用于"插入图片"、"添加 logo"、"放一张图"等场景。注意:如果用户需要将图片嵌入到某个单元格内部(单元格图片),请阅读 lark-sheets-write-cells。 | +| [Lark Sheet Recover](references/lark-sheets-recover.md) | 整表回退到历史版本(方案 B)。当用户提到"恢复到之前的版本"、"撤销所有改动回到某个状态"、"整表回滚"、"recover"时使用。这是全文档回退(丢弃目标版本之后的所有编辑,含他人改动)——要精确逐笔撤销本链路最近编辑,用 +undo。 | ## 公共 flag 速查 @@ -107,7 +108,7 @@ metadata: 1. **spreadsheet 定位(必填)**:`--url` 与 `--spreadsheet-token` 二选一,**必须给其中之一**。两个都不给 → 校验报错 `specify at least one of --url or --spreadsheet-token`;两个都给 → 互斥冲突。 - **`--url` 只解析 `/sheets/` 与 `/spreadsheets/` 两种链接**(从路径里抽出 token;也可以直接把裸 token 传给 `--spreadsheet-token`)。其它形态的链接不会被解析成表格 token。 - ⚠️ **`/wiki/` 知识库链接不能直接当表格定位用**:wiki 链接背后可能是电子表格,也可能是文档 / 多维表格等其它类型,`--url` **不会**自动把 wiki token 解析成 spreadsheet token,直接传会失败。必须先把它解析成真实文档 token —— `lark-cli wiki +node-get --node-token ""`,确认返回的 `obj_type` 为 `sheet` 后,取其 `obj_token` 作为 `--spreadsheet-token` 传入(解析细节见 [`../lark-wiki/SKILL.md`](../lark-wiki/SKILL.md))。 - - **例外**:`+workbook-create`(新建表 + 可选写入数据)与 `+workbook-import`(把本地文件导入为新表)都产出一张**还不存在**的表格,**不接受任何 spreadsheet / sheet 定位 flag**——`+workbook-create` 只有 `--title` / `--folder-token` / `--headers` / `--values` / `--sheets`,`+workbook-import` 只有 `--file`(必填)/ `--folder-token` / `--name`。 + - **例外**:`+workbook-create`(新建表 + 可选写入数据)与 `+workbook-import`(把本地文件导入为新表)都产出一张**还不存在**的表格,**不接受任何 spreadsheet / sheet 定位 flag**——`+workbook-create` 只有 `--title` / `--folder-token` / `--values` / `--styles` / `--sheets`,`+workbook-import` 只有 `--file`(必填)/ `--folder-token` / `--name`。 2. **sheet 定位(公共四件套 shortcut 必填)**:`--sheet-id` 与 `--sheet-name` 二选一,**必须给其中之一**。两个都不给 → 校验报错 `specify at least one of --sheet-id or --sheet-name`。 - ⚠️ **不确定 sheet 名时禁止直接猜 `Sheet1`**:除非用户对话明确说出 sheet 名 / id,或上下文(之前的工具调用 / URL 锚点 `?sheet=xxx`)已经出现过具体值,否则**第一步先调 `+workbook-info --url "..."`**(或 `--spreadsheet-token`)拿 `sheets[].sheet_id` / `sheets[].title` 列表再选。中文环境下子表常叫"数据" / "Sheet"(无数字)/ "工作表 1" / 业务名,猜 `Sheet1` 大概率撞 `sheet not found`,比先查多耗一次失败调用 + 重试。 - ⚠️ **`--range` 里的 `Sheet1!` 前缀不能替代 sheet 定位**:即使写了 `--range 'Sheet1!A1:B2'`,仍**必须**额外传 `--sheet-id` 或 `--sheet-name`,否则照样报上面的错。 diff --git a/skills/lark-sheets/references/lark-sheets-recover.md b/skills/lark-sheets/references/lark-sheets-recover.md new file mode 100644 index 000000000..69fe974c4 --- /dev/null +++ b/skills/lark-sheets/references/lark-sheets-recover.md @@ -0,0 +1,41 @@ +# Lark Sheet Recover + +## 使用场景 + +写。整表回退到指定历史 revision(方案 B)。本 reference 覆盖 1 个 shortcut: + +| 操作需求 | 使用工具 | 说明 | +|---------|---------|------| +| 整表回退到历史版本 | `+recover` | 把整个 spreadsheet 回退到 `--to-revision` 指定的版本,丢弃其后所有编辑 | + +⚠️ **全文档破坏性回退**:`+recover` 丢弃 `--to-revision` 之后的**所有**编辑,包括其他协作者的改动。只在 agent 自己的草稿表、或确认要整表回滚时使用。要精确撤销本链路最近几笔编辑,请用 `+undo`(逐笔、可控、不波及他人)。 + +## Shortcuts + +| Shortcut | Risk | 分组 | +| --- | --- | --- | +| `+recover` | write | 撤销恢复 | + +## Flags + +### `+recover` + +_公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_ + +| Flag | Type | 必填 | 说明 | +| --- | --- | --- | --- | +| `--to-revision` | int | required | 整表回退到该 revision(来自此前写操作返回的 revision) | + +## Examples + +### `+recover` + +把整表回退到某个历史版本。`--to-revision` 取此前某次写操作响应里返回的 `revision`。 + +```bash +lark-cli sheets +recover --spreadsheet-token --to-revision 42 +``` + +- 回退会产生一个**新** revision(不是删历史,而是追加一条回退记录),响应里返回这个新 revision。 +- 回退不可逆地丢弃 `--to-revision` 之后的内容,执行前先确认要丢弃的范围。 +- 与 `+undo` 的区别:`+undo` 精确撤销本 CLI 链路最近 N 笔编辑、不动他人改动;`+recover` 是全文档回到某版本、丢弃所有后续(含他人)。需要细粒度撤销时优先 `+undo`。 diff --git a/skills/lark-sheets/references/lark-sheets-workbook.md b/skills/lark-sheets/references/lark-sheets-workbook.md index f8201cf96..c7ac73351 100644 --- a/skills/lark-sheets/references/lark-sheets-workbook.md +++ b/skills/lark-sheets/references/lark-sheets-workbook.md @@ -138,10 +138,9 @@ _系统:`--dry-run`_ | --- | --- | --- | --- | | `--title` | string | required | 新 spreadsheet 标题 | | `--folder-token` | string | optional | 目标文件夹 token;省略时放在云空间根目录 | -| `--headers` | string + File + Stdin(简单 JSON) | optional | 表头行 JSON 数组:`["列A","列B"]` | -| `--values` | string + File + Stdin(简单 JSON) | optional | 初始数据 JSON 二维数组:`[["alice",95]]` | -| `--sheets` | string + File + Stdin(复合 JSON) | optional | 建表后写入的 typed 表格协议 JSON(同 +table-put):顶层 sheets 数组,每项 {name, start_cell?, mode?, header?, allow_overwrite?, columns:[{name,type,format?}], rows:[[...]]};type 为 string/number/date/bool。与 --headers/--values 互斥;新表默认子表复用为第一个子表,日期/数字类型保真。 | -| `--header-style` | bool | optional | 把 typed 表头行加粗(仅 --sheets 时生效,默认 true) | +| `--values` | string + File + Stdin(简单 JSON) | optional | untyped 初始数据,一个 JSON 二维数组(表头并入第一行):`[["列A","列B"],["alice",95]]`;值原样写入、类型由飞书自动识别,走与 --sheets 相同的分批 `+cells-set`;配 --styles 控制格式/颜色/合并/行列尺寸 | +| `--sheets` | string + File + Stdin(复合 JSON) | optional | 建表后写入的 typed 表格协议 JSON(同 +table-put):顶层 sheets 数组,每项 {name, start_cell?, mode?, header?, allow_overwrite?, columns:[{name,type,format?}], rows:[[...]]};type 为 string/number/date/bool。与 --values 互斥;新表默认子表复用为第一个子表,日期/数字类型保真。 | +| `--styles` | string + File + Stdin(复合 JSON) | optional | 建表时同时写入的视觉处理操作 JSON:顶层 `{styles:[...]}`,每项对应一个目标子表、含 `name`,并至少给 `cell_styles` / `row_sizes` / `col_sizes` / `cell_merges` 之一。`cell_styles` 用 A1 单元格 range + 扁平样式字段(字段同 +cells-set-style,含 number_format / 颜色 / 对齐 / border_styles);row/col sizes 用行/列范围 + type/size;merges 用单元格 range + 可选 merge_type。与 --sheets 搭配时 styles 数组长度/顺序/name 必须与 --sheets.sheets 对应;与 --values 搭配时只给一个 styles 项(其 name 忽略)。 | ### `+workbook-export` @@ -178,6 +177,16 @@ _一个或多个子表的 typed 数据,每个数组元素写入一张子表; - `columns` (array) — 列定义,顺序与 rows 中每行的取值一一对应 each: { name: string, type: enum, format?: string } - `rows` (array>) — 数据行;每行是一个数组,长度必须等于 columns 数 +### `+workbook-create` `--styles` + + +**数组项**(类型 object): +- `cell_merges` (array?) — 单元格合并操作数组;range 使用 A1 单元格范围,merge_type 默认 all each: { merge_type?: enum, range: string } +- `cell_styles` (array?) — 单元格样式操作数组;每项用 A1 单元格 range 指定范围,字段名与 +cells-set-style 对齐 each: { background_color?: string, border_styles?: object, font_color?: string, font_line?: enum, font_size?: number, …共 12 项 } +- `col_sizes` (array?) — 列宽操作数组;range 使用列范围如 A:C,type 为 pixel/standard,pixel 需要 size each: { range: string, size?: number, type: enum } +- `name` (string) — 子表名 +- `row_sizes` (array?) — 行高操作数组;range 使用行范围如 1:3,type 为 pixel/standard/auto,pixel 需要 size each: { range: string, size?: number, type: enum } + ## Examples 公共四件套:所有 shortcut 顶部排列 `--url` / `--spreadsheet-token` / `--sheet-id` / `--sheet-name`(XOR)。`+workbook-info` 只用前两者;`+sheet-*` 系列对单个工作表操作,需 `--sheet-id` 或 `--sheet-name`。 @@ -188,12 +197,13 @@ _一个或多个子表的 typed 数据,每个数组元素写入一张子表; ### `+workbook-create` -新建电子表格,可选预填数据。两种数据入口**互斥**,按需二选一: +新建电子表格,可选预填数据。两种数据入口(untyped `--values` / typed `--sheets`)**互斥**,按需二选一——两者都走同一条分批 `set_cell_range` 写入: ```bash -# 1) untyped:--headers + --values(纯值;类型由飞书自动识别,日期会落成文本) +# 1) untyped:--values(一个二维数组,表头并入第一行;值原样写、类型由飞书自动识别, +# 日期会落成文本,配 --styles 控制格式) lark-cli sheets +workbook-create --title "销售" \ - --headers '["门店","销售额"]' --values '[["北京",259874]]' + --values '[["门店","销售额"],["北京",259874]]' # 2) typed:--sheets(一步建表 + 类型保真)。date 列落成真日期(可排序/透视)、 # number 不丢精度、string 列保前导零(如订单号 00123);多子表一次建。 @@ -209,6 +219,69 @@ lark-cli sheets +workbook-create --title "交易" --sheets '{ `--sheets` 协议与 `+table-put` 完全同构(字段含义见 lark-sheets-write-cells 的 `+table-put`,大 payload 走 stdin / `@file`)。关键差异:**新建工作簿的默认子表会被复用为第一个子表**(重命名后承载数据),不会残留空 `Sheet1`;其余子表按需新建。它把 `+table-put` 单独做不到的"建表 + typed 写入"合到一条命令,是「pandas 算完直接落地一张带真日期的新表」的首选。回读校验用 `+table-get`(与 `--sheets` 同构、可 round-trip)。 +`--styles` 可在建表写入时同时写视觉处理。它和 `--sheets` 一样只有一种外层写法:顶层对象里放 `styles` 数组;数组每项对应一个子表,含 `name`,并按能力拆成四类可选数组: + +- `cell_styles`:像 `+cells-set-style`,用 A1 单元格 `range` 加扁平样式字段(`font_weight` / `background_color` / `number_format` 等)和可选 `border_styles`;这些样式会合并进同一次内容 `set_cell_range`。 +- `cell_merges`:用 A1 单元格 `range` 设置合并,`merge_type` 默认为 `all`,可选 `rows` / `columns`。 +- `row_sizes`:用行范围(如 `1:3`)设置行高,`type` 为 `pixel` / `standard` / `auto`;`pixel` 需要 `size`。 +- `col_sizes`:用列范围(如 `A:C`)设置列宽,`type` 为 `pixel` / `standard`;`pixel` 需要 `size`。 + +同一单元格命中多个 `cell_styles` 项时,后面的操作继续合并覆盖已传字段。`cell_merges` / `row_sizes` / `col_sizes` 在内容写入后顺序执行。 + +```bash +# 3) untyped:仍用 {"styles":[...]},只有一个子表样式项(name 忽略);range 覆盖 --values 初始区域 +lark-cli sheets +workbook-create --title "销售" \ + --values '[["门店","销售额"],["北京",259874],["上海",198320]]' \ + --styles '{ + "styles":[ + {"name":"Sheet1","cell_styles":[ + {"range":"A1:B1","font_weight":"bold","background_color":"#f5f5f5"}, + {"range":"B2:B3","number_format":"#,##0"} + ]} + ] + }' + +# 4) typed 单子表:--styles.styles[0].name 必须对应 --sheets.sheets[0].name +lark-cli sheets +workbook-create --title "交易" --sheets '{ + "sheets":[ + {"name":"明细","columns":[ + {"name":"日期","type":"date"}, + {"name":"金额","type":"number","format":"#,##0.00"} + ],"rows":[["2024-01-15",1234.5]]} + ]}' --styles '{ + "styles":[ + {"name":"明细", + "cell_styles":[ + {"range":"A1:B1","font_weight":"bold","background_color":"#f5f5f5", + "border_styles":{"bottom":{"style":"solid","weight":"thin","color":"#000000"}}}, + {"range":"A2:A2","number_format":"yyyy-mm-dd"}, + {"range":"B2:B2","number_format":"#,##0.00","font_color":"#0f7b0f"} + ], + "cell_merges":[{"range":"A1:B1"}], + "col_sizes":[{"range":"A:B","type":"pixel","size":120}], + "row_sizes":[{"range":"1:1","type":"pixel","size":28}]} + ] + }' + +# 5) typed 多子表:styles 数组和 sheets 数组长度、顺序、name 都必须一致 +lark-cli sheets +workbook-create --title "经营看板" --sheets '{ + "sheets":[ + {"name":"收入","columns":[{"name":"月份","type":"string"},{"name":"收入","type":"number","format":"#,##0"}],"rows":[["2026-05",1200000]]}, + {"name":"成本","columns":[{"name":"月份","type":"string"},{"name":"成本","type":"number","format":"#,##0"}],"rows":[["2026-05",730000]]} + ]}' --styles '{ + "styles":[ + {"name":"收入","cell_styles":[ + {"range":"A1:B1","font_weight":"bold","background_color":"#f0f7ff"}, + {"range":"B2:B2","font_color":"#0f7b0f"} + ]}, + {"name":"成本","cell_styles":[ + {"range":"A1:B1","font_weight":"bold","background_color":"#fff7ed"}, + {"range":"B2:B2","font_color":"#b42318"} + ]} + ] + }' +``` + > ⚠️ **`+workbook-create` 是把内存里的数据写成新表;要把已有的本地 Excel/CSV 文件原样导入成新表,用 `+workbook-import`**(见下),不要先在本地读出文件再 `+workbook-create` 重灌。 ### `+workbook-import` @@ -283,6 +356,6 @@ lark-cli sheets +sheet-hide-gridline --url "..." --sheet-id "$SID" ### Validate / DryRun / Execute 约束 -- `Validate`:XOR 公共四件套;`+sheet-create` 校验 `--title` 非空、`--row-count` ≤ 50000、`--col-count` ≤ 200;`+sheet-delete` 必须 `--yes` 或 `--dry-run`;`+workbook-create` 的 `--sheets` 与 `--headers`/`--values` **互斥**,给了 `--sheets` 则按 typed 协议校验 payload(其余约束同 `+table-put`)。 +- `Validate`:XOR 公共四件套;`+sheet-create` 校验 `--title` 非空、`--row-count` ≤ 50000、`--col-count` ≤ 200;`+sheet-delete` 必须 `--yes` 或 `--dry-run`;`+workbook-create` 的 `--sheets` 与 `--values` **互斥**,给了 `--sheets` 则按 typed 协议校验 payload(其余约束同 `+table-put`)。 - `DryRun`:`+sheet-*` 写操作输出"将要 PATCH 的 sheet metadata";`--sheet-name` 在 dry-run 输出里生成为 `` 占位符,不实际解析为 sheet-id。 - `Execute`:写操作不自动回读;如需确认目标 sheet 的新状态,自行调用 `+workbook-info`。 diff --git a/skills/lark-sheets/references/lark-sheets-write-cells.md b/skills/lark-sheets/references/lark-sheets-write-cells.md index 36859ed29..349c6d868 100644 --- a/skills/lark-sheets/references/lark-sheets-write-cells.md +++ b/skills/lark-sheets/references/lark-sheets-write-cells.md @@ -318,7 +318,6 @@ _公共:URL/token(无 sheet 定位) · 系统:`--dry-run`_ | Flag | Type | 必填 | 说明 | | --- | --- | --- | --- | | `--sheets` | string + File + Stdin(复合 JSON) | required | typed 表格协议 JSON:顶层 sheets 数组,每项 {name, start_cell?, mode?, header?, allow_overwrite?, columns:[{name,type,format?}], rows:[[...]]};type 为 string/number/date/bool | -| `--header-style` | bool | optional | 把列名表头行加粗(默认 true) | ## Schemas