HSSF與XSSF導出excel文檔


Apache POI

Apache POI 是用Java編寫的免費開源的跨平台的 Java API,它可以創建和維護操作各種符合Office Open XML(OOXML)標准和微軟的OLE 2復合文檔格式(OLE2)的Java API。

用它可以使用Java讀取和創建,修改MS Excel文件.而且,還可以使用Java讀取和創建MS Word和MSPowerPoint文件。Apache POI 提供Java操作Excel解決方案(適用於Excel97-2008)。

 

HSSF and XSSF for Excel Documents

需要以下jar

<!-- office文檔組件 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlbeans</groupId>
            <artifactId>xmlbeans</artifactId>
            <version>2.4.0</version>
        </dependency>

 

 

一、HSSF:支持 excel97—2003之間的,(.xls)

注意:97—2003excel一個sheet最多65536行。

 

創建步驟:

1、New Workbook//創建一個工作簿

2、New Sheet//創建一個工作表

3、createRow//創建一個行

4、row.createCell(index)//index是指定哪一列

5、cell.setCellValue(1);//向單元格設置內容

分析:WriteExcelHSSF 的代碼

是按照上邊步驟執行,最后進行寫操作。

測試代碼:

 1 package yycg.poi;
 2 
 3 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 4 import org.apache.poi.ss.usermodel.Cell;
 5 import org.apache.poi.ss.usermodel.Row;
 6 import org.apache.poi.ss.usermodel.Sheet;
 7 import org.apache.poi.ss.usermodel.Workbook;
 8 
 9 import java.io.FileOutputStream;
10 
11 /**
12  * poi測試導出excel文件,數據量大出現內存溢出
13  */
14 public class WriteExcelHSSF {
15     public static void main(String[] args) throws Exception {
16         //創建一個文件輸出 流
17         FileOutputStream out = new FileOutputStream("d:/workbook.xls");
18         //創建一個工作薄
19         Workbook wb = new HSSFWorkbook();
20         for (int j = 0; j < 11; j++) {
21             Sheet s = wb.createSheet();//創建一個sheet
22             wb.setSheetName(j, "sheet"+j);//指定sheet的名稱
23             //xls文件最大支持65536行
24             for (int rownum = 0; rownum < 65536; rownum++) {//創建行,.xls一個sheet中的行數最大65535
25                 //創建一行
26                 Row row = s.createRow(rownum);
27                 for (int cellnum = 0; cellnum < 10; cellnum++) {//一行創建10個單元格
28                     // 在行里邊創建單元格
29                     Cell cell = row.createCell(cellnum);
30                     //向單元格寫入數據
31                     cell.setCellValue(cellnum);
32                 }
33             }
34         }
35         System.out.println("int .......");
36         wb.write(out);//輸出 文件內容
37 
38         try {
39             Thread.sleep(2000);
40         }catch (InterruptedException e){
41             e.printStackTrace();
42         }
43         out.close();
44         System.out.println("創建excel文件成功!。。。。。。。。。。。。");
45     }
46 }

 

 

通過執行大數據拋出異常:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

內存溢出

 

總結:HSSF 在使用將excel數據加載到內容再寫磁盤,如果是大數據量操作,會導致內存溢出。

 

 

二、XSSF:支持2007以上版本,Excel 2007 OOXML (.xlsx)

excel文件格式是基於是xml存儲,這是與03版本最大的區別。

XSSF對HSSF性能更好,對內存消耗不高。

 

可以解決HSSF操作大數據內存溢出問題。

 

原理:

在創建XSSFworkbook時需要設置構造函數的參數:

SXSSFWorkbook wb = new SXSSFWorkbook(-1); //設置為-1,關閉自動寫入磁盤時機,由手動進行控制

SXSSFWorkbook wb = new SXSSFWorkbook(100); //SXSSF設置100表示,只保持100個記錄在內存,超過記錄則寫入磁盤。

創建workbook的過程和HSSF一樣,先后創建workbook、sheet、row、cell

測試代碼如下:

package yycg.poi;

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.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.FileOutputStream;

public class WriterExcelXSSF1 {
    public static void main(String[] args) throws  Exception{
        //創建一個SXSSFWorkbook
        //關閉自動刷新
        SXSSFWorkbook wb = new SXSSFWorkbook(-1);
        //創建一sheet
        Sheet sheet = wb.createSheet();
        for(int rownum=0;rownum<100000;rownum++){
            //創建一個行
            Row row = sheet.createRow(rownum);
            for (int cellnum=0;cellnum<10;cellnum++){
                //創建單元格
                Cell cell = row.createCell(cellnum);
                //單元格地址
                String adress = new CellReference(cell).formatAsString();
                cell.setCellValue(adress);//向單元格中寫入數據
            }
            //手動控制行刷新到磁盤的方式
            if (rownum%10000==0){//一萬行向磁盤寫一次
                ((SXSSFSheet)sheet).flushRows(100);//保留最后100行並刷新所有其他行
                //Thread.sleep(1000);
                System.out.println("寫入....");
                // ((SXSSFSheet)sh).flushRows() is a shortcut for ((SXSSFSheet)sh).flushRows(0),
                // this method flushes all rows
            }
        }

        FileOutputStream out=new FileOutputStream("d:/testxssf.xlsx");
        wb.write(out);//將臨時文件合並,寫入最終文件
        out.close();
        wb.dispose();
    }
}

 

 

package yycg.poi;

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.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public class WriteExcelSXSSF2 {

    public static void main(String[] args) throws Throwable {
        SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory,
        // exceeding rows will be
        // flushed to disk
        Sheet sh = wb.createSheet();
        for (int rownum = 0; rownum < 1000; rownum++) {
            Row row = sh.createRow(rownum);
            for (int cellnum = 0; cellnum < 10; cellnum++) {
                Cell cell = row.createCell(cellnum);
                String address = new CellReference(cell).formatAsString();
                cell.setCellValue(address);
            }

        }

        FileOutputStream out = new FileOutputStream("d:/test2222.xlsx");
        wb.write(out);
        out.close();

        // dispose of temporary files backing this workbook on disk
        wb.dispose();
    }

}

 

 

通過跟蹤發現,使用XSSF在導出大數據時,手動控制進行寫磁盤,寫在了臨時文件中,我的電腦是:

(C:\Users\Thinkpad\AppData\Local\Temp\poi-sxssf-sheet1910970138657434208.xml 該目錄有很多臨時文件)

 

最終待導出完成將臨時合並成最終文件寫入磁盤。

 

總結:使用XSSF導出數據,將數據寫入內存一部分,超過的則立即寫磁盤,所以內存占有量有限不會導致內存溢出。

 


免責聲明!

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



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