Files
Starlight_Lancher/.agents/skills/lark-sheets/references/lark-sheets-write-cells.md

55 KiB
Raw Blame History

Lark Sheet Write Cells

写入边界 + 回读校验(编辑类任务必做)

  1. 明确写入边界:写入前必须能回答"目标 range 的起止行列号是多少?是否落在用户授权范围内?"。除用户明示要修改的区域外,禁止扩张到原数据列以外或新建 Sheet。
  2. 完整性断言:批量写入前先把"预期写入条数"硬编码到代码里(如要填 106 条翻译 → expected = 106),写完后回读断言 actual == expected。少于预期就继续写,禁止交付半成品。
  3. 回读抽样校验:写完关键值 / 公式后,用 +csv-get+cells-get 重新读取写入区域,至少抽样 3-5 个代表性单元格(首 / 中 / 末),核对值与预期一致(与本地脚本计算的预期值对照)。公式特定的"先验证模板再 --copy-to-range / 修完再读回"细则见下方相关章节。
  4. 护原表 · 派生产物落点(写排名 / 标记 / 汇总 / 改写列时易丢数据):派生结果一律写到真实末列 +1 的全新空列或新建子表,禁止复用任何已有原数据列——哪怕该列看起来"空",也要先 +csv-get 回读确认整列无原始数据再写。三条准则:① 不把新公式 / 新值写进原数据列(典型反例:把新算的排名公式写进了原本存放另一份原始数据的列,整列原始数据被覆盖丢失);② 不改写、不合并原表头字段名(典型反例:把几个独立表头字段合并成一列,原字段名丢失);③ 慎用 --allow-overwrite:它一旦让写入区盖到相邻原始列 / 行就是不可逆数据丢失,加它之前必须用 +sheet-info / +csv-get 核清目标 range 不含任何原始数据。

新增列 / 新增行的样式继承(防止视觉风格不一致)

新增列 / 新增行必须先用 +cells-get 读相邻原列 / 原行的完整样式作为模板,禁止只传 value 期望默认样式与原表一致——飞书新单元格默认对齐通常是 H:right, V:bottom,与多数原表的 H:center, V:middle 不一致。

完整继承清单(写新列 / 新行时 cells 数组必须同时携带):

  1. cell_styles.font_family / cell_styles.font_size / cell_styles.font_weight / cell_styles.font_color / cell_styles.font_style(字体名称 / 字号 / 粗细 / 颜色 / 斜体等)
  2. cell_styles.horizontal_alignment / cell_styles.vertical_alignmentH-Align / V-Align—— 漏继承会导致新列对齐与原列不一致(常见)
  3. cell_styles.number_format(小数位 / 千分位 / 百分比 / 日期格式)—— 漏继承会导致同列数值格式混乱
  4. cell_styles.background_color(背景色)
  5. border_styles(四边框)
  6. merged_cells(合并范围)——续写场景必查:用 +sheet-info --include merges 读原数据区域的合并信息。原行有跨列合并(如标题行 A1:G1 合并)时,新行必须+cells-{merge|unmerge} 工具复制相同合并模式到新行(如续写第 3 个周报块的标题行 A23:G23 必须合并)。仅传 cells 数组的 5 类样式不够——合并范围要单独靠 +cells-{merge|unmerge} 工具落地(典型反例:续写多周记录表时,新增周次的标题行未合并,视觉上与原前几周风格不一致)

采样模板的正确做法

  • 表头新列 → 读相邻表头单元格(如新加 D1 → 读 A1/B1/C1 任一)
  • 数据新列 → 读相邻数据行单元格(如新加 M5:M100 → 读 L5 / L6 / L7
  • 续写新行 → 读最近一行已有数据(如续写第 20 行 → 读 19 行所有列)

反模式(违规):

  • 只传 {"value": "四级菜单"} 给 D1不传 cell_styles → D1 默认非加粗、非居中,与 A1/B1/C1 风格断裂
  • 新列 M5 写入 =SUM(F5:L5) 时只传 formula,不传 cell_styles.horizontal_alignment / vertical_alignment / number_format → M 列对齐变 H:right,数字格式变默认

长数字防科学计数法(数值列写入必查)

写入或计算结果可能产生长数字(≥ 12 位整数 / 高精度小数)的列,必须cell_styles.number_format 显式设置非通用格式,否则飞书会自动用科学计数法显示,用户看到的就是"内容被截断 / 看不清原值"。

场景 必加的 number_format
长整数(订单号 / 身份证 / 单据号) "0""@"(强制文本,避免精度丢失)
金额 / 千分位 "#,##0.00"
百分比 "0.00%"
数量 / 计数 "0"(整数)
日期 "yyyy-mm-dd""yyyy/m/d"

典型反例:长数字列(如审批单号、流水号)未设 number_format,飞书显示为 1.23E+15,用户复制出来已经丢失精度。

数字还是文本,按"数据本质是量值还是标识符"二选一 —— 不看当下要不要计算:金额 / 百分比 / 比率 / 计数 / 度量这类本质是量值的数据,一律以数字类型写入(百分比存小数 0.54number_format:"0%"不要@ 文本格式。这与"用户当下是否要排序 / 求和"无关——数据类型由数据本质决定、不由当下用途决定:表格数据几乎总会被后续排序 / 图表 / 二次计算复用,"54%" 文本与数值列混排本就破坏一致性,且数字 + number_format 显示效果与文本完全相同,没有任何理由选文本。最常见的误判就是"这只是 leaderboard / 报表 / 看板展示,又不用算,写成 54% 字符串就行"——这是错的,展示用途不改变"百分比是数值"的事实。+table-putdtypes 声明 int64 / float64;版式 +table-put 装不下时用 +cells-set 传数字 + number_format;都别在本地拼成带 $ / % 的字符串走 +csv-put。)反过来,编号 001、规格 3-1、身份证 / 电话 / 单据号等本质是标识符 / 标签、要原样保留不被飞书自动解释的内容(否则 00113-1→日期、点分日期 12.1012.1(尾零丢失)、长号→科学计数),才以字符串类型写入(dtypesobject)并把 number_format 设为 "@"(文本格式),字面保真。

使用场景

写入。向飞书表格的单元格区域写入值、公式、样式、批注、图片或下拉,也可批量写入 CSV / DataFrame。本 reference 覆盖 6 个 shortcut按数据来源 + 内容形态选:

场景 用这个 shortcut 原因
模型手里已经有 CSV 文本(小规模手动构造、从 +csv-get 取到后简单加工) +csv-put 直接传 CSV 文本 + --start-cell,不用自己拼二维 cells 数组;必要时自动扩容行列
列里有数值语义的数据(数字 / 金额 / 百分比 / 日期 / 计数)→ 飞书要类型保真来源不限DataFrame、Counter、dict、list 都算) +table-put typed 协议(外层 {"sheets":[{"name":"…","columns":[...],"data":[[...]],"dtypes":{...},"formats":{...}}]}只有这四件套字段dtypes 用 pandas dtype 串声明列类型(int64 / float64 / datetime64[ns] / bool / objectformats 给每列展示格式(千分位 / 百分比 / 日期)。date 落真日期、金额 / 百分比 / 计数等数值列保精度且带 number_format(可排序 / 求和 / 入图表)、string 保前导零,多 sheet 一次写
写入含样式、批注、图片、数据校验等任意富写入 +cells-set 唯一支持完整富字段的 shortcut公式 +csv-put 也能写)
只改已有 cell 的样式,不动 value/formula +cells-set-style 拍平 10 个样式字段为独立 flag不触发不必要的值写入
单 cell 嵌入图片 +cells-set-image +cells-set 参数更简短
已有区域局部补表头样式/边框 先用 +csv-put 写值,再用 +cells-set-style 补样式 分工配合,入参最短
新建子表 / 整表成套美化(哪怕全是纯文本) +table-put --sheets … --styles … 一步带值 + 全套样式(区域底色 / 边框 / 列宽 / 行高 / 合并payload 里不存在的 sheet 名自动建子表) --styles 与列是否 typed 无关,纯文本同样适用;比「写值 + 多次刷样式」少好几次调用

选命令按内容形态分流(不设"默认首选":① 列有数值语义(金额 / 百分比 / 日期 / 计数)→ +table-putdtypes 声明类型 + formats 设展示格式),版式装不下时 → +cells-set 传数字 + number_format;② 要样式 / 批注 / 图片 / 富文本 → +cells-set;③ 全文本、无数值语义的内容平铺 → +csv-put(入参最短)。判据详见上方「数字还是文本」。

⚠️ +csv-put 可写值或公式:以 = 开头的单元格会被当作公式计算(读回时 formula 字段保留、value 为计算结果)。公式内部含逗号 / 引号 / 换行时必须按 RFC 4180 转义——含逗号的字段整格用双引号包裹、字段内部的引号再翻倍:如 =COUNTIF(D5:D22,"及格") 必须写成 "=COUNTIF(D5:D22,""及格"")"(外层双引号包裹整格,内部 "及格" 的引号翻倍成 ""及格"")。漏转义会被 CSV 解析器按逗号拆列、整块写入区域错位(如本该 G4:H6 错成 G4:K4),详见下方 +csv-put 示例。因此含逗号 / 引号 / 换行的公式优先改用 +cells-setJSON 二维数组)写入——cells[r][c].formula 字段直接放公式串,零 CSV 转义负担,从根上避免拆列错位+table-put 的 typed 协议只接受 columns / data / dtypes / formats 四件套、没有 formula 字段,公式写入只能走 +cells-set / +csv-put)。此外 +csv-put 不会携带样式/批注/图片,也无法把 = 开头的内容当字面量文本写入;需要样式/批注/图片用 +cells-set(或"写值 + 补样式"两步法)。

