- 注意 数据是 从函数里面拿到,很多语言都支持 函数作为参数,java8 之后也支持
- 函数作为参数 有些不好理解,但是 很多写法 就是比较灵活了 如Scala 代码就十分优雅,鼓励用
/**
* 大数量导出
* @param fileName 生成文件地址
* @param head 表头
* @param pageSize 页大小
* @param pages 总页数
* @param function 获取数据函数
* @return
*/
public String exportBigData(String fileName, Class head, int pageSize, int pages, Function<Integer,List<?>> function) {
// 每个 sheet 数据量大小 固定最大1百万
int sheet = 1000000;
int sheetNum = sheet / pageSize;
int sheetIndex = 1;
com.alibaba.excel.ExcelWriter excelWriter = null;
try {
excelWriter = EasyExcel.write(fileName, head).build();
WriteSheet writeSheet = null;
for (int i = 1; i < pages; i++) {
writeSheet = EasyExcel.writerSheet(sheetIndex, "Sheet"+sheetIndex).build();
// 分页去数据库查询数据
List list = function.apply(i);
excelWriter.write(list, writeSheet);
if(i % sheetNum == 0){
sheetIndex++;
}
}
} finally {
// 关闭流
if (excelWriter != null) {
excelWriter.finish();
}
}
return fileName;
}
调用
1.导出过 5000w 数据 但是很耗时,数据量大了 可能出现重复数据,因为导出的时候数据可能发生变化
2.分页数据量大,多线程分页加载提高效率 可能会出现内存溢出
@Test
public void testExport() throws Exception {
long start = System.currentTimeMillis();
String fileName = "F:\\"+ "repeatedWritetest" + System.currentTimeMillis() + ".xlsx";
int pageSize = 20000;
PageHelper.startPage(1,pageSize);
List<Map> maps = testUserMapper.listData();
PageInfo pageInfo = new PageInfo<Map>(maps);
int pages = pageInfo.getPages();
// 调用
exportBigData(fileName,DemoData01.class,pageSize, pages,(i)->{
PageHelper.startPage(i,pageSize,false);
List<Map> data = testUserMapper.listData();
return getDemoData01List(maps);
});
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start)/1000 +"秒");
}
网友评论