问题
后端列表导出能力不满足实际需求:
- 不支持 Excel(XLSX)。现有
GET /api/v1/data/:object/export(packages/rest/src/rest-server.ts)只支持 csv / json 两种格式。
- 导出的是原始值,不可读。
rowsToCsv 直接写 row[field],formatCsvCell 只做 Date→ISO 转义,导致:
- lookup / user 类型导出的是 id,而不是名称
- select 类型导出的是 code/value,而不是 label
- boolean 导出的是
true/false,而不是「是/否」
- date/datetime 导出的是 ISO 串,未格式化
- 业务需要导出约 2 万行数据,必须服务端流式处理(客户端方案扛不住)。
权限方面现状已正确:导出走 findData(context),SecurityPlugin 自动施加对象级 / 字段级屏蔽 / 行级 RLS,本 issue 不改权限。
方案(仅改 packages/rest)
- 新增 xlsx 格式:导出路由
format 增加 xlsx,用 exceljs 的流式 WorkbookWriter 写入 response stream(不全量进内存,支撑 2 万行);packages/rest/package.json 新增 exceljs 依赖。
- 新增类型感知格式化(新文件
packages/rest/src/export-format.ts):依据对象 schema 字段类型,把原始值转成显示值——
- lookup / user:对字段自动加
$expand,从展开的嵌套记录取 displayField / 被引用对象 nameField(缺失时回退 name/title/id)
- select:用字段
options 把 value 映射成 label
- boolean:
是 / 否
- date / datetime:格式化
- csv / json / xlsx 三种输出统一过此格式化层
- 导出查询对 lookup / user 字段自动注入
$expand,让名称随行返回(批量 $in,深度上限 3,无 N+1)。
范围
- 本 issue 只覆盖 framework 后端(
packages/rest)。
- 前端
@object-ui/data-objectstack 适配器接入同步流式下载 + ListView 改造,另在 objectui 仓库跟进。
验收
GET /api/v1/data/:object/export?format=xlsx 返回合法 xlsx,2 万行流式不 OOM。
- lookup/user 出名称、select 出 label、boolean 出是/否、date 已格式化。
- 现有 csv/json 行为不回退;权限(对象/字段/行级)仍由 findData 自动保证。
问题
后端列表导出能力不满足实际需求:
GET /api/v1/data/:object/export(packages/rest/src/rest-server.ts)只支持csv/json两种格式。rowsToCsv直接写row[field],formatCsvCell只做 Date→ISO 转义,导致:true/false,而不是「是/否」权限方面现状已正确:导出走
findData(context),SecurityPlugin 自动施加对象级 / 字段级屏蔽 / 行级 RLS,本 issue 不改权限。方案(仅改
packages/rest)format增加xlsx,用exceljs的流式WorkbookWriter写入 response stream(不全量进内存,支撑 2 万行);packages/rest/package.json新增exceljs依赖。packages/rest/src/export-format.ts):依据对象 schema 字段类型,把原始值转成显示值——$expand,从展开的嵌套记录取displayField/ 被引用对象nameField(缺失时回退 name/title/id)options把 value 映射成 label是/否$expand,让名称随行返回(批量$in,深度上限 3,无 N+1)。范围
packages/rest)。@object-ui/data-objectstack适配器接入同步流式下载 + ListView 改造,另在 objectui 仓库跟进。验收
GET /api/v1/data/:object/export?format=xlsx返回合法 xlsx,2 万行流式不 OOM。