1. 程式人生 > >POI SAX 使用事件驅動解析Excel(03/07)

POI SAX 使用事件驅動解析Excel(03/07)

本文主要是用於POI解析大檔案Excel容易出現記憶體溢位的現象而提出解決方案,故此解決了大資料量的Excel檔案解析的難度,在此拿出來貢獻給大家,謝謝!

裡面用到的相關類請檢視:   http://www.cnblogs.com/wshsdlau/p/5643862.html

1. Office2007與Office Open XML

    在Office 2007之前,Office一直都是以二進位制位的方式儲存,但這種格式不易被其它軟體拿來使用,在各界的壓力下,MicroSoft於2005年釋出了基於XML的ooxml開放文件標準。ooxml的xml schema強調減少load time,增快parsing speed,將child elements分開儲存,而不是multiple attributes一起存,這有點類似於HTML的結構。ooxml 使用XML和ZIP技術結合進行檔案儲存,因為XML是一個基於文字的格式,而且ZIP容器支援內容的壓縮,所以其一大優勢就是可以大大減小檔案的尺寸。其它特點這裡不再敘述。

2. SAX方式解析XML

    SAX全稱Simple API for XML,它是一個介面,也是一個軟體包。它是一種XML解析的替代方法,不同於DOM解析XML文件時把所有內容一次性載入到記憶體中的方式,它逐行掃描文件,一邊掃描,一邊解析。所以那些只需要單遍讀取內容的應用程式就可以從SAX解析中受益,這對大型文件的解析是個巨大優勢。另外,SAX “推" 模型可用於廣播環境,能夠同時註冊多個ContentHandler,並行接收事件,而不是在一個管道中一個接一個地進行處理。一些支援 SAX 的語法分析器包括 Xerces,Apache parser(以前的 IBM 語法分析器)、MSXML(Microsoft 語法分析器)和 XDK(Oracle 語法分析器)。這些語法分析器是最靈活的,因為它們還支援 DOM。

3. POI以SAX解析excel2007檔案

   所需jar包:poi-3.10-FINAL-20140208.jar,poi-ooxml-3.10-FINAL-20140208.jar, poi-ooxml-schemas-3.10-FINAL-20140208.jar

      xercesImpl.jar      xml-apis-2.0.2.jar      xmlbeans-2.6.0.jar     sax2.jar

輔助類

ExcelReaderUtil:

[java] view plain copy print?
  1. package com.boguan.bte.util.excel;  
  2. import com.boguan.bte.service.common.IExcelRowReader;  
  3. import com.boguan.bte.service.common.impl.ExcelRowReader;  
  4. /** 
  5.  * 名稱: ExcelReaderUtil.java<br> 
  6.  * 描述: <br> 
  7.  * 型別: JAVA<br> 
  8.  * 最近修改時間:2016年7月5日 上午10:10:20<br> 
  9.  *  
  10.  * @since 2016年7月5日 
  11.  * @author “” 
  12.  */
  13. publicclass ExcelReaderUtil {  
  14.     // excel2003副檔名
  15.     publicstaticfinal String EXCEL03_EXTENSION = ".xls";  
  16.     // excel2007副檔名
  17.     publicstaticfinal String EXCEL07_EXTENSION = ".xlsx";  
  18.     /** 
  19.      * 讀取Excel檔案,可能是03也可能是07版本 
  20.      *  
  21.      * @param excel03 
  22.      * @param excel07 
  23.      * @param fileName 
  24.      * @throws Exception 
  25.      */
  26.     publicstaticvoid readExcel(IExcelRowReader reader, String fileName) throws Exception {  
  27.         // 處理excel2003檔案
  28.         if (fileName.endsWith(EXCEL03_EXTENSION)) {  
  29.             ExcelXlsReader exceXls = new ExcelXlsReader();  
  30.             exceXls.setRowReader(reader);   
  31.             exceXls.process(fileName);  
  32.             // 處理excel2007檔案
  33.         } elseif (fileName.endsWith(EXCEL07_EXTENSION)) {  
  34.             ExcelXlsxReader exceXlsx = new ExcelXlsxReader();  
  35.             exceXlsx.setRowReader(reader);   
  36.             exceXlsx.process(fileName);  
  37.         } else {  
  38.             thrownew Exception("檔案格式錯誤,fileName的副檔名只能是xls或xlsx。");  
  39.         }  
  40.     }  
  41.     /** 
  42.      * 測試 
  43.      * @param args 
  44.      * @throws Exception 
  45.      */
  46.     publicstaticvoid main(String[] args) throws Exception {  
  47.         IExcelRowReader rowReader = new ExcelRowReader();  
  48.         ExcelReaderUtil.readExcel(rowReader, "E://test.xls");  
  49.     }  
  50. }  