⚠️ +csv-put 会把数值落成文本:把金额 / 百分比 / 计数等在本地拼成带 $ / % / 千分位的字符串(如 "$1,234.50" / "+30.5%")再 +csv-put 灌进去,单元格就是文本——丢失排序 / 求和 / 图表能力,且与数值列混排无法参与计算。数值该怎么写、何时 +table-put、版式装不下时何时退 +cells-set 传数字 + number_format,判据与分流见上方「数字还是文本」;核心一句:准备把数字 format 成字符串再写时就是走错了路,数值一律以数字写入 + number_format 控制显示。

⚠️ +csv-put 也会把「看着像数字」的字段静默数值化与上一条相反的另一半坑CSV 里语义是日期标签 / 编号 / 标识符、内容却全是数字字符的列,会被按数值解析——12.1012.1(点分日期尾零丢失)、3.030011、长号→科学计数。这类列即使已攒好 CSV 文本也不能裸走 +csv-put:优先 +table-put 把该列 dtypes 声明为 object(无年份的点分标签如 12.10 / 3-1 字面保真)或 datetime64[ns](完整真日期),版式装不下再退 +cells-set + number_format:"@"。此类失真在「抽样首 / 中 / 末」回读时易被掩盖(12.10 / 12.20 等尾零行常不落在抽样窗口),日期 / 编号列回读要专挑带尾零 / 前导零的代表值核对。

⚠️ 大数据回写走"+csv-get--range 行窗口分批读到本地 + 本地脚本处理 + +csv-put 分批回写"。

+cells-set 写入要点(常用模式 / 公式 / 样式)

以下是用 +cells-set(及 +cells-set-style)做富写入时的常用模式与准则;选哪个 shortcut 见上方「使用场景」。

+cells-set 为一块区域设置值 / 公式 / 批注 / 样式,也支持 rich_texttype: "embed-image" 嵌入单元格图片。关键:cells 二维数组的行列维度必须与 range(闭区间)严格一致,否则触发 InvalidCellRangeError——维度计算示例见文末 ## Schemas--cells

单元格图片 vs 浮动图片(最易选错):图若属于某条记录、要随那行排序 / 筛选 / 增删(凭证 / 证件照 / 每行配图,话里带「对应 / 每行 / 这列」等绑定词)→ 单元格图片(本工具):用 +cells-set-image(最短)或 +cells-setrich_text + type: "embed-image"。只是自由摆放的装饰logo / 水印 / 封面)→ 浮动图片,见 lark-sheets-float-image。别因「浮动图更好控制 / 更熟」默认选浮动图——它承载"对应某记录"的图会随增删行 / 排序错位。

