一、问题的提出
/**
* 大数据导出1.0
* /demo/exportExcel4
* @param response
*/
@GetMapping("/exportExcel4")
public void exportExcel4(HttpServletResponse response) throws IOException {
Date start = new Date();
// 模拟数据
List users = new ArrayList<>();
for (int i = 0; i < 1000000; i++) { //一百万数据量
users.add(new UserExportVO("test-"+i,1,new
Date(),"18688888888","abc"+i+"@qq.com",null,"xxxx"));
}
ExcelUtil.exportExcelX(users, "测试导出表", "sheet1", UserExportVO.class, "测试导出表.xlsx", response);
System.out.println("耗时:"+(new Date().getTime() - start.getTime())/1000+"秒");
}
导出耗时:115秒,导出文件大小:157M。
二、大数据导出
导出是能够与导出了,但是耗时太长了,有办法减半吗?导出文件大小太大了,能办法减半吗?
大数据导出是当我们的导出数量在几万,到上百万的数据时,一次从数据库查询这么多数据加载到内存然后写入会对我们的内存和CPU都产生压力,这个时候需要我们像分页一样处理导出分段写入Excel缓解Excel的压力。
大数据导出主要是使用到了ExcelExportUtil.exportBigExcel的方法:
/**
* 大数据导出2.0
* /demo/exportExcel5
* @param response
*/
@GetMapping("/exportExcel5")
public void exportExcel5(HttpServletResponse response) throws IOException {
Date start = new Date();
Workbook workbook = null;
ExportParams params = new ExportParams("大数据测试", "测试");workbook =
ExcelExportUtil.exportBigExcel(params, UserExportVO.class, new IExcelExportServer() {
@Override
public List
难点就是接口IExcelExportServer的实现,底层会进行page++,不断的查找下一页,所以这里一定要有一段结束这个循环的逻辑。在实际项目中,更多的是查询的list的size()==0了。
导出的文件的大小,从原来的157M,变为了28M,少了6倍左右。
当然这个第一次的导出方式,文件的大小,也和导出的配置有关系,在之前为了解决图片导出问题,设置了为ExcelType.HSSF。
如果设置为ExcelType.XSSF的格式直接就OutOfMemoryError: GC overhead limit exceeded了(这种情况发生的原因是,程序基本上耗尽了所有的可用内存, GC也清理不了)。
总结
对于大数据的导出,核心要注意的就是内存溢出了。
(1)100万的数据,使用ExcelType.XSSF的方式导出,会报错:OutOfMemoryError: GC overhead limit exceeded。
(2)100万的数据,使用ExcelType. HSSF的方式导出,能导出,耗时115秒左右,导出的文件大小157M左右。
(3)大数据的导出方式,能导出,耗时60秒左右,导出的文件大小28M左右。