package com.boguan.bte.util.excel;

import com.boguan.bte.service.common.IExcelRowReader;
import com.boguan.bte.service.common.impl.ExcelRowReader;

/**
 * 名稱: ExcelReaderUtil.java<br>
 * 描述: <br>
 * 型別: JAVA<br>
 * 最近修改時間:2016年7月5日 上午10:10:20<br>
 * 
 * @since 2016年7月5日
 * @author “”
 */
public class ExcelReaderUtil {
    // excel2003副檔名
    public static final String EXCEL03_EXTENSION = ".xls";
    // excel2007副檔名
    public static final String EXCEL07_EXTENSION = ".xlsx";

    /**
     * 讀取Excel檔案,可能是03也可能是07版本
     * 
     * @param excel03
     * @param excel07
     * @param fileName
     * @throws Exception
     */
    public static void readExcel(IExcelRowReader reader, String fileName) throws Exception {
        // 處理excel2003檔案
        if (fileName.endsWith(EXCEL03_EXTENSION)) {
            ExcelXlsReader exceXls = new ExcelXlsReader();
            exceXls.setRowReader(reader); 
            exceXls.process(fileName);
            // 處理excel2007檔案
        } else if (fileName.endsWith(EXCEL07_EXTENSION)) {
            ExcelXlsxReader exceXlsx = new ExcelXlsxReader();
            exceXlsx.setRowReader(reader); 
            exceXlsx.process(fileName);
        } else {
            throw new Exception("檔案格式錯誤,fileName的副檔名只能是xls或xlsx。");
        }
    }

