在之前我們知道處理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
