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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM