Files
biz-api-cloud-zax/pjcloud-common/pjcloud-common-excel/README.md
T

73 lines
3.3 KiB
Markdown

# 通用 Excel 模块
`pjcloud-common-excel` 提供 Excel 导入、普通导出以及大数据量 XLSX 分批流式导出能力。
## 分批流式导出
`BatchExcelExportTemplate` 适用于单次导出不能把全部查询结果和全部工作表行同时保留在 JVM 堆中的场景。它统一负责:
- 根据预统计数量循环分页查询;
- 使用 `SXSSFWorkbook` 把超出内存窗口的工作表行刷新到磁盘;
- 校验分页实际数量与预统计数量一致;
- 校验 Excel 2007 单工作表行数上限;
- 释放模板流、工作簿、SXSSF 临时 XML 和最终 XLSX 临时文件;
- 通过回调接入业务进度、汇总行和文件上传逻辑。
业务模块先增加公共 Excel 依赖:
```xml
<dependency>
<groupId>com.bsd</groupId>
<artifactId>pjcloud-common-excel</artifactId>
</dependency>
```
典型调用方式:
```java
String fileUrl = BatchExcelExportTemplate.<ExportRow, ExportContext, String>builder(total)
.batchSize(1000)
.dataStartRowIndex(2)
.reservedTailRowCount(1)
.temporaryFilePrefix("user-export-")
.templateSupplier(() -> ResourceUtil.getStream("file/user.xlsx"))
.templateInitializer(workbook -> prepareTemplate(workbook))
.pageFetcher((pageNumber, batchSize) -> {
Page<ExportRow> page = new Page<>(pageNumber, batchSize, false);
return userService.pageForExport(page, query).getRecords();
})
.rowWriter((sheet, rowIndex, dataIndex, item, context) ->
writeRow(sheet, rowIndex, dataIndex, item, context))
.footerWriter((sheet, rowIndex, processedTotal, context) ->
writeSummary(sheet, rowIndex, context))
.progressListener((processedTotal, expectedTotal) ->
reporter.advance("已整理 " + processedTotal + " / " + expectedTotal + " 条"))
.fileConsumer(path -> upload(Files.readAllBytes(path), fileName))
.execute();
```
## 与异步任务组合
公共 Excel 模块不依赖 `pjcloud-common-async-task`。业务层通过 `progressListener` 把每批完成事件转给
`AsyncTaskProgressReporter`,通过 `fileConsumer` 上传完整文件并返回 `AsyncTaskResult` 所需的地址。
异步任务总步数可统一计算:
```java
int progressTotal = BatchExcelExportTemplate.calculateProgressTotal(total, batchSize, 2);
reporter.updateTotal(progressTotal, "已查询 " + total + " 条数据,将分批生成文件");
```
额外的 `2` 由业务流程定义,例如文件上传一步和异步任务成功收尾一步。公共模板每完成一个查询批次只通知一次,
不会按明细行高频写 Redis。
## 调用约束
- 预统计和分页查询必须使用完全相同的筛选条件、租户上下文和数据权限。
- 分页 SQL 必须有稳定排序;排序字段存在重复值时,需要追加唯一字段,避免翻页时漏行或重复。
- 导出期间数据发生增删会触发数量不一致异常,业务方应提示用户重新导出。
- `dataStartRowIndex` 和 `reservedTailRowCount` 都按 Excel 零基行号语义配置。
- `fileConsumer` 收到的路径只在回调期间有效,不得交给其他线程延迟读取。
- 默认关闭共享字符串表以控制内存;只有确认重复文本占比高且内存可控时才启用。
- 单个工作表仍受 XLSX 的 1,048,576 行上限约束;超过上限时应按业务条件拆分文件或扩展为多工作表导出。