常用模式(必须遵守,禁止逐行写入替代

  • 整列公式:先在 H2 写一个公式,再用 --copy-to-range "H2:H100"--copy-to-range "H:H" 向下填充。禁止对每一行单独调用 +cells-set 写入相同结构的公式
  • 整列格式:先在 J1 写一个带样式的模板单元格,再用 --copy-to-range "J:J"
  • 首行样式:先在 A1 写一个模板单元格,再用 --copy-to-range "1:1"
  • 用户说”这列 / 整列 / 这行 / 首行 / 向下复制”时,必须使用模板单元格 + --copy-to-range
  • 多区域写入相同格式/公式结构时,优先写一个模板,再用 --copy-to-range 复制到所有目标区域

⚠️ 模板 --range 从数据行起算、别把表头圈进去--copy-to-range 会把 --range 模板按目标区尺寸周期性平铺,模板里若含了表头行,表头会每隔几行重复铺进数据区。整列填充时模板只取一格数据样式(如 H2),不要取成 H1:H2

⚠️ 逐行写入公式是常见低效写法:对每一行单独调用 +cells-set 写公式(如 26 次)既慢又易错,且不会自动平移公式引用。正确做法是 1 次模板写入 + 1 次 --copy-to-range(公式引用自动平移)。

💡 写入公式前先按迁移规则改写:如果公式来自 Excel 或包含数组场景,先读取并遵循 lark-sheets-formula-translation 的规则完成改写,再把最终公式写入 formula 字段。

💡 内容与样式分离写入(推荐):当需要同时写入内容和样式时,cells 中每个单元格都带上 cell_styles / border_styles 会导致入参非常冗长。由于同一区域的样式通常高度重复(如整列统一背景色、统一边框),推荐拆成两步:

  1. 先写内容+cells-set 只传 value / formula,不带样式,cells 入参精简。⚠️ 这里"不带样式"指暂不带 cell_styles不是降级用 +csv-put 铺文本——数值列(百分比 / 金额 / 计数)仍必须以数字写入(百分比传 0.44):样式能后补,数据类型不能后补(见上方「数字还是文本」)。
  2. 再批量刷样式:对区域中的一个单元格写入目标样式作为模板,再用 --copy-to-range 将样式扩展到整列 / 整行 / 整个区域(--copy-to-range 会复制值、公式和样式,所以模板单元格应已包含正确的值)

示例:要对 A2:A100 写入数据并统一设置蓝色背景 + 边框:

Step 1: `+cells-set` — range="A2:A100", cells 只含 value无样式入参短
Step 2: `+cells-set` — range="A2", cells 含 value + cell_styles + border_styles单个模板, --copy-to-range="A2:A100"

这比在 99 个单元格中都重复写样式 JSON 高效得多。

💡 样式更新是「部分合并」,不是整体覆盖+cells-set-style / +cells-batch-set-style(以及 +cells-setcell_styles / border_styles)只改你显式传入的样式属性,未传的属性保留原值。两个实用推论:

  • 可分层叠加:对同一区域先刷字体色、再单独刷背景色、再单独刷边框,后一步不会清掉前一步——美化已有区域时无需一次带齐所有字段,可拆成多次窄调用。
  • border_styles 按边合并:只传 {"top":{...}} 只更新上边框,bottom / left / right 保留原状;不必为了「只改一条边」而把四边全部重传。(例外见上方「新增行的边框/样式禁止用 {} 跳过」:全新行底子里没有边框,仍需把要显示的边都显式传出。)

💡 大批量数据分批写入(推荐):当需要写入大量行(如几十行以上)时,不要试图在一次调用中生成全部 cells 数据——cells 数组过大会让单次生成的内容过长,容易出错或被截断。应将数据拆分为多批,每批 20-50 行,分多次调用 +cells-set 逐批生成并写入(如先写 A2:D21,再写 A22:D41,依此类推)。每次只生成当前批次的数据,控制单次生成量。

注意:

  • 不要把 cells 写成字符串化 JSON
  • +cells-set 默认即覆盖非空 cell--allow-overwrite 默认 true若要保护非空 cell 不被覆盖,显式传 --allow-overwrite=false(遇非空 cell 报错)
  • 若目标区域涉及合并单元格,不要向合并区域中的非左上角单元格写入数据;如需写入,应改写合并区域左上角单元格,或先调整/取消合并区域
  • 构造 range 时行号必须基于逻辑行号:如果之前通过 +csv-get 读取了数据CSV 中被双引号包裹的多行字段(如 "2026年3月2日\n星期一")是一个单元格,不是两行。写入时的行号必须按逻辑记录计算,不能按物理换行符计数,否则 range 会整体偏移导致写入到错误位置

用户说"样式和原表一致 / 保持原表格式 / 边框继承"时同理:cell_styles 只覆盖字体和对齐、不含边框,边框必须用独立 border_styles 字段传——完整继承清单见上方「新增列 / 新增行的样式继承」。

⚠️ 公式写入必须自己校验结果(后端不会报语法错)+cells-set 写公式时,即便公式有括号不配对(如 =IFERROR(VALUE(REGEXEXTRACT(D5, "\d+"))), 0) 比 IFERROR 多一个 ))或用了飞书不支持的函数(如 GOOGLETRANSLATE / CUBEVALUE后端工具也会返回 updated_cells_count=N, rc=0 的"成功"——错误会静默写进单元格显示为 #VALUE! / #NAME? / #REF!。因此:

  1. 写完立即读回+cells-set 后紧跟 +csv-get(或 +cells-get)读目标范围前几行,检查是否出现 #VALUE! / #NAME? / #REF! / #N/A / #DIV/0! / #NUM!
  2. 看到 # 开头的错误值立即修公式:#NAME? 多半是函数名拼错或用了飞书不支持的函数(如 GOOGLETRANSLATE / CUBE 系列;注意 UNIQUE / FILTER / SPLIT 飞书是支持的);#VALUE! 多半是类型不匹配或括号错位;#REF! 是引用错误;~CIRCULAR~REF~ 是循环引用(公式引用了自身或会闭环)
  3. --copy-to-range 扩展前先验证模板:模板单元格公式自己都算错,--copy-to-range 复制到 100 行就是 100 个错误
  4. 去重 / 筛选函数:飞书支持 UNIQUE / FILTER / SPLIT(原生数组函数,详见 lark-sheets-formula-translation),可直接用;DISTINCT 不是飞书函数,去重用 UNIQUE。大数据量去重 / 分组也可用透视表(+pivot-{create|update|delete},值字段聚合方式选 count
  5. 循环引用预检写聚合公式SUM / AVERAGE / COUNT 等)前必须明确引用范围不包含目标单元格自身或其传递依赖。典型反例:在 C3 写 =SUMIF(B:B,LEFT(B3,9)&"*",C:C)B 列匹配 B3 前 9 位时 C3 自己也命中,导致 C3 自引用 → ~CIRCULAR~REF~。修法:用辅助列 / 显式排除自身(SUMIFS(C:C, B:B, ..., A:A, "<>"&A3)/ 缩小范围避开自己
  6. REGEX 模式覆盖率验证:公式里的 REGEXEXTRACT / REGEXMATCH / REGEXREPLACE 等正则模式落地前必须用本地脚本在源列上跑一遍命中率统计(df[col].str.contains(pattern).mean());命中率 < 100% 时必须扩展 pattern 或加多分支IFS / 多个 IFERROR 串联)兜底,禁止只覆盖样本前 N 行就交付(典型反例:用 REGEXEXTRACT(D5,"长(\d+)") 只匹配带"长"前缀的尺寸文本,对"宽×高"、"×"、"*"等其它分隔符直接漏匹配)
  7. 公式范围与用户指令字面对齐:用户说"对 F 至 L 列求和"就必须写 SUM(F2:L2)F2+G2+H2+I2+J2+K2+L2不能漏列、多列、错列。写完用 +cells-get 拿回 formula 字符串,与用户原话逐字对照(参与求和的列名一致 / 起止列号一致 / 运算符一致),不一致就是违规
  8. 量纲 / 单位换算 / 数量乘项预检(公式不报错但结果整体偏倍数):从文本提取数字做计算前,先核对单位是否统一、是否漏乘数量、口径是否一致——这类错误公式能跑通、无 # 报错,回读也看不出(值"像对的")。必须用本地脚本对 35 个代表行离线手算一遍预期值,与公式结果逐格比对量级:① 单位不一致先统一再算(典型反例:尺寸 320CM*337CM 直接取数相乘除以 1e6 得 0.11,正确是 CM→MM 换算后得 10.78差 100 倍);② 按"单件×数量"的量必须乘数量列(典型反例:侧面板面积漏乘 F 列数量F=2 的行只算了一半);③ 标准值口径对齐(典型反例:营养成分 mg/kg 与 g/100g 口径混用,整列放大 100 倍)。口径 / 单位 / 数量任一项错,整列计算结果就是错的;这类错误公式不报错、回读也不易看出,必须靠离线手算对照。

⚠️ 公式写入的默认收尾不是停在回读,而是继续跑 +formula-verify+csv-get / +cells-get 的抽样回读只能帮你快速发现明显错误,但它覆盖不到整列中段、隐藏行、被条件格式遮蔽的错误,也看不到 partial 截断。只要这次 +cells-set / --copy-to-range / +csv-put 实际写入了公式,收尾默认就是转到 lark-sheets-formula-verify+formula-verify,直到 status='success' 不要等用户补一句“再验证下公式”才做。

⚠️ 收到 formula_errors 反馈后不要只打补丁+cells-set 返回值里若出现 formula_errors: [{cell, formula, error_type, detail}],说明某些 cell 公式编译失败(error_type=compile_failed 通常是函数语法错如 SPLIT(x)[1] 的下标取值飞书不支持SPLIT 本身支持,取第 N 项用 INDEX(SPLIT(...),N)non_formula= 开头但解析不通过)。此时禁止只聚焦修报错点的局部语法(如仅把 [1] 换成 INDEX(..,1)),必须:

  1. 重新审视整条公式的完整性:被 formula_errors 标出的那一行公式除了下标语法错还可能有其他先天缺陷字符清洗不全、IFERROR 兜底漏条件、引用列写错),修完语法错后立即整体复核
  2. 同步对称修复所有相似列:如果同一任务涉及多列相似处理(如"算 H 列面积"用 D 列尺寸、"算 I 列面积"用 E 列尺寸),修完一列必须把同样的清洗/兜底逻辑同步到所有相似列,禁止出现 H 列用 SUBSTITUTE(长)+SUBSTITUTE(高)+SUBSTITUTE(×) 而 I 列只用 SUBSTITUTE(×) 这种不对称处理——会导致一列编译通过有值、另一列编译通过但 IFERROR 全返回空,用户看到的是"数据为空"而非"公式错"
  3. 修完再读回验证:不只看 formula_errors 为空(这只证明编译通过,不证明运行时有值),必须 +csv-get 读目标列前 3-5 行,确认非空源数据对应的目标列有非空计算结果
  4. 核心心智formula_errors 是"帮你暴露编译错"的工具,不是"修掉它就收工"的通行证。编译通过 + 运行时 IFERROR 兜底空 = 用户视角的"没算出来"