    /**
     * 測試
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        IExcelRowReader rowReader = new ExcelRowReader();
        ExcelReaderUtil.readExcel(rowReader, "E://test.xls");
    }
}


[java] view plain copy print?
  1. package com.boguan.bte.service.common;  
  2. import java.util.List;  
  3. /** 
  4.  * 名稱: IRowReader.java<br> 
  5.  * 描述: <br> 
  6.  * 型別: JAVA<br> 
  7.  * 最近修改時間:2016年7月5日 上午10:28:06<br> 
  8.  *  
  9.  * @since 2016年7月5日 
  10.  * @author “” 
  11.  */
  12. publicinterface IExcelRowReader {  
  13.     /** 
  14.      * 業務邏輯實現方法 
  15.      *  
  16.      * @param sheetIndex 
  17.      * @param curRow 
  18.      * @param rowlist 
  19.      */
  20.     void getRows(int sheetIndex, int curRow, List<String> rowlist);  
  21. }  
package com.boguan.bte.service.common;

import java.util.List;

/**
 * 名稱: IRowReader.java<br>
 * 描述: <br>
 * 型別: JAVA<br>
 * 最近修改時間:2016年7月5日 上午10:28:06<br>
 * 
 * @since 2016年7月5日
 * @author “”
 */
public interface IExcelRowReader {
    /**
     * 業務邏輯實現方法
     * 
     * @param sheetIndex
     * @param curRow
     * @param rowlist
     */
    void getRows(int sheetIndex, int curRow, List<String> rowlist);
}

[java] view plain copy print?
  1. package com.boguan.bte.service.common.impl;  
  2. import java.util.List;  
  3. import com.boguan.bte.service.common.IExcelRowReader;  
  4. /** 
  5.  * 名稱: ExcelRowReader.java<br> 
  6.  * 描述: <br> 
  7.  * 型別: JAVA<br> 
  8.  * 最近修改時間:2016年7月5日 上午10:30:11<br> 
  9.  *  
  10.  * @since 2016年7月5日 
  11.  * @author “” 
  12.  */
  13. publicclass ExcelRowReader implements IExcelRowReader {  
  14.     @Override
  15.     publicvoid getRows(int sheetIndex, int curRow, List<String> rowlist) {  
  16.         System.out.print(curRow+" ");    
  17.         for (int i = 0; i < rowlist.size(); i++) {    
  18.             System.out.print(rowlist.get(i)==""?"*":rowlist.get(i) + " ");    
  19.         }    
  20.         System.out.println();    
  21.     }  
  22. }  
package com.boguan.bte.service.common.impl;

import java.util.List;

import com.boguan.bte.service.common.IExcelRowReader;

/**
 * 名稱: ExcelRowReader.java<br>
 * 描述: <br>
 * 型別: JAVA<br>
 * 最近修改時間:2016年7月5日 上午10:30:11<br>
 * 
 * @since 2016年7月5日
 * @author “”
 */
public class ExcelRowReader implements IExcelRowReader {

