# 飞书表格样式与配色规范

> **本文定位**：飞书表格"正确视觉输出"的取值标准与美化决策流——配色、表头、对齐、数值格式、斑马纹、列宽行高、图表展示，以及新增 / 继承 / 美化已有区域三类场景的做法。
> **边界**：本文只讲"样式长什么样、怎么决策"；**怎么调用工具写入样式**（`cell_styles` / `border_styles` 字段、合并、resize 等参数）见 `lark-sheets-write-cells` / `lark-sheets-range-operations` / `lark-sheets-batch-update`。**条件格式**（高亮 / 标红 / 数据条 / 色阶）见 `lark-sheets-conditional-format`。本文不含 shortcut，通用编辑准则见主 SKILL.md「飞书表格编辑准则」。

## 最高优先级原则

- **用户指令优先**：用户明确提出的格式要求（如"使用红色背景"）具有最高权重，即使与通用审美冲突。
- **继承原表风格**：编辑前先采样原文件视觉特征（色系、边框、对齐、数字格式），新增内容必须与之对齐。严禁对已有风格的文件强行施加通用标准化格式。
- **扩展而非覆盖**：新增行列或追加数据时，目标是"扩展原模板"——继承邻近区域的表头风格、条纹节奏、边框层级、对齐方式、数字格式和列宽/行高策略。
- **美化只动样式属性，不动数据**：对**已有区域**做美化时，**只能**修改 `font` / `fill` / `border` / `alignment` / `number_format` 这 5 类样式属性。**禁止**改动原始单元格的 `value` / `formula`、合并区域、行列结构、Sheet 名称。如果美化需求需要改变数据布局（例如"汇总行加进表里"），必须把"加汇总行"和"美化"拆成两步，前者属于编辑动作、需另行得到用户授权。
- **不可见视觉属性也属保护对象**：原表的**合并范围、对齐方式（H-Align/V-Align）、行高列宽、数字格式**是用户能感知但不一定会明示的视觉属性。即使用户没说"保留这些"，**禁止**因写入新内容而修改它们；写公式 / 写值 / 写新列时只传 `value` / `formula`，不要重置 `alignment` / `number_format` 等字段为默认值（重置等同于改动）。**例外**：用户明示要修改这些属性时（如"调整对齐 / 合并 / 列宽"）才能动。
- **美化范围必须覆盖所有用户语义目标**：用户说"给表格加边框 / 美化整个表"时，范围 = 实际数据区域**含所有数据行**（含汇总行、总计行、表尾备注行），不能停在"看起来主体内容结束"的地方。落地前先用 `current_region` + 末尾 5~10 行核对真实末行（同 `lark-sheets-read-data` 的「确定数据范围的正确流程」），再设置美化范围。范围漏掉用户提到的目标行 / 列**直接判失败**。

## 美化任务 5 维度 checklist（用户说"美化 / 整理 / 让表更清晰 / 适合打印"时必做）

当用户用"美化 / 整理表格 / 让表清晰 / 适合打印 / 调整样式"等口语表达**主动美化需求**时，**必须**遍历以下 5 个维度逐一落地，**只动一处就交付**（如只加边框）属于违规：

1. **表头格式区分**：表头行加粗 + 背景色填充（与数据行有色差）+ 居中对齐；多行表头时全部行同步处理
2. **对齐方式**：文本列左对齐、数值 / 货币 / 百分比列右对齐、日期 / 分类列居中；垂直方向统一居中
3. **数值格式**：每列统一小数位 + 千分位（用 `number_format`）；金额列统一货币符号；同一列内**禁止**出现 0 位 / 1 位 / 2 位小数混杂
4. **边框**：覆盖范围按上方「美化范围必须覆盖所有用户语义目标」规则（含汇总 / 总计 / 表尾说明行），内外框线清晰
5. **列宽 + 行高 + 自动换行**：详细规则见 `lark-sheets-range-operations` 的「写入后列宽自适应」章节（按最长字符数扩列宽 / 长文本设置 `cell_styles.word_wrap="auto-wrap"` + 调高行高 / 长数字设置 `number_format` 防科学计数法）

**差异化标注场景**：用户要求"重复行 / 异常值 / 重要项视觉区分"时，标注列 / 行必须设置与普通数据**显著不同**的 `cell_styles`（背景色 + 加粗 + 字体色至少改一项），不能与普通数据格式完全一致。

