POI 海量数据/大数据文件生成SXSSFWorkbook使用简介
在之前我们知道处理xls的excel用的workbook是HSSFWorkbook,处理xlsx的excel用的是XSSFWorkbook。
上面两个类导出excel的时候数据会驻留在内存中,所以当数据量大的时候容易造成内存溢出。SXSSFWorkbook是用来生成海量excel数据文件,主要原理是借助临时存储空间生成excel。POI要求3.8以上,生成的文件格式要求是07及以上版本,因为excel07级以上版本的行数1048576,量很大,而03版本的只有6万多。
读取07及以上版本的excel仍然是“XSSFWorkbook”,写入则为“SXSSFWorkbook ”。
导出的代码:(一个简单的测试,如果想封装工具类,参考:https://www.cnblogs.com/qlqwjy/p/9974212.html)
package cn.xm.exam.utils; import java.io.File; import java.io.FileOutputStream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; public class SXSSFExcelUtil { public static void main(String[] args) { String[] title = { "id", "name", "sex" }; // 创建一个工作簿 Workbook workbook = new SXSSFWorkbook(); // 创建一个工作表sheet Sheet sheet = workbook.createSheet(); // 创建第一行 Row row = sheet.createRow(0); // 创建一个单元格 Cell cell = null; // 创建表头 for (int i = 0; i < title.length; i++) { cell = row.createCell(i); cell.setCellValue(title[i]); } // 从第二行开始追加数据 for (int i = 1; i <= 10000; i++) { // 创建第i行 Row nextRow = sheet.createRow(i); // 参数代表第几列 Cell cell2 = nextRow.createCell(0); cell2.setCellValue("a" + i); cell2 = nextRow.createCell(1); cell2.setCellValue("user" + i); cell2 = nextRow.createCell(2); cell2.setCellValue("男"); } // 创建一个文件 File file = new File("G:/tt1.xls"); try { file.createNewFile(); // 打开文件流 FileOutputStream outputStream = new FileOutputStream(file); workbook.write(outputStream); outputStream.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
补充:SXFFSWoorkbook导出的excel相比于XSSFWoorkbook导出的更节省空间:
下面分别是SXXFS\XFFS\HFFS导出上面1万条数据的excel的文件大小:
补充:测试HSSF\XSSF导出的数据占用内存,而SXFFS导出的数据不容易造成内存溢出
数据改为5万条并且写入之后查看内存信息:
(1)查看XSSF导出的时候占用JVM内存
package cn.xm.exam.utils; import java.io.File; import java.io.FileOutputStream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class SXSSFExcelUtil { public static void main(String[] args) { String[] title = { "id", "name", "sex" }; // 创建一个工作簿 Workbook workbook = new XSSFWorkbook(); // 创建一个工作表sheet Sheet sheet = workbook.createSheet(); // 创建第一行 Row row = sheet.createRow(0); // 创建一个单元格 Cell cell = null; // 创建表头 for (int i = 0; i < title.length; i++) { cell = row.createCell(i); cell.setCellValue(title[i]); } // 从第二行开始追加数据 for (int i = 1; i <= 50000; i++) { // 创建第i行 Row nextRow = sheet.createRow(i); // 参数代表第几列 Cell cell2 = nextRow.createCell(0); cell2.setCellValue("a" + i); cell2 = nextRow.createCell(1); cell2.setCellValue("user" + i); cell2 = nextRow.createCell(2); cell2.setCellValue("男"); } // 创建一个文件 File file = new File("G:/tt1.xls"); try { file.createNewFile(); // 打开文件流 FileOutputStream outputStream = new FileOutputStream(file); workbook.write(outputStream); outputStream.close(); // dispose of temporary files backing this workbook on disk // ((SXSSFWorkbook) workbook).dispose(); System.out.println("创建完成"); System.out.println("总的内存->" + Runtime.getRuntime().totalMemory() / 1024 / 1024 + "MB"); System.out.println("剩余的内存->" + Runtime.getRuntime().freeMemory() / 1024 / 1024 + "MB"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
结果:
创建完成
总的内存->883MB
剩余的内存->550MB
(2)查看SXSSF导出的时候占用JVM内存
将上面XSSF改为SXFFS查看结果:
创建完成
总的内存->182MB
剩余的内存->175MB
【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】