# 导出 (export)

## 使用场景

### 导出

用户说"导出/下载xlsx/存为Excel/存成表格文件/把表格变成xlsx/导出表格/下载表格/导出为 excel":
- 导出表格 → `export`（单命令会自动等待完成，并可选下载）
- 仅需传 `--node`，可选 `--output` 指定本地文件/目录（不传则返回 downloadUrl）
- 需要落盘到本地 → `dws sheet export --node <NODE_ID> --output <path>`，命令自动下载 xlsx
- 禁止用 `range read` 全量读取后自行拼接 xlsx 来模拟导出；必须使用 `export`，才能保留格式、合并和公式等属性
- 禁止在 AI Agent 侧实现轮询或重试；命令会自动等待结果，最长约 5 分钟

用户说"导出 CSV/存成 csv/导出这个工作表为 csv":
- 导出单个工作表为纯 CSV → `export-csv`（**同步**，不走异步任务；与 `export` 是两条独立命令）
- 用 `--sheet-id` 指定工作表（不传取第一个）、`--range` 限定范围、`--value-render-option` 选取值模式
- 不传 `--output` 时 CSV 正文打印到 stdout，可直接管道处理

## 命令详细参考

### 导出表格为 xlsx（异步任务一站式）
```
Usage:
  dws sheet export [flags]    # 一站式：提交 → 轮询 → 可选下载
Example:
  # 仅导出，返回 downloadUrl（链接有时效性，请尽快下载）
  dws sheet export --node <NODE_ID>
  dws sheet export --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>"

  # 导出并自动下载为本地文件
  dws sheet export --node <NODE_ID> --output ./report.xlsx

  # --output 为目录时，自动按下载链接中的文件名保存
  dws sheet export --node <NODE_ID> --output ./

Flags:
      --node string     表格文档 ID 或 URL (必填)
      --output string   本地保存路径（可选，支持文件路径或目录）
```

将钉钉在线电子表格导出为 Office xlsx 格式。**单命令一站式**：命令会自动等待导出完成，并在指定 `--output` 时保存到本地。AI Agent 无需拆分步骤或自行轮询；最长等待约 5 分钟，超时后按命令错误处理。

**命令返回**：
- `--output` 未指定：进度日志 + 末尾输出 `jobId` 和 `downloadUrl`（链接有时效性，请尽快下载）
- `--output` 指定为文件路径：下载到该路径并输出 `导出完成: <path>`
- `--output` 指定为已存在目录：自动从 `downloadUrl` 推断文件名并保存到该目录下

**失败处理**：
- 导出任务返回 `FAILED`：命令立即返回错误并附带失败原因，**禁止自动重试 `dws sheet export`**，告知用户稍后再试
- 轮询 30 次仍 `PROCESSING`：命令返回超时错误，告知用户稍后再试

**限制**：仅支持钉钉在线电子表格（axls）→ xlsx。导出钉钉文字文档请使用 `doc` 产品对应的导出工具。

### 导出单个工作表为纯 CSV（同步）
```
Usage:
  dws sheet export-csv [flags]
Example:
  dws sheet export-csv --node <NODE_ID>
  dws sheet export-csv --node <NODE_ID> --sheet-id <SHEET_ID> --output ./data.csv
  dws sheet export-csv --node <NODE_ID> --range A1:Z1000 --value-render-option raw_value

Flags:
      --node string                  表格文档 ID 或 URL (必填)
      --sheet-id string              工作表 ID 或名称（不传则第一个工作表）
      --range string                 导出范围，A1 表示法（不传则整表；大表可用此分块导出）
      --value-render-option string   取值模式: formatted_value(默认) / raw_value / formula
      --output string                本地保存路径（可选，支持文件路径或目录）；不传则输出到 stdout
      --allow-truncated              允许数据被截断时仍然导出。默认截断即报错且不写文件
```

同步读取**单个**工作表并输出 RFC4180 CSV，不走异步导出任务。与 `export` 是两条独立命令：`export` 导整篇工作簿的 xlsx（异步提交+轮询），`export-csv` 只导一个工作表的纯值（一次请求即返回）。不传 `--output` 时 CSV 正文打印到 stdout，可直接管道处理。

**`--output` 落盘是原子替换**：CSV 先写同目录临时文件、成功后再替换目标，写入失败时已有文件保持原样（父目录不存在仍按错误处理，不会自动创建）。`--output` 指向已存在目录时保存为该目录下的 `sheet-export.csv`。