**显式要求边框 / 表头 / 对齐时同样按上面标准落地**（不必等用户说"美化"）：① 用户说"给某矩形区域加边框"必须**整个矩形含表头行、数据行、汇总行全部加内外框**，落地后核起 / 末行、末列三边界（反例：要求加边框的区域实际无任何边框）；② **新建表头前先确认哪一行才是表头**——别把已有的第一行数据误当表头刷成蓝底白字，真正该加的表头列也要建出来（反例：把第一行数据误设成了表头样式）；③ 新增 / 编辑区域的字号必须与原表一致，禁止 13 号与 14 号、10 号与 11 号混杂（反例：新列字号与原表不一致）。

## 通用样式规范

> 以下取值标准都在「最高优先级原则」的**继承原表风格 / 扩展而非覆盖**前提下生效：凡涉及"沿用原表"的条目，遵循该原则即可，本节不再逐条复述。

### 1. 表头样式

- 表头/汇总行须与数据区域有明确视觉区分。
- 使用低饱和度背景色搭配字体颜色（如深蓝 + 白字，浅蓝 + 黑字），文字加粗、水平居中。
- 表头覆盖多列时使用合并单元格。

### 2. 数据区域样式

- 减少垂直线条，优先使用水平浅灰细线。
- **对齐方式**：文本左对齐，数值/货币/百分比右对齐，日期或分类居中，所有内容垂直居中。
- 次要信息（备注、次要日期等）使用缩小字号或浅灰色。
- **Zebra Stripes**：数据行 > 10 行时可使用交替背景色引导视线。
  - 设置前先清理原区域背景色为白色（#FFFFFF），再设置斑马纹色，避免新旧混杂。
  - 优先直接设置单元格背景色，而非条件格式（除非用户要求）。
  - 推荐配色：奇数行 #FFFFFF，偶数行 #F3F4F6 或 #EBF1F8。

### 3. 数值格式

- 百分比使用 `%` 符号，适当注明单位和货币符号（¥、$）。
- 大于 1000 的数字使用千分位符，保留一致的小数位数（1–2 位）。
- 涉及数据检索的须注明数据来源。
- 可使用数据条/色阶/条件格式增强可视化。

### 4. 整体结构

- 长表/宽表考虑冻结行列，方便滚动查看。
- **长文本处理**：启用自动换行，行高合理调整以确保阅读舒适，添加适当垂直留白，目标是清晰、专业、不拥挤的布局。
- 保持表格简洁，合理分组（可用合并单元格展示分组），在适当位置添加合计或汇总行。
- **区域分隔**：多阶段或多类别时，使用柔和背景色块进行逻辑分区，而非简单边框。
- **增删行列的样式规则**：
  - 新增整列继承同组列的表头样式、列宽、对齐和数字格式；新增整行继承同层级数据行或汇总行风格，避免写成表头风格。追加列时需判断是否应加入已有合并单元格（常见于顶部标题行）。
  - 若追加位置紧邻汇总行、说明区或空白分隔区，先判断真实数据区域边界再操作，避免破坏原有结构。
  - **Zebra Stripes 维护**：插入或删除行后若影响后续行奇偶性，须从受影响行往后重建条纹（先清理再重设）。少量增删用局部重建，大量变动用全局清理+统一重建。
  - 具体采样与复制流程见下方「场景二：从已有区域继承美化」。
- **列宽 / 行高调整**（飞书 `+cols-resize` / `+rows-resize` 直接给像素值：统一尺寸用 `--range` + `--width`/`--height <px>`，多列 / 多行不同尺寸用 `--widths`/`--heights` map 一次原子完成，如 `--widths '{"A":100,"C:E":120}'`）：
  - 禁止硬编码固定列宽，须根据该列实际内容长度估算像素。
  - 经验估算：中文每字约 15-18px，英文/数字每字约 7-9px，外加 10-16px padding。
  - 上下限建议 80~400px；超上限启用自动换行（`word_wrap: auto-wrap`）+ 调整行高，而非无限加宽。
  - 合并单元格不参与列宽计算，避免撑宽单列。
  - 复制自原文件的列优先沿用原列宽，不重新计算覆盖。

### 5. 配色

- 优先沿用原表色板与明暗层级（见「继承原表风格」），新增区域不凭空换色，确保视觉连续。
- 背景填充选择柔和色（如浅蓝 `#DDEBF7`），区分颜色时优先同一主题色不同深浅，避免超过 3 种主题色。

### 6. 图表展示