    @Override
    public void getRows(int sheetIndex, int curRow, List<String> rowlist) {
        System.out.print(curRow+" ");  
        for (int i = 0; i < rowlist.size(); i++) {  
            System.out.print(rowlist.get(i)==""?"*":rowlist.get(i) + " ");  
        }  
        System.out.println();  
    }
    
}

03 Reader:

[java] view plain copy print?
  1. package com.boguan.bte.util.excel;  
  2. import java.io.FileInputStream;  
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6. import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;  
  7. import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;  
  8. import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;  
  9. import org.apache.poi.hssf.eventusermodel.HSSFListener;  
  10. import org.apache.poi.hssf.eventusermodel.HSSFRequest;  
  11. import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;  
  12. import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;  
  13. import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;  
  14. import org.apache.poi.hssf.model.HSSFFormulaParser;  
  15. import org.apache.poi.hssf.record.BOFRecord;  
  16. import org.apache.poi.hssf.record.BlankRecord;  
  17. import org.apache.poi.hssf.record.BoolErrRecord;  
  18. import org.apache.poi.hssf.record.BoundSheetRecord;  
  19. import org.apache.poi.hssf.record.FormulaRecord;  
  20. import org.apache.poi.hssf.record.LabelRecord;  
  21. import org.apache.poi.hssf.record.LabelSSTRecord;  
  22. import org.apache.poi.hssf.record.NumberRecord;  
  23. import org.apache.poi.hssf.record.Record;  
  24. import org.apache.poi.hssf.record.SSTRecord;  
  25. import org.apache.poi.hssf.record.StringRecord;  
  26. import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  27. import org.apache.poi.poifs.filesystem.POIFSFileSystem;  
  28. import com.boguan.bte.service.common.IExcelRowReader;  
  29. /** 
  30.  * 名稱: ExcelXlsReader.java<br> 
  31.  * 描述: <br> 
  32.  * 型別: JAVA<br> 
  33.  * 最近修改時間:2016年7月5日 上午10:00:32<br> 
  34.  *  
  35.  * @since 2016年7月5日 
  36.  * @author “” 
  37.  */
  38. publicclass ExcelXlsReader implements HSSFListener {  
  39.     privateint minColumns = -1;  
  40.     private POIFSFileSystem fs;  
  41.     privateint lastRowNumber;  
  42.     privateint lastColumnNumber;  
  43.     /** Should we output the formula, or the value it has? */
  44.     privateboolean outputFormulaValues = true;  
  45.     /** For parsing Formulas */
  46.     private SheetRecordCollectingListener workbookBuildingListener;  
  47.     // excel2003工作薄
  48.     private HSSFWorkbook stubWorkbook;  
  49.     // Records we pick up as we process
  50.     private SSTRecord sstRecord;  
  51.     private FormatTrackingHSSFListener formatListener;  
  52.     // 表索引
  53.     privateint sheetIndex = -1;  
  54.     private BoundSheetRecord[] orderedBSRs;  
  55.     @SuppressWarnings("unchecked")  
  56.     private ArrayList boundSheetRecords = new ArrayList();  
  57.     // For handling formulas with string results
  58.     privateint nextRow;  
  59.     privateint nextColumn;  
  60.     privateboolean outputNextStringRecord;  
  61.     // 當前行
  62.     privateint curRow = 0;  
  63.     // 儲存行記錄的容器
  64.     private List<String> rowlist = new ArrayList<String>();;  
  65.     @SuppressWarnings("unused")  
  66.     private String sheetName;  
  67.     private IExcelRowReader rowReader;  
  68.     publicvoid setRowReader(IExcelRowReader rowReader) {  
  69.         this.rowReader = rowReader;  
  70.     }  
  71.     /** 
  72.      * 遍歷excel下所有的sheet 
  73.      *  
  74.      * @throws IOException 
  75.      */
  76.     publicvoid process(String fileName) throws IOException {  
  77.         this.fs = new POIFSFileSystem(new FileInputStream(fileName));  
  78.         MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);  
  79.         formatListener = new FormatTrackingHSSFListener(listener);  
  80.         HSSFEventFactory factory = new HSSFEventFactory();  
  81.         HSSFRequest request = new HSSFRequest();  
  82.         if (outputFormulaValues) {  
  83.             request.addListenerForAllRecords(formatListener);  
  84.         } else {  
  85.             workbookBuildingListener = new SheetRecordCollectingListener(formatListener);  
  86.             request.addListenerForAllRecords(workbookBuildingListener);  
  87.         }  
  88.         factory.processWorkbookEvents(request, fs);  
  89.     }  
  90.     /** 
  91.      * HSSFListener 監聽方法,處理 Record 
  92.      */
  93.     @SuppressWarnings("unchecked")  
  94.     publicvoid processRecord(Record record) {  
  95.         int thisRow = -1;  
  96.         int thisColumn = -1;  
  97.         String thisStr = null;  
  98.         String value = null;  
  99.         switch (record.getSid()) {  
  100.         case BoundSheetRecord.sid:  
  101.             boundSheetRecords.add(record);  
  102.             break;  
  103.         case BOFRecord.sid:  
  104.             BOFRecord br = (BOFRecord) record;  
  105.             if (br.getType() == BOFRecord.TYPE_WORKSHEET) {  
  106.                 // 如果有需要,則建立子工作薄
  107.                 if (workbookBuildingListener != null && stubWorkbook == null) {  
  108.                     stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();  
  109.                 }  
  110.                 sheetIndex++;  
  111.                 if (orderedBSRs == null) {  
  112.                     orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);  
  113.                 }  
  114.                 sheetName = orderedBSRs[sheetIndex].getSheetname();  
  115.             }  
  116.             break;  
  117.         case SSTRecord.sid:  
  118.             sstRecord = (SSTRecord) record;  
  119.             break;  
  120.         case BlankRecord.sid:  
  121.             BlankRecord brec = (BlankRecord) record;  
  122.             thisRow = brec.getRow();  
  123.             thisColumn = brec.getColumn();  
  124.             thisStr = "";  
  125.             rowlist.add(thisColumn, thisStr);  
  126.             break;  
  127.         case BoolErrRecord.sid: // 單元格為布林型別
  128.             BoolErrRecord berec = (BoolErrRecord) record;  
  129.             thisRow = berec.getRow();  
  130.             thisColumn = berec.getColumn();  
  131.             thisStr = berec.getBooleanValue() + "";  
  132.             rowlist.add(thisColumn, thisStr);  
  133.             break;  
  134.         case FormulaRecord.sid: // 單元格為公式型別
  135.             FormulaRecord frec = (FormulaRecord) record;  
  136.             thisRow = frec.getRow();  
  137.             thisColumn = frec.getColumn();  
  138.             if (outputFormulaValues) {  
  139.                 if (Double.isNaN(frec.getValue())) {  
  140.                     // Formula result is a string
  141.                     // This is stored in the next record
  142.                     outputNextStringRecord = true;  
  143.                     nextRow = frec.getRow();  
  144.                     nextColumn = frec.getColumn();  
  145.                 } else {  
  146.                     thisStr = formatListener.formatNumberDateCell(frec);  
  147.                 }  
  148.             } else {  
  149.                 thisStr = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"';  
  150.             }  
  151.             rowlist.add(thisColumn, thisStr);  
  152.             break;  
  153.         case StringRecord.sid:// 單元格中公式的字串
  154.             if (outputNextStringRecord) {  
  155.                 // String for formula
  156.                 StringRecord srec = (StringRecord) record;  
  157.                 thisStr = srec.getString();  
  158.                 thisRow = nextRow;  
  159.                 thisColumn = nextColumn;  
  160.                 outputNextStringRecord = false;  
  161.             }  
  162.             break;  
  163.         case LabelRecord.sid:  
  164.             LabelRecord lrec = (LabelRecord) record;  
  165.             curRow = thisRow = lrec.getRow();  
  166.             thisColumn = lrec.getColumn();  
  167.             value = lrec.getValue().trim();  
  168.             value = value.equals("") ? " " : value;  
  169.             this.rowlist.add(thisColumn, value);  
  170.             break;  
  171.         case LabelSSTRecord.sid: // 單元格為字串型別
  172.             LabelSSTRecord lsrec = (LabelSSTRecord) record;  
  173.             curRow = thisRow = lsrec.getRow();  
  174.             thisColumn = lsrec.getColumn();  
  175.             if (sstRecord == null) {  
  176.                 rowlist.add(thisColumn, " ");  
  177.             } else {  
  178.                 value = sstRecord.getString(lsrec.getSSTIndex()).toString().trim();  
  179.                 value = value.equals("") ? " " : value;  
  180.                 rowlist.add(thisColumn, value);  
  181.             }  
  182.             break;  
  183.         case NumberRecord.sid: // 單元格為數字型別
  184.             NumberRecord numrec = (NumberRecord) record;  
  185.             curRow = thisRow = numrec.getRow();  
  186.             thisColumn = numrec.getColumn();  
  187.             value = formatListener.formatNumberDateCell(numrec).trim();  
  188.             value = value.equals("") ? " " : value;  
  189.             // 向容器加入列值
  190.             rowlist.add(thisColumn, value);  
  191.             break;  
  192.         default:  
  193.             break;  
  194.         }  
  195.         // 遇到新行的操作
  196.         if (thisRow != -1 && thisRow != lastRowNumber) {  
  197.             lastColumnNumber = -1;  
  198.         }  
  199.         // 空值的操作
  200.         if (record instanceof MissingCellDummyRecord) {  
  201.             MissingCellDummyRecord mc = (MissingCellDummyRecord) record;  
  202.             curRow = thisRow = mc.getRow();  
  203.             thisColumn = mc.getColumn();  
  204.             rowlist.add(thisColumn, " ");  
  205.         }  
  206.         // 更新行和列的值
  207.         if (thisRow > -1)  
  208.             lastRowNumber = thisRow;  
  209.         if (thisColumn > -1)  
  210.             lastColumnNumber = thisColumn;  
  211.         // 行結束時的操作
  212.         if (record instanceof LastCellOfRowDummyRecord) {  
  213.             if (minColumns > 0) {  
  214.                 // 列值重新置空
  215.                 if (lastColumnNumber == -1) {  
  216.                     lastColumnNumber = 0;  
  217.                 }  
  218.             }  
  219.             lastColumnNumber = -1;  
  220.             // 每行結束時, 呼叫getRows() 方法
  221.             rowReader.getRows(sheetIndex, curRow, rowlist);  
  222.             // 清空容器
  223.             rowlist.clear();  
  224.         }  
  225.     }  
  226.       publicstaticvoid main(String[] args) {  
  227.        IExcelRowReader rowReader = new ExcelRowReader();  
  228.       try {  
  229.           // ExcelReaderUtil.readExcel(rowReader,
  230.           // "E://2016-07-04-011940a.xls");
  231.             System.out.println("**********************************************");  
  232.             ExcelReaderUtil.readExcel(rowReader, "E://test.xlsx");  
  233.             } catch (Exception e) {  
  234.             e.printStackTrace();  
  235.            }  
  236.        }  
  237. }  