**超大表默认 fail-closed**：数据超出单次读取上限（服务端返回 `hasMore`）时，命令**直接报错并以非 0 退出，既不打印 CSV 也不写文件**（已存在的目标文件不会被截断数据覆盖）。处理方式：
- 用 `--range` 分块导出（如 `--range A1:Z1000`、`A1001:Z2000` …）
- 改用 `dws sheet export` 导出完整表格的 xlsx
- 确认可以接受不完整数据时，显式加 `--allow-truncated`；此时才会照常输出/落盘，并在 stderr 给出「已被截断」警告，成功提示也会写明"数据已截断，不是完整表格"

```bash
# 落盘到本地
dws sheet export-csv --node <NODE_ID> --sheet-id <SHEET_ID> --output ./data.csv

# 输出到 stdout 便于管道处理
dws sheet export-csv --node <NODE_ID> --sheet-id <SHEET_ID>

# 大表分块导出（避免截断；不分块时默认会因截断而报错）
dws sheet export-csv --node <NODE_ID> --sheet-id <SHEET_ID> --range "A1:Z1000" --output ./part1.csv

# 明确接受不完整数据（否则截断即失败）
dws sheet export-csv --node <NODE_ID> --sheet-id <SHEET_ID> --allow-truncated --output ./partial.csv
```

注意：CSV 只写纯值，不保留样式/合并/公式；需要完整属性请用 `dws sheet export` 导 xlsx。只是让 Agent 读取内容（带 `[row=N]` 行号前缀）请用 `dws sheet csv-get`。

## 核心工作流

```bash
# ── 工作流 12: 导出表格为 xlsx（单命令一站式）──

# 场景 A：仅获取下载链接（命令自动等待完成并返回 downloadUrl）
dws sheet export --node <NODE_ID> --format json
# 传入 URL 也可：
# dws sheet export --node "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>" --format json

# 场景 B：导出并自动下载为本地文件
dws sheet export --node <NODE_ID> --output ./report.xlsx

# 场景 C：下载到目录，自动按链接推断文件名
dws sheet export --node <NODE_ID> --output ./

# 禁止在 Agent 侧实现任何轮询或重试；命令会自动等待结果。
# 若命令返回失败或超时，直接告知用户稍后再试，不要自动重调 dws sheet export。
```

## 上下文传递

| 操作 | 从返回中提取 | 用于 |
|------|-------------|------|
| `export` | `downloadUrl`（未指定 --output）/ `outputPath`（指定 --output） | 直接下发给用户或告知文件已保存到本地；不要再调用其他 export 相关命令 |
| `export` 超时中断 | 错误信息 | 直接报告失败或超时；当前没有独立续查命令，不自动重新提交导出 |
| `export-csv` | CSV 正文（未指定 --output，走 stdout）/ `导出完成: <path>`（指定 --output） | 直接把 CSV 交给下游处理，或告知文件已保存到本地。命令是同步的，无任务/轮询概念 |

## 注意事项

- ★ `export` 仅支持钉钉在线电子表格（axls）→ xlsx；传入钉钉文字文档会报 `invalidRequest.document.typeIllegal`
- ★ `export` 为单命令一站式，会自动等待结果并可选下载；**Agent 不得自行轮询或重试**，命令返回成功后不再调用其他 export 相关命令
- `export` 内置轮询策略：1~5 次间隔 2s、6~10 次间隔 5s、11~20 次间隔 10s、21~30 次间隔 15s，硬上限 30 次（约 5 分钟）；超时后命令返回错误，告知用户稍后再试即可
- ★ `export` 命令返回失败或超时时，**禁止自动重调 `dws sheet export`**；直接告知用户导出失败并建议稍后再试
- `export` 未指定 `--output` 时，返回的 `downloadUrl` 具有时效性，获取后请尽快下载；若用户需要本地文件，优先直接传 `--output` 让 CLI 代为下载
- `export` 的 `--output` 可为文件路径或已存在目录；为目录时自动从 `downloadUrl` 推断文件名，为文件路径时直接按该路径保存
- 用户要求"导出表格/下载 xlsx"时，必须使用 `export` 单命令，禁止用 `range read` 读全量数据后自行拼 xlsx 模拟导出；`export` 会保留格式、合并、公式等属性
- `export-csv` 与 `export` 是两条独立命令：`export-csv` 同步导出**单个**工作表的纯值 CSV，不保留样式/合并/公式；要整篇工作簿或完整属性一律用 `export`
- ★ `export-csv` 遇到数据超出单次读取上限时默认报错、既不输出也不写文件；优先用 `--range` 分块导出，只有用户明确接受不完整数据时才加 `--allow-truncated`
