first commit

This commit is contained in:
2026-09-02 11:44:52 +08:00
commit 0c8fa2653e
309 changed files with 57278 additions and 0 deletions
@@ -0,0 +1,292 @@
# 透视表 (pivot-table)
## 真对象硬约束
当用户要求"透视表 / 分组汇总 / 交叉分析 / 按 X 统计 Y"时,**必须**通过 `pivot-table create` 创建真实的透视表对象。**禁止**用 `SUMIFS` / `COUNTIFS` 等普通公式 + `csv-put` 在原表中拼一张"看起来像透视表的汇总表"来代替——静态公式无法随源数据动态更新,且失去交互能力。判断标准:交付后 `pivot-table list` 必须能返回该对象。
## 使用场景
读写透视表对象。本 reference 覆盖 4 个命令:
| 操作需求 | 使用命令 | 说明 |
|---------|---------|------|
| 查看已有透视表 | `pivot-table list` | 获取透视表的结构、数据源和配置 |
| 创建透视表 | `pivot-table create` | 创建透视表对象 |
| 更新透视表 | `pivot-table update` | 更新透视表配置(行/列/值/筛选字段) |
| 删除透视表 | `pivot-table delete` | 删除透视表 |
典型工作流:先读取现有透视表了解配置 -> 执行创建/更新/删除 -> 再次读取验证结果。
## 行/值字段映射(创建前必做)
创建透视表前先识别用户需求中的分组维度和聚合指标,**不要搞反**:
- **rows(行字段)** = 分组维度,即"按什么分组"。例:部门、地区、医生、产品类别
- **values(值字段)** = 聚合指标,即"统计什么数值"。例:销售额(`summarize_by: "sum"`)、订单数(`summarize_by: "count"`
- **columns(列字段)** = 交叉维度(可选),即"再按什么横向展开"。例:月份、性别
| 用户说 | rows | values | columns |
|--------|------|--------|---------|
| "按部门统计人数" | 部门 | 姓名(`"count"` | -- |
| "按医生统计费用和结余" | 主管医生 | 费用(`"sum"`)、结余(`"sum"` | -- |
| "各部门男女人数" | 部门 | 姓名(`"count"` | 性别 |
**常见配置错误(必须注意)**
- **数据源范围必须精确**:透视表的数据源范围必须包含表头行,且精确覆盖全部数据行列。范围过大(包含空行/空列)或过小(遗漏数据列)都会导致透视表结果错误
- **行列字段选择要匹配用户意图**:用户说"按商品统计金额" -> 行字段=商品,值字段=金额(`summarize_by: "sum"`)。不要把行列字段搞反
- **聚合类型要匹配**:用户说"统计数量" -> `"count"`"统计总额" -> `"sum"`"统计平均" -> `"average"`
- **创建后必须验证**:调用 `pivot-table list` 确认透视表结构正确
## 命令详细参考
### 获取透视表
```
Usage:
dws sheet pivot-table list [flags]
Example:
# 列出所有透视表
dws sheet pivot-table list --node NODE_ID --sheet-id SHEET_ID
# 获取单个透视表详情
dws sheet pivot-table list --node NODE_ID --sheet-id SHEET_ID --pivot-table-id PT_ID
Flags:
--node string 表格文档 ID 或 URL (必填)
--sheet-id string 工作表 ID 或名称 (必填)
--pivot-table-id string 透视表 ID (可选,不传则返回全部)
```
### 创建透视表
```
Usage:
dws sheet pivot-table create [flags]
Example:
# 按部门统计销售额(默认自动新建工作表存放)
dws sheet pivot-table create --node NODE_ID \
--source "'Sheet1'!A1:D100" \
--properties '{
"rows": [{"field": "部门"}],
"values": [{"field": "销售额", "summarize_by": "sum"}],
"show_row_grand_total": true
}'
# 指定放置到已有工作表的特定位置
dws sheet pivot-table create --node NODE_ID \
--source "'Sheet1'!A1:E200" \
--target-sheet-id TARGET_SHEET_ID --target-position "A1" \
--properties '{
"rows": [{"field": "部门"}],
"values": [{"field": "销售额", "summarize_by": "sum"}]
}'
# 通过文件传入配置
dws sheet pivot-table create --node NODE_ID \
--source "'Sheet1'!A1:D50" --properties @pivot.json
Flags:
--node string 表格文档 ID 或 URL (必填)
--source string 数据源区域,A1 表示法含 sheet 前缀 (必填,如 "'Sheet1'!A1:D100")
--properties string 透视表配置 JSON (必填,含 rows/columns/values/filters)
--target-sheet-id string 目标工作表 ID 或名称 (可选,不传则自动新建工作表)
--target-position string 透视表放置位置 (可选,A1 格式单个 cell,如 "B5",不传默认 A1)
```
### 更新透视表
```
Usage:
dws sheet pivot-table update [flags]
Example:
# 先获取现有配置
dws sheet pivot-table list --node NODE_ID --sheet-id SHEET_ID --pivot-table-id PT_ID
# 修改后回写
dws sheet pivot-table update --node NODE_ID --sheet-id SHEET_ID --pivot-table-id PT_ID \
--properties '{
"rows": [{"field": "部门"}],
"values": [
{"field": "销售额", "summarize_by": "sum"},
{"field": "订单号", "summarize_by": "count", "display_name": "订单数"}
],
"show_row_grand_total": true
}'
Flags:
--node string 表格文档 ID 或 URL (必填)
--sheet-id string 工作表 ID 或名称 (必填)
--pivot-table-id string 透视表 ID (必填,可通过 pivot-table list 获取)
--properties string 透视表配置 JSON (必填)
```
### 删除透视表
```
Usage:
dws sheet pivot-table delete [flags]
Example:
dws sheet pivot-table delete --node NODE_ID --sheet-id SHEET_ID --pivot-table-id PT_ID
Flags:
--node string 表格文档 ID 或 URL (必填)
--sheet-id string 工作表 ID 或名称 (必填)
--pivot-table-id string 透视表 ID (必填,可通过 pivot-table list 获取)
```
> [强制] 危险操作:删除不可恢复。必须先向用户展示操作摘要并获得明确同意,用户同意后才加 `--yes` 执行。
## `--properties` JSON Schema 速查
**顶层字段**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `rows` | object[] | 否 | 行字段数组(分组维度),详见下方「rows/columns 字段项」表 |
| `columns` | object[] | 否 | 列字段数组(交叉维度),结构同 rows |
| `values` | object[] | 是 | 值字段数组(聚合指标,至少一项),详见下方「values 字段项」表 |
| `filters` | object[] | 否 | 筛选字段数组,详见下方「filters 字段项」表 |
| `show_row_grand_total` | boolean | 否 | 是否显示行总计,默认 true |
| `show_col_grand_total` | boolean | 否 | 是否显示列总计,默认 true |
| `show_subtotals` | boolean | 否 | 是否显示分类小计,默认 true |
| `repeat_row_labels` | boolean | 否 | 是否显示重复项标签,默认 false |
| `collapse` | object | 否 | 行字段折叠状态:字段名 -> 要折叠的项目列表,如 `{"部门": ["A组", "B组"]}` |
**rows/columns 字段项**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `field` | string | 是 | 列名(表头文本),必须与数据源首行的列名完全匹配 |
| `display_name` | string | 否 | 显示名称(不传时使用 field 值) |
**filters 字段项**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `field` | string | 是 | 列名(表头文本),必须与数据源首行的列名完全匹配 |
| `display_name` | string | 否 | 显示名称(不传时使用 field 值) |
**values 字段项**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `field` | string | 是 | 列名(表头文本),必须与数据源首行的列名完全匹配 |
| `summarize_by` | string | 否 | 聚合方式,默认 sum,详见下方枚举表 |
| `display_name` | string | 否 | 显示名称(不传时自动生成,如"求和 - 销售额" |
| `show_data_as` | string | 否 | 值显示方式:`normal`/`percent_of_row_total`/`percent_of_col_total`/`percent_of_grand_total` |
**summarize_by 枚举值**
| 值 | 说明 |
|----|------|
| `sum` | 求和(默认) |
| `count` | 计数 |
| `average` | 平均值 |
| `max` | 最大值 |
| `min` | 最小值 |
| `product` | 乘积 |
| `count_numbers` | 数值计数 |
| `std_dev` | 标准偏差 |
| `std_dev_p` | 总体标准偏差 |
| `var` | 方差 |
| `var_p` | 总体方差 |
| `distinct` | 去重计数 |
| `median` | 中位数 |
## `--source` 数据源格式
- 格式:`'SheetName'!StartCell:EndCell`
- 示例:`'Sheet1'!A1:D100``'销售数据'!A1:F500`
- 必须包含表头行(通常从第 1 行开始)
- sheet 名称用单引号包裹(含空格或特殊字符时必须)
- `source` 直接使用上述 A1 表示法,不要改写成其他结构
## 高级功能示例
```bash
# 含折叠 + show_data_as
dws sheet pivot-table create --node <NODE_ID> \
--source "'Sheet1'!A1:E200" \
--properties '{
"rows": [{"field": "部门"}],
"values": [
{"field": "销售额", "summarize_by": "sum"},
{"field": "订单数", "summarize_by": "count", "show_data_as": "percent_of_col_total"}
],
"collapse": {"部门": ["A组"]},
"show_row_grand_total": true
}'
```
> `collapse` / `show_data_as` 为可选字段;仅使用命令文档列出的取值,并按命令返回处理无效配置。
## 核心工作流
```bash
# -- 工作流 1: 创建简单分组汇总 --
# 1. 先查 sheetId
dws sheet list --node <NODE_ID> -f json
# 2. 查看数据范围确认列名和边界
dws sheet csv-get --node <NODE_ID> --sheet-id <SHEET_ID> --range "A1:F5"
# 3. 创建透视表(按部门统计销售额)
dws sheet pivot-table create --node <NODE_ID> \
--source "'Sheet1'!A1:D100" \
--properties '{
"rows": [{"field": "部门"}],
"values": [{"field": "销售额", "summarize_by": "sum"}],
"show_row_grand_total": true
}'
# 4. 验证创建结果(用 create 返回的 targetSheetId 查询)
dws sheet pivot-table list --node <NODE_ID> --sheet-id <TARGET_SHEET_ID>
# -- 工作流 2: 多维度交叉分析 --
dws sheet pivot-table create --node <NODE_ID> \
--source "'Sheet1'!A1:E200" \
--properties '{
"rows": [{"field": "部门"}, {"field": "产品"}],
"columns": [{"field": "季度"}],
"values": [
{"field": "销售额", "summarize_by": "sum"},
{"field": "订单号", "summarize_by": "count", "display_name": "订单数"}
],
"show_row_grand_total": true,
"show_col_grand_total": true,
"show_subtotals": true
}'
# -- 工作流 3: 更新透视表配置 --
# 先获取现有配置
dws sheet pivot-table list --node <NODE_ID> --sheet-id <SHEET_ID> --pivot-table-id <PT_ID>
# 修改后回写(增加一个值字段)
dws sheet pivot-table update --node <NODE_ID> --sheet-id <SHEET_ID> --pivot-table-id <PT_ID> \
--properties '{
"rows": [{"field": "部门"}],
"values": [
{"field": "销售额", "summarize_by": "sum"},
{"field": "利润", "summarize_by": "average", "display_name": "平均利润"}
],
"show_row_grand_total": true
}'
```
## 上下文传递
| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `pivot-table list` | `pivotTables[].id` | 后续 update / delete 的 `--pivot-table-id` |
| `pivot-table list --pivot-table-id` | 完整配置(rows/columns/values/filters/collapse/options | update 时作为基础配置修改后回写 |
| `pivot-table create` | `pivotTable.id` | 后续 update / delete 的 `--pivot-table-id` |
| `pivot-table create` | `pivotTable.targetSheetId` | 后续 list / update / delete 的 `--sheet-id`(透视表所在工作表) |
| `pivot-table delete` | `message` | 确认删除完成 |
| `sheet list` | 工作表的 `sheetId` | 所有 pivot-table 命令的 `--sheet-id` |
## 注意事项
- [强制] **`--sheet-id` 获取规范**`sheetId` 未知时必须先通过 `dws sheet list --node <NODE_ID> --format json` 查询,禁止凭空编造(如臆测为 `Sheet1``sheet1``0``default` 等)
- [强制] **创建后必须验证**:透视表创建后必须调用 `pivot-table list` 验证配置是否正确
- [强制] **pivot-table-id 禁止臆测**:必须通过 `pivot-table list` 获取真实的透视表 ID,不可编造
- [强制] **source 必须精确**:数据源范围必须从表头行开始,精确覆盖数据区域,先用 `csv-get` 确认数据边界
- **field 名称必须准确**rows/columns/values/filters 中的 field 值必须与源数据表头完全一致(区分大小写)
- **透视表自动新建子表**:创建的透视表默认放置在自动新建的子表中,不会覆盖源数据。可通过 `--target-sheet-id``--target-position` 指定放置到已有工作表
- **不支持修改数据源**:update 仅可修改字段配置和显示选项,不可修改 source
- **折叠状态**:collapse 字段用于控制行字段的展开/折叠,格式为 {字段名: [要折叠的项]}
- **大 JSON 用 @file**`--properties` 支持 `@文件路径` 读取本地 JSON 文件