⚠️ 新增行的边框/样式禁止用 {} 跳过cells 数组里 {} 的语义是"此单元格不做任何修改、保留原状态"。这在写入已有行时是安全的(原有边框/样式保持不变),但在写入新行(比如表尾追加汇总行、扩展行)时是灾难:新行底子里本来就没边框,{} 不修改 = 保留无边框状态,导致该 cell 视觉断裂。

⚠️ "汇总行"识别 → 读 lark-sheets-visual-standards 拿完整样式规范:下述双重条件同时满足才是汇总行,禁止仅凭"有 AVERAGE"就判定:

  • 语义信号(二选一):用户 prompt 含"合计/汇总/总计/统计/各科平均分/最下面加一行算…/底部总计"等意图词;或上下文明确是"表尾追加一行做聚合"
  • 结构信号:新行全行都在做聚合(含 =SUM/AVERAGE/COUNT/MAX/MIN/SUBTOTAL(...),支持 IFERROR 包裹),不是单个 cell 算个参考值或每行都算的派生列

满足上述时,不要在本文里猜样式,直接去读 lark-sheets-visual-standards 的「场景一 → 1A. 添加汇总行 / 表头行」章节,按那里的样式要点配齐 font.bold / horizontal_alignment / background_color / border_styles

反例(不是汇总行,禁止自动加粗):

  • 用户说"在 H5 帮我算个 AVERAGE 参考"→ 单 cell 计算
  • 每行都有 =AVERAGE(本行区间) 的派生列 → 属数据列
  • 用户明确说"不要加粗/样式和数据行保持一致"→ 遵循用户意图

