Excel 文件内容形如下图!
需求场景
导出超10w左右的数据,涉及
- 源数据查。
- 组装业务数据
- 解析数据库中的json数据内容,并组装相应的信息
- 生成Excel文件内容到磁盘
- 将文件压缩,并写回到浏览器。触发自动下载
上线之后,功能运行正常。
问题(频繁Out of memory异常)
调查之后发现是,程序中的内存无法被GC回收。
导致内存被占用程序呈现出 ‘艰难维持’。导致导出多一些的内容,频繁触发OOM错误。
- 优化1: 数据库查询,只查询出需要的字段信息;
- 优化2: 将POI的模式切换为异步磁盘刷新模式
new SXSSFWorkbook(1024);
- 优化3: 控制只能有一个下载任务在执行
经过上述优化之后,程序运行稳定。
但仍然存在当数据越来越多时,仍然存在OOM的错误
终极优化,使用 Easy Excel
建议阅读之后,再进行下文阅读。
优点
:节约内存
避免将全部全部数据一次加载到内存
采用sax模式一行一行解析,并将一行的解析结果以
观察者的模式
通知处理。
缺点,用法削微晦涩一点
使用方式 不创建对象的写
由于Excel内容中存在动态标题列,以及大量的数据解析组装.没法定义一个较完整的实体类进行数据编写
part0 maven引用
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.8</version>
</dependency>
part1 查询数据
略
part2 生成excel文件
public class EasyExcelExportSptReportUtil {
/**
* 生成excel 文件
*
* @param taskSptReportList 数据
* @param file_base_path 文件存放基础路径
*/
public static void handelExportData(List<TaskSptReport> taskSptReportList, String file_base_path) {
if (CollectionUtils.isEmpty(taskSptReportList)) {
return;
}
String serviceTypeName = taskSptReportList.get(0).getServiceTypeName();
String serviceTypeId = taskSptReportList.get(0).getServiceTypeId();
String timeStr = DateUtils.format(new Date(System.currentTimeMillis()), DateUtils.DATE_HHMMSS);
String fileName = serviceTypeId + "_" + serviceTypeName.replaceAll("/", "_") + "-" + timeStr + ".xlsx";
String file_path = file_base_path + "/" + fileName;
createNewFile(file_path);
ExcelWriter excelWriter = EasyExcel.write(file_path).build();
HorizontalCellStyleStrategy defaultStyles = defaultStyles();
//指定单元格样式
CellColorSheetWriteHandler writeHandler = new CellColorSheetWriteHandler();
List<TaskSptReport> groupList = groupTaskSptMap.get(keyName);
String sptVersionId = keyName.split("_")[1];
String sheetName = "(" + serviceTypeId + ")" + sptVersionId;
TaskSptReport one_row = groupList.get(0);
WriteSheet writeSheet = EasyExcel.writerSheet(sheetName)
.registerWriteHandler(defaultStyles)
.registerWriteHandler(writeHandler).build();
writeSheet.setHead(head(one_row));
List<List<String>> rowDataList = convert2RowData(groupList);
excelWriter.write(rowDataList, writeSheet);
excelWriter.finish();
//3. 将多个excel 文件合并压缩成一个zip文件
//生成zip压缩文件
return;
}
/**
* 默认样式
*
* @return
*/
public static HorizontalCellStyleStrategy defaultStyles() {
//TODO 默认样式
//表头样式策略
WriteCellStyle headWriteCellStyle = new WriteCellStyle(