- 遵循用户指令选择图表类型，或匹配用户意图（饼图/环形图 → 占比，折线图 → 趋势）。
- 包含必要元素：标题、图例、数据标签、坐标轴标题。
- 调整至合适大小，避免数据和标签过多堆叠。
- **图表放置防重叠**：新增图表前须计算放置区域，避免与已有图表重叠。具体步骤：
  1. 调用 `+chart-list` 获取当前工作表所有已有图表的 `position`（锚点单元格：`col` 是列字母如 "A"/"B"、`row` 是 1-based 行号；以 `+chart-list` 实际返回字段为准）、`offset`（锚点内偏移：`row_offset`、`col_offset`，单位像素）以及 `size`（`width`、`height`，单位像素）。
  2. 获取工作表的行高和列宽信息（像素）。
  3. 根据每个图表的锚点 `position.row`/`position.col` + 偏移 `offset.row_offset`/`offset.col_offset` + 尺寸 `size.width`/`size.height`，结合行高列宽，计算出每个已有图表覆盖的像素矩形区域 `(x_min, y_min, x_max, y_max)`。
  4. 为新图表选定大小后，候选放置位置应避开所有已有矩形区域；若存在重叠则向下或向右偏移，直至找到无冲突位置。
  5. 若工作表已无足够空间，优先向下方空白区域放置，保持图表间至少 1 行或 1 列的间距。

> 飞书表格中颜色需带 `#` 前缀（如 `#0070C0`），与 openpyxl 的无前缀写法不同。
> 具体工具调用参数格式，请读取对应工具 skill（`lark-sheets-write-cells`、`lark-sheets-conditional-format`、`lark-sheets-range-operations` 等）。

---

## 场景化操作指南

### 场景一：新增独立样式

> 适用情况：在表格中创建全新的、具有独立视觉特征的区域，如汇总行、新表头、独立数据表等。

#### 1A. 添加汇总行 / 表头行

**决策流程：**
1. 先用 `+cells-get` 读取目标位置上方的数据区域，确认数据边界和已有样式（背景色、字体大小等）
2. 如果需要新增空行，先用 `+dim-{insert|delete|hide|unhide|freeze|group|ungroup}` 插入行
3. 用 `+cells-set` 写入汇总公式 + 特殊样式（背景色区分 + 加粗 + 边框）
4. 如果汇总行标题需要跨列显示，追加 `+cells-{merge|unmerge}` 合并标题区域

**样式要点：**
- 汇总行使用比数据区域更深的同色系背景（如数据区 #EBF1F8 → 汇总行 #D6E4F0 或 #4472C4 + 白字）
- 必须加粗，水平对齐方式与数据列一致（数值列右对齐，文本列左对齐）
- 上方加一条较粗的边框线，与数据区域形成视觉分隔

#### 1B. 添加独立数据表/独立区域

**决策流程：**

1. 新建 sheet，或用 `+cells-get` 或 `+workbook-info` 确认已有表格的占用范围，找到空闲区域
2. 用 `+cells-get` 采样已有表格的表头样式（背景色、字体大小、字重、对齐方式）和数据区域样式
3. 新表头复用已有表头的配色和字体参数（保持风格统一），但内容和列宽可独立
4. 新数据区域复用已有数据区域的对齐规则、边框风格、数字格式
5. 用 `+cells-set` 一次性写入新表头 + 数据

**样式要点：**
- 必须复用：背景色色系、字体大小、字重、边框风格
- 可以独立：列宽、行高、具体数字格式（根据新数据的类型调整）
- 新旧表格之间至少留 1~2 行空白作为视觉分隔

### 场景二：从已有区域继承美化

> 适用情况：新增的行/列/区域与已有内容性质相同（数据类型、层级一致），需要无缝衔接已有格式。

#### 2A. 继续补充行/列（数据性质与已有内容一致）

**核心规则**：采样紧邻 2 行 → 判断并延续 Zebra Stripes 奇偶性 → 按 write-cells 的继承清单带齐样式写入。

**斑马纹延续要点**（本节只管"奇偶判断"这一标准，"带哪些样式字段写入"的机制见下方指针）：

- 至少读 2 行（末行 + 倒数第二行）才能判断是否有斑马纹交替色
- 若倒数两行背景色不同（如 #FFFFFF 与 #F3F4F6），新行按奇偶延续，不要固定一个色