正确做法(二选一):

  • 做法 A推荐:按上方「内容与样式分离写入」两步法——先用模板单元格 + --copy-to-range完整样式cell_styles + border_styles 都要,不能只铺 border否则新行字体 / 对齐 / 背景色全裸奔),再单独 +cells-set 写 value / formula。汇总行的 cell_styles 要点bold / 背景色 / 上边框)见 lark-sheets-visual-standards 的「场景一 → 1A. 添加汇总行 / 表头行」。
  • 做法 B:一次写入,但每个 cell含空白格都显式带 cell_styles + border_styles不能用 {}

判断是不是"新行":写入 range 超出 +csv-get 返回的 current_region 右 / 下边界(如 current_region=A1:H10、写 A11:H11)即新行,必须按上述做法补边框。

富文本单元格:超链接 / @人 / @文档(rich_text

带显示文本的超链接、@人、@文档这类富内容必须+cells-setrich_text 字段(cells[].rich_text 数组,每段一个对象、带 type不能直接传普通字符串——纯字符串只会被当作纯文本存进单元格。完整字段跑 lark-cli sheets +cells-set --print-schema --flag-name cells,常用段类型:

  • 超链接(带显示文本){"type":"link","text":"飞书","link":"https://www.feishu.cn"}。纯 URL 不需要 rich_text,直接写普通字符串即可。
  • @人{"type":"mention","mention_token":"<userId>","notify":false}仅支持同租户用户,单次写入最多 50 人。 notify 默认 true(会给被 @ 的人发通知),不想发务必显式传 false
  • @文档:同样 "type":"mention"mention_token 传文档 tokenshtXXX)。

mention_type(类型编号)等可选字段以 --print-schema 输出为准。

⚠️ rich_text 一旦设置会忽略同一 cell 的 value;它与 formula / multiple_values 三者只能选其一作为内容字段(可叠加 cell_styles / note 等)。

Dropdown 选项 + 配色(+dropdown-set / +dropdown-update

选项怎么来:--options--source-range 二选一

flag 选项来源 适用场景
--options '["a","b","c"]' 写在命令里的固定列表 选项集是常量、不需要事后维护
--source-range ''\''Sheet1'\''!T1:T3' 已有单元格里的值 选项要跟数据动态同步;想维护一张「枚举值」列后多处引用

两个 flag 必须传一个、且只能传一个——同时传或都不传CLI 会立刻报错。--source-range 用 A1 + sheet 前缀写法(如 'Sheet1'!T1:T3sheet 名按 A1 标准单引号包裹),可以指同 sheet 也可以指其它 sheet'Refs'!A1:A10)。

配色:默认即上色,三种意图三条线

下拉默认带胶囊高亮——什么 flag 都不传时,所有选项按内置 10 色色板循环上色,跟 UI 手动配下拉的默认行为对齐。三种意图:

想要的效果 怎么传
默认色板循环上色 都不传 --highlight / --colors
按选项指定具体颜色 只传 --colors '["#hex",...]'(不需要再传 --highlight
纯白下拉、不要高亮 --highlight=false(注意 =false 不能省,单写 --highlight 在 cobra 里等价于 true

--colors 长度可以短于选项数list 模式短于 --options 长度listFromRange 模式短于 --source-range 的单元格数),未指定的选项按内置色板循环补色;但不能长于——CLI 在 Validate 阶段就会拦截,错误形如 --colors length (4) must not exceed dropdown source size (3)

--highlight=false 显式关闭高亮时,--colors 即使传了也会被忽略(语义自相矛盾,但不报错)。

最小用例

--options 模式 — 默认色板(最常见)

lark-cli sheets +dropdown-set \
  --url https://... --sheet-id <id> \
  --range A2:A100 \
  --options '["待开始","进行中","已完成","已取消"]'

--options 模式 — 指定颜色4 个选项配 3 个颜色,第 4 个按色板补):

lark-cli sheets +dropdown-set \
  --url https://... --sheet-id <id> \
  --range A2:A100 \
  --options '["待开始","进行中","已完成","已取消"]' \
  --colors '["#bff7d9","#FFE699","#bacefd"]'

--source-range 模式(先在 'Sheet1'!T1:T3 维护「男/女/保密」三行,再让 B2:B21 引用它):

lark-cli sheets +dropdown-set \
  --url https://... --sheet-id <id> \
  --range B2:B21 \
  --source-range ''\''Sheet1'\''!T1:T3' \
  --colors '["#cce8ff","#ffd6e7","#e6e6e6"]'

纯白下拉(明确告诉用户"不要彩色"时才用):

lark-cli sheets +dropdown-set \
  --url https://... --sheet-id <id> \
  --range A2:A100 \
  --options '["低","中","高"]' \
  --highlight=false

⚠️ --source-range 必须带 sheet 前缀(即使跟 --range 同 sheet。注意一个坑回读这种 listFromRange 下拉单元格时,data_validation.range 看起来不带 sheet 前缀(形如 $T$1:$T$3),如果要把读出来的 range 反过来写回 --source-range必须自己重新补上 sheet 前缀,否则会被拒。

⚠️ --ranges 类批量 flag 的 sheet 前缀必须「裸写」——+cells-batch-set-style / +cells-batch-clear / +dropdown-update / +dropdown-delete--ranges 解析器不接受引号:表名含点或空格(如 2025.9一月份)也直接写 2025.9!A1,写成 '2025.9'!A1 会被当成表名一部分、报 sheet not found--source-range、透视表 --source--range 走 A1 标准sheet 名带单引号(如 'Sheet1'!A1:B2)是标准写法、裸写也接受,回读统一返回带引号形式——别把 --ranges 的裸写要求套到这些 flag 上。

+dropdown-update(多 range 批量更新)的所有 flag 语义与 +dropdown-set 完全一致;只是目标 --ranges 由单值变成 JSON 数组(每项带 sheet 前缀),同一份选项 + 配色应用到所有 range。

Shortcuts

Shortcut Risk 分组
+cells-set write 单元格
+cells-set-style write 单元格
+cells-set-image write 单元格
+dropdown-set write 对象
+csv-put write 单元格
+table-put write 单元格

Flags

+cells-set

公共四件套 · 系统:--dry-run

Flag Type 必填 说明
--range string required 写入区域A1 格式)
--cells string + File + Stdin复合 JSON required JSON2D 数组 [[{cell},...],...],维度与 --range 完全一致;每个 cell 可含 value / formula / cell_styles / note / rich_text(含 type="embed-image" 单元格嵌图)等,完整字段跑 --print-schema
--allow-overwrite bool optional 允许覆盖非空 cell默认 true设为 false 时遇非空 cell 报错
--max-cells int optional 防爆,默认 50000隐藏 flag不在 --help 列出,但可正常传入)
--copy-to-range string optional 复制范围A1 表示法):把 --range 中 --cells 写入的内容(值/公式/样式,取决于实际传入字段)复制到该区域,公式引用自动平移(如 C2=B2 → C3=B3。适合先写一行/一块模板再扩展填充整列/整区域(如 --range A1:G1 写模板、--copy-to-range A1:G100 填充 100 行)。支持整行 3:6、整列 C:E、到列尾 D3:D、到行尾 D3:3支持英文逗号分隔多个目标区域如 C1:D2,E5:F6

+cells-set-style

公共四件套 · 系统:--dry-run

Flag Type 必填 说明
--range string required 目标范围A1 格式,如 A1:B2
--background-color string optional 背景颜色(十六进制,如 #ffffff
--font-color string optional 字体颜色(十六进制,如 #000000
--font-family string optional 字体名称(如 Arial微软雅黑
--font-size float64 optional 字体大小px10、12、14
--font-style string optional 字体样式(可选值:normal / italic
--font-weight string optional 字重(可选值:normal / bold
--font-line string optional 字体线条样式(可选值:none / underline / line-through
--horizontal-alignment string optional 水平对齐(可选值:left / center / right
--vertical-alignment string optional 垂直对齐(可选值:top / middle / bottom
--word-wrap string optional 换行策略(可选值:overflow / auto-wrap / word-clip
--number-format string optional 数字格式(例:文本 @、数字 0.00、货币 $#,##0.00、日期 mm/dd/yyyy
--border-styles string + File + Stdin复合 JSON optional 边框配置 JSON{ top: {style,color,weight}, bottom: ..., left: ..., right: ... }4 方向结构相同

+cells-set-image

公共四件套 · 系统:--dry-run

Flag Type 必填 说明
--range string required 目标单元格A1 格式,必须单 cellA1;起止 cell 须相同)
--image string required 本地图片路径(支持 PNG / JPEG / JPG / GIF / BMP / JFIF / EXIF / TIFF / BPG / HEIC
--name string optional 图片文件名(含扩展名);省略时取 --image 的 basename

+dropdown-set

公共四件套 · 系统:--dry-run

Flag Type 必填 说明
--range string required 目标范围A1 格式,如 A2:A100
--options string + File + Stdin复合 JSON xor 下拉选项 JSON 数组,例如 ["opt1","opt2"]。服务端不限制选项数量,也不限制单个选项长度;含逗号的选项可以接受(写入时会自动转义)。大量选项建议改用 --source-range
--colors string + File + Stdin简单 JSON optional 下拉胶囊背景色RGB hex 数组(如 ["#1FB6C1","#F006C2"])。长度可短不可长——超长 Validate 拦截(--colors length (N) must not exceed dropdown source size (M)),未指定项按内置 10 色色板循环补色。单独传即生效--highlight=false 时被忽略。
--multiple bool optional 启用多选;默认 false
--highlight bool optional 下拉胶囊背景色高亮开关。不传 = 开(按内置 10 色色板循环上色);--highlight=false 关闭得到纯白下拉。配色用 --colors 覆盖。
--source-range string xor listFromRange 模式的下拉源 rangeA1 表示法 + sheet 前缀(如 'Sheet1'!T1:T3)。映射到 server data_validation.range,搭配 server data_validation.type='listFromRange' 自动生效。跟 --options 二选一:传 --options 走 inline 列表type=list传本 flag 走 range 引用type=listFromRange--colors 长度规则不变(≤ 源 range 单元格数),--highlight / --multiple 行为相同。当 --highlight 开启且 source 覆盖单元格数超过 2000 时,服务端会将该下拉判为 option-error这是不支持的组合CLI 会向 stderr 输出 warning。如需取消--highlight=false

+csv-put

公共四件套 · 系统:--dry-run

Flag Type 必填 说明
--start-cell string required 目标区域起点 A1A1B5,不带 sheet 前缀;用 --sheet-id / --sheet-name 指定 sheet必须是单个单元格不接受范围写法终点按 CSV 实际行列数自动推断
--csv string + File + Stdin非 JSON 文本) required RFC 4180 CSV 文本;可写值或公式(以 = 开头的单元格按公式计算);不带样式 / 批注 / 图片,需要这些用 +cells-set。
--allow-overwrite bool optional 允许覆盖(默认 true设为 false 时若目标非空报错
--range string optional --start-cell 的别名(与 +csv-get / +cells-set 一致,用 --range 定位);传区间(如 A1:H17时自动取其左上角单元格隐藏 flag不在 --help 列出,但可正常传入)

+table-put

公共URL/token无 sheet 定位) · 系统:--dry-run

Flag Type 必填 说明
--sheets string + File + Stdin复合 JSON required Typed 表格协议pandas-DataFrame-shapedJSON顶层 {"sheets":[...]},每个数组项是一张子表 {name, start_cell?, mode?, header?, allow_overwrite?, columns:["colA","colB",...], data:[[...]], dtypes?:{colA:pandasDtype, ...}, formats?:{colA:numberFormat, ...}} —— name 与外层 sheets 数组都不可省。Agents 用 scripts/sheets_df.pydf_to_sheet(df, name) 一行把 DataFrame 转成一项(多子表就 list 拼起来再包 {"sheets":[...]})。dtypes 值是 pandas dtype 字符串(int64float64Int64boolbooleandatetime64[ns]object、...CLI 端映射成内部 string/number/date/bool —— 省略 dtypes 时该列按文本写入(适合原始 CSV-shaped 数据)。formats[col] 是 Excel number_format 字符串(如 #,##0.000.0%yyyy-mm);缺省时 date 列用 yyyy-mm-ddstring 列用文本格式 @
--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_stylesrow/col sizes 用行/列范围 + type/sizemerges 用单元格 range + 可选 merge_type。styles 数组的长度/顺序/name 必须与被写入的子表对应(与 --sheets.sheets 一一对应)。完整 cell_styles 字段结构跑 +table-put --print-schema --flag-name styles

Schemas

复合 JSON flag 字段速查(只列顶层 + 一层嵌套)。深层结构看下方 ## Examples,或用 --print-schema 读完整 JSON Schema用法见 SKILL.md「公共 flag 速查」与「Agent 使用提示」)。

+cells-set --cells

【维度】行列数必须与 range 完全一致:'A1:C2'→[[,,],[,,]]2行×3列'B5:B7'→[[],[],[]]3行×1列'A1'→[[]]1×1

二维数组项(类型 object

  • value (oneOf?) — 静态单元格值(文本、数字、布尔)
  • formula (string?) — 以 '=' 开头的单元格公式(例如:'=SUM(A1:A10)'
  • note (string?) — 单元格批注/备注
  • cell_styles (object?) — 单元格样式属性,包括字体、颜色、对齐方式和数字格式 { font_color?: string, font_family?: string, font_size?: number, font_weight?: enum, font_style?: enum, …共 11 项 }
  • border_styles (object?) — 单元格边框配置,含 top/bottom/left/right 四个方向,每个方向的结构相同(见 top { top?: object, bottom?: object, left?: object, right?: object }
  • rich_text (array