package com.boguan.bte.util.excel;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import com.boguan.bte.service.common.IExcelRowReader;

/**
 * 名稱: ExcelXlsReader.java<br>
 * 描述: <br>
 * 型別: JAVA<br>
 * 最近修改時間:2016年7月5日 上午10:00:32<br>
 * 
 * @since 2016年7月5日
 * @author “”
 */
public class ExcelXlsReader implements HSSFListener {

    private int minColumns = -1;

    private POIFSFileSystem fs;

    private int lastRowNumber;

    private int lastColumnNumber;

    /** Should we output the formula, or the value it has? */
    private boolean outputFormulaValues = true;

    /** For parsing Formulas */
    private SheetRecordCollectingListener workbookBuildingListener;

    // excel2003工作薄
    private HSSFWorkbook stubWorkbook;

    // Records we pick up as we process
    private SSTRecord sstRecord;

    private FormatTrackingHSSFListener formatListener;

    // 表索引
    private int sheetIndex = -1;

    private BoundSheetRecord[] orderedBSRs;

    @SuppressWarnings("unchecked")
    private ArrayList boundSheetRecords = new ArrayList();

    // For handling formulas with string results
    private int nextRow;

    private int nextColumn;

    private boolean outputNextStringRecord;

    // 當前行
    private int curRow = 0;

