---
title: 导出
description: 列表导出、行数统计与合计查询
pageClass: g3-api
---
# 导出
导出接口,前缀 `/export/**`。三个接口**走完全相同的权限链路与同一套聚合 SQL**,因此「共 N 条」、列表底部合计与导出文件里的内容必然一致。
| 接口 | 返回 | 用途 |
|---|---|---|
| `/export/list` | **文件流**(xlsx 或 zip) | 导出列表 |
| `/export/count` | JSON | 批量导出弹窗的「共 N 条」 |
| `/export/totals` | JSON | 列表底部的「总合计」 |
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `moduleId` | string | 是 | 模块编码(决定列、查询表与权限) |
| `searchCondition` | string | | 查询条件(布尔表达式片段) |
| `orderBy` | string | | 排序,如 `b_id ASC`,多列逗号分隔 |
| `rowKeys` | any[] | | 勾选行的主键;**传了就是「按勾选导出」** |
| `keyField` | string | | 配合 `rowKeys` 的主键列名 |
| `columns` | string[] | | 指定导出列(默认按模块配置) |
| `rangeStart` / `rangeEnd` | int | | 行号区间(1 起,闭区间),导出当前页/区间 |
| `volumeSize` | int | | 分卷大小;传了则返回 **zip**,按此条数分卷 |
| `withSummary` | bool | | 是否输出合计行,**默认 `true`** |
## `POST` `/export/list`
导出并直接返回文件流。
```json
{
"moduleId": "v_b_othercompany",
"searchCondition": "b_canuse = 1",
"orderBy": "b_id ASC",
"withSummary": true
}
```
**响应不是 JSON**,而是文件流,按 `Content-Type` 区分:
| 场景 | Content-Type | 说明 |
|---|---|---|
| 普通导出 | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` | 单个 xlsx |
| 分卷导出(传了 `volumeSize`) | `application/zip` | 多个 xlsx 打包 |
响应头带 `Content-Disposition: attachment; filename*=UTF-8''...`(文件名已做 URL 编码,中文名可直接还原)。
**几种请求形态的差异**:
| 形态 | 传什么 | 结果 |
|---|---|---|
| 全部导出 | 不传 `rowKeys` / 区间 | 当前条件下的**全部行**(不是当前页) |
| 勾选导出 | `rowKeys` + `keyField` | 只导出选中的行 |
| 区间导出 | `rangeStart` / `rangeEnd` | 导出指定行号区间 |
| 分卷导出 | `volumeSize` | 按条数切成多个 xlsx,打包返回 |
> `rowKeys` 里的数字主键**按原值透传**,不做字符串化——否则数字主键变成字符串后索引失效。
## `POST` `/export/count`
符合条件的行数。请求字段同上(通常只传 `moduleId` / `searchCondition`)。
```json
{
"code": 0,
"message": "操作成功",
"data": { "total": 128 }
}
```
> 因为与导出共用同一条权限链路与同一套 WHERE,这个数字**与真正导出的行数一致**——可以直接用来做「共 N 条」提示。
## `POST` `/export/totals`
各合计列的聚合值。请求字段同上。
```json
{
"code": 0,
"message": "操作成功",
"data": {
"b_amount": 123456.78,
"b_qty": 320
}
}
```
返回的键是**列名**,值是聚合结果(`sum` / `count` 等,取决于模块里该列的配置)。
> **没有配置任何合计列时返回空对象** ``,不是错误——前端据此不渲染合计行。
## 错误与权限
- **权限过滤发生在 SQL 里**:导出按 `SqlPermissionService` 的三层判定裁剪字段与数据范围。
- **字段权限**:`b_view=0` 或 `b_export=0` 的列会被**移除**(不会导出空列)。
- **数据范围**:按 `s_user_data_power` 追加条件。
- **没有导出动作权限**时拒绝:`1000`「没有模块「x」的动作权限「export」,请联系管理员授权」。
- **参数错误也在写流之前抛出**,所以失败时响应体仍是 JSON(HTTP 200 + `code != 0`),**不会返回半截损坏的 xlsx**。前端可**按 `Content-Type` 判断**拿到的是文件还是错误 JSON。
| 场景 | 表现 |
|---|---|
| 模块不存在 | `1000`,`message` 含「模块」 |
| 缺少 `moduleId` | `1000`「moduleId 不能为空」 |
| `rangeStart` 等不是整数 | `1000`「rangeStart 必须是有效整数」 |
| 无导出权限 | `1000`「没有模块「x」的动作权限「export」」 |