1. 程式人生 > >POI 海量資料/大資料檔案生成SXSSFWorkbook使用簡介

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