0.9.0: 导入导出协议改成 sheet 表(多 sheet)

export 返回 { sheet 名: 行数组 },import 收同样的形状 —— 一份负载对应一个 xlsx
工作簿。默认仍是单张表(以 moduleKey 命名),模块重写 export/import 就能自定义
多 sheet(如商品/商店/销售规则一次搬完),不必再把多张表压扁成 __t/__data 两列
塞进一个 sheet。

import 取同名 sheet、没有就退回第一张:手工在 Excel 里建的表叫 Sheet1,老版本
前端发的是裸数组,两种都不该白导。
This commit is contained in:
2026-08-21 20:05:37 +08:00
parent 355f808294
commit 6dff7b82cc
6 changed files with 126 additions and 9 deletions
+29
View File
@@ -362,6 +362,35 @@ class UserTable extends ShrimpTableModule<IUser> {
}
```
### 导入导出:多 sheet
`export`/`import` 的负载是 **`IShrimpSheets` = `{ sheet 名: 行数组 }`**,一份对应一个 xlsx 工作簿。
默认行为:导出一张以 `moduleKey` 命名的 sheet;导入取同名 sheet,没有就退回第一张(手工在 Excel 里建的表叫 `Sheet1`,也能导)。
要一个模块导出多张表(比如"商品 / 商店 / 销售规则"一次搬完),重写这两个方法就行,前端会按 key 自动建 sheet、按名字读回来:
```ts
class ShopTable extends ShrimpTableModule<IShop> {
async export(): Promise<IShrimpSheets> {
return {
goods: await GoodsDB.find().lean(),
shop: await ShopDB.find().lean(),
saleRule: await SaleRuleDB.find().lean(),
}
}
async import(data?: IShrimpSheets) {
for (const row of data?.goods ?? []) { /* 先建商品,记 oldId → newId */ }
for (const row of data?.shop ?? []) { /* 再建商店 */ }
for (const row of data?.saleRule ?? []) { /* 最后用映射还原引用 */ }
}
}
```
注意:
- sheet 名受 Excel 限制 —— 超 31 字符或含 `[]:*?/\` 会被前端替换/截断,别拿长 key 当 sheet 名。
- 单元格放不下对象/数组,前端导出时会把它们 `JSON.stringify`;导入时由字段类型的 `reqFilter`(如 `tab` 的 `parse`)还原。所以嵌套结构建议声明成有 handler 的类型,或自己在 `import` 里 parse。
- 老版本(≤ v0.8.x)的裸数组负载仍能导入,会被当成单张表。
### 字段级 reqFilter / validate
通过 `registerTypeHandler` 注册自定义 type 的处理器: