poi讀取excel有兩種模式,一種是用戶模式,一種是事件模式。用戶模式有許多封裝好的方法操作簡單,但創建太多的對象,非常耗內存。當讀取數據量太多時,就需要使用事件模式。
sax模式
excel在07版后存儲方式發生變化,因此事件模式也有兩種讀取接口。一種讀取excel03版以下;一種是excel07版以上,使用sax。
excel03版
03版使用HSSFEventFactory來處理excel,HSSFEventFactory通過RecordFactoryInputStreaml循環獲取Record.sid,將每一條送給HSSFRequest注冊的監聽器處理。用戶要處理每條記錄還需要自定義一個HSSFListener,通過實例化processRecord(Record record)接口方法處理Record.sid。關於Record.sid的類型,可以查看poi的api文檔,文檔有所有類型Record.sid的描述(這點比07版好,07版可能你還需要自己去找標簽的意義)。
1、RecordFactoryInputStreaml:將數據轉為Record.sid
2、HSSFListener:監聽獲取每條Record.sid記錄進行處理
3、HSSFRequest:注冊監聽器
HSSFEventFactory實例化代碼示例:
1 /** 2 * 初始化流監控 3 * @param in 4 */ 5 public void readExcelContent(InputStream in,int rowNum){ 6 this.rowNum = rowNum; 7 POIFSFileSystem poifs = null; 8 InputStream din = null; 9 try{ 10 poifs = new POIFSFileSystem(in); 11 din = poifs.createDocumentInputStream("Workbook"); 12 //這兒為所有類型的Record都注冊了監聽器,如果需求明確的話,可以用addListener方法,並指定所需的Record類型 13 HSSFRequest req = new HSSFRequest(); 14 //添加監聽記錄的事件 15 MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this); 16 formatListener = new FormatTrackingHSSFListener(listener); //監聽代理,方便獲取recordformat 17 req.addListenerForAllRecords(formatListener); 18 //創建時間工廠 19 HSSFEventFactory factory = new HSSFEventFactory(); 20 //處理基於時間文檔流(循環獲取每一條Record進行處理) 21 factory.processEvents(req, din); 22 }catch(Exception e){ 23 throw new RuntimeException(e); 24 }finally{ 25 //關閉基於POI文檔流 26 if (din != null) { 27 try { 28 din.close(); 29 } catch (IOException io) { 30 throw new RuntimeException(io); 31 } 32 } 33 } 34 }
excel07版
excel07版是一種基於xml讀取的發生取值,通過讀取結構化的xml數據,取得表單數據。
07是使用sax(Simple APIs for XML,也即XML簡單應用程序接口)來解析excel。SAX接口也被稱作事件驅動接口,當使用SAX分析器對XML文檔進行分析時,會觸發一系列事件,並激活相應的事件處理函數,應用程序通過這些事件處理函數實現對XML文檔的訪問。
用戶實現DefaultHandler接口,獲取excel的row和cell的值。
注:poi文檔對excel07的xml存儲標簽沒有做詳細說明,excel2007是使用xml格式來存儲的,把一個excel文件后綴改為zip,打開之后就直接可以看到excel文件對應的xml格式的文件了。
代碼示例(github):
里面封裝讀取03和07讀取工具(支持大量數據讀取)
https://github.com/L-yulong/poiexcelReader