    // 儲存行記錄的容器
    private List<String> rowlist = new ArrayList<String>();;

    @SuppressWarnings("unused")
    private String sheetName;

    private IExcelRowReader rowReader;

    public void setRowReader(IExcelRowReader rowReader) {
        this.rowReader = rowReader;
    }

    /**
     * 遍歷excel下所有的sheet
     * 
     * @throws IOException
     */
    public void process(String fileName) throws IOException {
        this.fs = new POIFSFileSystem(new FileInputStream(fileName));
        MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
        formatListener = new FormatTrackingHSSFListener(listener);
        HSSFEventFactory factory = new HSSFEventFactory();
        HSSFRequest request = new HSSFRequest();
        if (outputFormulaValues) {
            request.addListenerForAllRecords(formatListener);
        } else {
            workbookBuildingListener = new SheetRecordCollectingListener(formatListener);
            request.addListenerForAllRecords(workbookBuildingListener);
        }
        factory.processWorkbookEvents(request, fs);
    }

    /**
     * HSSFListener 監聽方法,處理 Record
     */
    @SuppressWarnings("unchecked")
    public void processRecord(Record record) {
        int thisRow = -1;
        int thisColumn = -1;
        String thisStr = null;
        String value = null;
        switch (record.getSid()) {
        case BoundSheetRecord.sid:
            boundSheetRecords.add(record);
            break;
        case BOFRecord.sid:
            BOFRecord br = (BOFRecord) record;
            if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
                // 如果有需要,則建立子工作薄
                if (workbookBuildingListener != null && stubWorkbook == null) {
                    stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
                }

                sheetIndex++;
                if (orderedBSRs == null) {
                    orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
                }
                sheetName = orderedBSRs[sheetIndex].getSheetname();
            }
            break;

        case SSTRecord.sid:
            sstRecord = (SSTRecord) record;
            break;

        case BlankRecord.sid:
            BlankRecord brec = (BlankRecord) record;
            thisRow = brec.getRow();
            thisColumn = brec.getColumn();
            thisStr = "";
            rowlist.add(thisColumn, thisStr);
            break;
        case BoolErrRecord.sid: // 單元格為布林型別
            BoolErrRecord berec = (BoolErrRecord) record;
            thisRow = berec.getRow();
            thisColumn = berec.getColumn();
            thisStr = berec.getBooleanValue() + "";
            rowlist.add(thisColumn, thisStr);
            break;

        case FormulaRecord.sid: // 單元格為公式型別
            FormulaRecord frec = (FormulaRecord) record;
            thisRow = frec.getRow();
            thisColumn = frec.getColumn();
            if (outputFormulaValues) {
                if (Double.isNaN(frec.getValue())) {
                    // Formula result is a string
                    // This is stored in the next record
                    outputNextStringRecord = true;
                    nextRow = frec.getRow();
                    nextColumn = frec.getColumn();
                } else {
                    thisStr = formatListener.formatNumberDateCell(frec);
                }
            } else {
                thisStr = '"' + HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression()) + '"';
            }
            rowlist.add(thisColumn, thisStr);
            break;
        case StringRecord.sid:// 單元格中公式的字串
            if (outputNextStringRecord) {
                // String for formula
                StringRecord srec = (StringRecord) record;
                thisStr = srec.getString();
                thisRow = nextRow;
                thisColumn = nextColumn;
                outputNextStringRecord = false;
            }
            break;
        case LabelRecord.sid:
            LabelRecord lrec = (LabelRecord) record;
            curRow = thisRow = lrec.getRow();
            thisColumn = lrec.getColumn();
            value = lrec.getValue().trim();
            value = value.equals("") ? " " : value;
            this.rowlist.add(thisColumn, value);
            break;
        case LabelSSTRecord.sid: // 單元格為字串型別
            LabelSSTRecord lsrec = (LabelSSTRecord) record;
            curRow = thisRow = lsrec.getRow();
            thisColumn = lsrec.getColumn();
            if (sstRecord == null) {
                rowlist.add(thisColumn, " ");
            } else {
                value = sstRecord.getString(lsrec.getSSTIndex()).toString().trim();
                value = value.equals("") ? " " : value;
                rowlist.add(thisColumn, value);
            }
            break;
        case NumberRecord.sid: // 單元格為數字型別
            NumberRecord numrec = (NumberRecord) record;
            curRow = thisRow = numrec.getRow();
            thisColumn = numrec.getColumn();
            value = formatListener.formatNumberDateCell(numrec).trim();
            value = value.equals("") ? " " : value;
            // 向容器加入列值
            rowlist.add(thisColumn, value);
            break;
        default:
            break;
        }

        // 遇到新行的操作
        if (thisRow != -1 && thisRow != lastRowNumber) {
            lastColumnNumber = -1;
        }

        // 空值的操作
        if (record instanceof MissingCellDummyRecord) {
            MissingCellDummyRecord mc = (MissingCellDummyRecord) record;
            curRow = thisRow = mc.getRow();
            thisColumn = mc.getColumn();
            rowlist.add(thisColumn, " ");
        }

        // 更新行和列的值
        if (thisRow > -1)
            lastRowNumber = thisRow;
        if (thisColumn > -1)
            lastColumnNumber = thisColumn;

        // 行結束時的操作
        if (record instanceof LastCellOfRowDummyRecord) {
            if (minColumns > 0) {
                // 列值重新置空
                if (lastColumnNumber == -1) {
                    lastColumnNumber = 0;
                }
            }
            lastColumnNumber = -1;

            // 每行結束時, 呼叫getRows() 方法
            rowReader.getRows(sheetIndex, curRow, rowlist);
            // 清空容器
            rowlist.clear();
        }
    }

  
      public static void main(String[] args) {
       IExcelRowReader rowReader = new ExcelRowReader();
      try {
          // ExcelReaderUtil.readExcel(rowReader,
          // "E://2016-07-04-011940a.xls");
            System.out.println("**********************************************");
            ExcelReaderUtil.readExcel(rowReader, "E://test.xlsx");
            } catch (Exception e) {
            e.printStackTrace();
           }
       }


}


07Reader:

[java] view plain copy print?
  1. package com.boguan.bte.util.excel;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.util.ArrayList;  
  5. import java.util.Iterator;  
  6. import java.util.List;  
  7. import org.apache.commons.lang.StringUtils;  
  8. import org.apache.poi.openxml4j.exceptions.OpenXML4JException;  
  9. import org.apache.poi.openxml4j.opc.OPCPackage;  
  10. import org.apache.poi.ss.usermodel.BuiltinFormats;  
  11. import org.apache.poi.ss.usermodel.DataFormatter;  
  12. import org.apache.poi.xssf.eventusermodel.XSSFReader;  
  13. import org.apache.poi.xssf.model.SharedStringsTable;  
  14. import org.apache.poi.xssf.model.StylesTable;  
  15. import org.apache.poi.xssf.usermodel.XSSFCellStyle;  
  16. import org.apache.poi.xssf.usermodel.XSSFRichTextString;  
  17. import org.xml.sax.Attributes;  
  18. import org.xml.sax.InputSource;  
  19. import org.xml.sax.SAXException;  
  20. import org.xml.sax.XMLReader;  
  21. import org.xml.sax.helpers.DefaultHandler;  
  22. import org.xml.sax.helpers.XMLReaderFactory;  
  23. import com.boguan.bte.service.common.IExcelRowReader;  
  24. import com.boguan.bte.service.common.impl.ExcelRowReader;  
  25. /** 
  26.  * 名稱: ExcelXlsxReader.java<br> 
  27.  * 描述: <br> 
  28.  * 型別: JAVA<br> 
  29.  * 最近修改時間:2016年7月5日 上午10:00:52<br> 
  30.  *  
  31.  * @since 2016年7月5日 
  32.  * @author “” 
  33.  */
  34. publicclass ExcelXlsxReader extends DefaultHandler {  
  35.     private IExcelRowReader rowReader;  
  36.     publicvoid setRowReader(IExcelRowReader rowReader) {  
  37.         this.rowReader = rowReader;  
  38.     }  
  39.     /** 
  40.      * 共享字串表 
  41.      */
  42.     private SharedStringsTable sst;  
  43.     /** 
  44.      * 上一次的內容 
  45.      */
  46.     private String lastContents;  
  47.     /** 
  48.      * 字串標識 
  49.      */
  50.     privateboolean nextIsString;  
  51.     /** 
  52.      * 工作表索引 
  53.      */
  54.     privateint sheetIndex = -1;  
  55.     /** 
  56.      * 行集合 
  57.      */
  58.     private List<String> rowlist = new ArrayList<String>();  
  59.     /** 
  60.      * 當前行 
  61.      */
  62.     privateint curRow = 0;  
  63.     /** 
  64.      * 當前列 
  65.      */
  66.     privateint curCol = 0;  
  67.     /** 
  68.      * T元素標識 
  69.      */
  70.     privateboolean isTElement;  
  71.     /** 
  72.      * 異常資訊,如果為空則表示沒有異常 
  73.      */
  74.     private String exceptionMessage;