POI 海量資料/大資料檔案生成SXSSFWorkbook使用簡介
阿新 • • 發佈:2018-12-27
在之前我們知道處理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