POI处理Excel大文件的问题和解决方法

    最近在测试上传Excel2007大文件的功能,采用的是Apache POI工具。

    Excel2007: 24M , POI :3.10

    发现POI在处理24MExce2007l文件的时候,几乎占用了2G的Heap Space.

    由于Excel2007的文件是经过压缩的,其实数据都是存放在shareStringl.xml文件中。

 所以24M的文件,经过解压缩后,其实有160M的大小。

   问题分析:

   经过Debug发现,POI在处理shareString.xml文件的时候,Heap内存就一直在飙升.最后导致内存的溢出,只  能加大Heap Space.

   而

   问题:说明POI在处理Excel2007的时候占用了很大的内存,那么有没有更好的方法来读取Excel文件呢?

   首先先去http://poi.apache.org/faq.html :这个是个常用的问题列表,在

  14. I think POI is using too much memory! What can I do?

 

This one comes up quite a lot, but often the reason isn't what you might initially think. So, the first thing to check is - what's the source of the problem? Your file? Your code? Your environment? Or Apache POI?

.........

Next, use the example program ToCSV to try reading the a file in with HSSF or XSSF. Related is XLSX2CSV, which uses SAX parsing for .xlsx

   我们看到了POI已经提出了针对这个问题的回答,而且正好在XLS2CSV中找到了很好的解决读取大容量的方法.

   在XLS2CSV中,即使是读取300M的2007excel文件也没有什么问题,占用的内存也是可以接受的。

    在这段代码中的注释中写出了下面一段话:

  *Data sheets are read using a SAX parser to keep the
 * memory footprint relatively small, so this should be
 * able to read enormous workbooks.  The styles table and
 * the shared-string table must be kept in memory.  The
 * standard POI styles table class is used, but a custom
 * (read-only) class is used for the shared string table
 * because the standard POI SharedStringsTable grows

 * very quickly with the number of unique strings.                                                                              

大概的意思就是说通用的处理方法会快速消耗掉内存,所以采用了 SAX parser方法来处理大容量的文件.

       public void processSheet(
            StylesTable styles,
            ReadOnlySharedStringsTable strings,
            InputStream sheetInputStream)
            throws IOException, ParserConfigurationException, SAXException {

        InputSource sheetSource = new InputSource(sheetInputStream);
        SAXParserFactory saxFactory = SAXParserFactory.newInstance();
        SAXParser saxParser = saxFactory.newSAXParser();
        XMLReader sheetParser = saxParser.getXMLReader();
        ContentHandler handler = new MyXSSFSheetHandler(styles, strings, this.minColumns, this.output);
        sheetParser.setContentHandler(handler);
        sheetParser.parse(sheetSource);
    }
    上面的一段代码是比较核心的代码,通过SAXParser解析xml文件,尽量不占用内存资源,从而达到读取大文件的目的。

XLSX2CSV代码下载: http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐
  • —软件人才免语言低担保 赴美带薪读研!—



你可能感兴趣的:(poi,Excel,文件)