遇到的问题
1.list集合太大,触发oom
2.导出excel数据量太大内存占满,没输出到硬盘前已经出发oom
接下来尝试用poi解决
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.10-FINAL</version>
</dependency>
一开始用XSSFWorkbook
rows参数是传进来的总条数,col是输出的总列数
public static void XSSFWorkbook(int rows, int col) throws Exception {
long start = System.currentTimeMillis();
XSSFWorkbook workbook1 = new XSSFWorkbook();
Sheet first = workbook1.createSheet("sheet1");
for (int i = 0; i < rows; i++) {
Row row = first.createRow(i);
for (int j = 0; j < col; j++) {
if(i == 0) {
// 首行
row.createCell(j).setCellValue("column" + j);
} else {
// 数据
if (j == 0) {
CellUtil.createCell(row, j, String.valueOf(i));
} else
CellUtil.createCell(row, j, String.valueOf(Math.random()));
}
}
}
FileOutputStream out = new FileOutputStream("E:/XSSFWorkbookworkbook.xlsx");
workbook1.write(out);
out.close();
System.out.println(("XSSFWorkbook "+(System.currentTimeMillis()-start)/1000));
}
导致触发GC
原因是excel文档的数据都存在内存中,当一直望excel填充数据,那么就越大,内存就扛不住
去poi官网看到
再次回到POI的官网。http://poi.apache.org/spreadsheet/index.html
官方提到自POI3.8版本开始提供了一种SXSSF的方式,用于超大数据量的操作。于是…
原文:
SXSSF is an API-compatible streaming extension of XSSF to be used when very large spreadsheets have to be produced…
POI类库实现了相对高效的批量写入类SXSSFWorkbook
于是尝试了
public static void SXSSFWorkbook(int rows, int col) throws Exception {
long start = System.currentTimeMillis();
XSSFWorkbook workbook1 = new XSSFWorkbook();
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(workbook1, 100);
Sheet first = sxssfWorkbook.createSheet("sheet1");
for (int i = 0; i < rows; i++) {
Row row = first.createRow(i);
for (int j = 0; j < col; j++) {
if(i == 0) {
// 首行
row.createCell(j).setCellValue("column" + j);
} else {
// 数据
if (j == 0) {
CellUtil.createCell(row, j, String.valueOf(i));
} else
CellUtil.createCell(row, j, String.valueOf(Math.random()));
}
}
}
FileOutputStream out = new FileOutputStream("E:/SXSSFWorkbookworkbook.xlsx");
sxssfWorkbook.write(out);
out.close();
System.out.println(("SXSSFWorkbook "+(System.currentTimeMillis()-start)/1000));
}
看到数据的瞬间感觉,哇塞。好给力的说。居然从将近50秒缩短带11秒。。。
为什么都是代码差距就这么大呢?
原来,SXSSF实现了一套自动刷入数据的机制。当数据数量达到一定程度时(用户可以自己设置这个限制)。像文本中刷入部分数据输出到硬盘中。这样就缓解了程序运行时候内存的压力。达到高效的目的。
原理:用硬盘换内存
当然也有现成的工具类hutool的BigExcelWriter
查看源码只是在poi的基础上封装了一层