> 具体继承哪些字段、怎么采样与写入（`+cells-get` 读源行 `cell_styles` + `border_styles`、`+sheet-info --include row_heights,merges` 读行高合并、带齐 6 类样式写入）见 `lark-sheets-write-cells` 的「新增列 / 新增行的样式继承」章节——`border_styles` 四边最易遗漏，以那里为准。

#### 2B. 基于模板区域的修改（copy 保留所有格式）

**核心思路：三步分层法**

```
Step 1 — 格式铺开：`+batch-update` + `+range-copy`（或 `+range-fill`）
  └── 将模板行/区域的 **全部格式**（样式、边框、数字格式、数据验证等）复制到目标区域
  └── 推荐用 `+range-copy --paste-type formats`（仅复制格式，目标值/公式保留），即"格式刷"
  └── 若需连带公式平移填充（如公式列结构一致），改用 `+range-fill --series-type copy` 或 `+range-copy --paste-type all`

Step 2 — 内容覆写：`+batch-update` + `+cells-set`（仅传 value/formula，不传任何样式）
  └── 将每行的实际数据写入，cell_styles 全部省略，因为格式已在 Step 1 中就位

Step 3 — 微调收尾：`+rows-resize --heights` / `+cols-resize --widths`（行高列宽 map 一次原子完成）、`+batch-update` + `+cells-{merge|unmerge}` 等
  └── 调整行高列宽、处理合并单元格、扩展条件格式范围等边缘情况
```

**关键注意事项：**
- Step 1 用 `+range-copy --paste-type formats` 时只铺格式、不动值/公式，Step 2 再用 `+cells-set` 写值即可（`+cells-set` 默认覆盖，无需额外 flag）；若 Step 1 用 `--paste-type all` 连带复制了值/公式，Step 2 写入同样会覆盖（默认行为）
- `+range-fill --series-type auto`（或 `linear`/`date`）会自动递增数字序列（1→2→3）和日期序列，`+range-fill --series-type copy` 则原样复制值但公式引用会自动平移
- 如果模板区域存在合并单元格，copy/fill 不会复制合并状态，必须在 Step 3 中用 `+cells-{merge|unmerge}` 补全
- 如果模板区域有条件格式，需要在 Step 3 中通过 `+cond-format-update` 扩展 ranges

**场景：纯"格式刷"（用户说"把 A 列样式应用到 B 列"、"格式复制过去"、"只刷格式不改数据"）**

单步即可，无需三步分层：调用 `+range-copy --paste-type formats`，`--source-range` 为样式来源、`--target-range` 为目标起点。参数细节见 `lark-sheets-range-operations`。

### 场景三：已有区域格式美化

> 适用情况：对已存在数据的区域进行格式美化（不改变数据内容），重点处理表头、汇总行等特殊行的识别与格式设置，需特别注意合并单元格的安全操作。

#### 整体操作流程

```
1. 探查阶段
   ├── `+workbook-info` → 获取子表列表、行列数、冻结位置
   ├── `+sheet-info --include merges` → 获取合并区域
   ├── `+cells-get`（前几行 + 末尾几行，`--include style`）→ 采样表头/数据区/汇总行样式
   └── 分析结果 → 建立区域地图（表头行号、数据起止行号、汇总行号、合并区域列表）

2. 规划阶段
   ├── 判断表头行：通常第 1 行或前 2 行，特征为加粗/背景色/合并/居中
   ├── 判断汇总行：通常最后 1~2 行，特征为加粗/SUM/AVERAGE 公式/更深背景色
   ├── 判断合并区域：从 `+cells-get` 返回中识别（多个单元格同值且样式相同通常暗示合并）
   └── 制定美化方案：按区域分别设置样式

3. 执行阶段（按顺序）
   ├── 先处理合并单元格（如需取消合并再重新合并，必须先 unmerge 再 merge）
   ├── 设置表头样式
   ├── 设置数据区域样式
   ├── 设置汇总行样式
   └── 调整列宽行高
```

#### 美化中的合并单元格要点

- 编辑前先识别已有合并区域（见探查阶段），避免破坏原有语义分区。
- 美化表头/分组标题时，若需修改合并区域的范围或样式，遵循"先 `unmerge` → 修改 → 再 `merge`"顺序。
- 合并区域样式只写左上角，不要对合并内的其他单元格重复写入样式。

> 合并单元格完整的安全操作规则（含数据保护、样式占位等 5 条）见 `lark-sheets-range-operations` 的 `+cells-{merge|unmerge}` 章节。
