我在使用Apache POI解析 .xlsx
文件时遇到了一些问题 - 我在部署的应用程序中获得了 java.lang.OutOfMemoryError: Java heap space
. 我只处理5MB以下和大约70,000行的文件,所以我怀疑阅读其他问题是否有问题 .
正如在this comment中所建议的那样,我决定使用建议的变量运行 SSPerformanceTest.java
,以便查看我的代码或设置是否有任何问题 . 结果显示HSSF( .xls
)和XSSF( .xlsx
)之间存在显着差异:
1) HSSF 50000 50 1: 经过1秒
2) SXSSF 50000 50 1: 经过了5秒钟
3) XSSF 50000 50 1: 经过了15秒
FAQ具体说:
如果你不能在3秒内完成所有HSSF,XSSF和SXSSF中50,000行和50列的运行(理想情况下要少得多!),问题在于您的环境 .
接下来,它说要运行我已经完成的 XLS2CSV.java
. 在上面生成的XSSF文件(包含50000行和50列)中输入大约需要15秒 - 与写入文件所需的数量相同 .
Is something wrong with my environment, and if so how do I investigate further?
VisualVM的统计数据显示在处理过程中使用的堆高达1.2Gb . 当然,考虑到与处理开始之前相比,这是一个额外的演出?
注意:上面提到的堆空间异常仅发生在 生产环境 中(在Google App Engine上)并且仅发生在 .xlsx
文件中,但是此问题中提到的测试都已在我的开发机器上运行 -Xmx2g
. 我希望如果我可以解决我的开发设置问题,它将在部署时使用更少的内存 .
来自app引擎的堆栈跟踪:
引起:java.lang.OutOfMemoryError:org.apache.xmlbeans.impl.store.Cur上的org.apache.xmlbeans.impl.store.Cur.createElementXobj(Cur.java:260)中的Java堆空间$ CurLoadContext.startElement (Cur.java:2997)org.apache.xmlbeans.impl.store.Locale $ SaxHandler.startElement(Locale.java:3211)at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.reportStartTag(Piccolo.java) :1082)org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseAttributesNS(PiccoloLexer.java:1802)at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseOpenTagNS(PiccoloLexer.java:1521)
2 回答
我遇到了同样的问题,使用Apache POI阅读庞大的.xlsx文件,我遇到了
excel-streaming-reader-github
该库充当流式API的包装器,同时保留了标准POI API的语法
该库可以帮助您读取大文件 .
我工作的平均XLSX板材大约是18-22张750,000行,13-20列 . 这在具有许多其他功能的Spring Web应用程序中正在旋转 . 我给了整个应用程序而不是那么多内存:
-Xms1024m -Xmx4096m
- 它很棒!首先是转储代码:在内存中加载每个数据行并开始转储它是错误的 . 在我的情况下(从PostgreSQL数据库报告)我重写数据转储程序使用
RowCallbackHandler
写入我的XLSX,在此期间我达到750000行的"my limit",我创建新表 . 并且使用50行的可见性窗口创建工作簿 . 通过这种方式,我可以转储大量的卷:XLSX文件的大小约为1230Mb .写一些代码表:
在重新编写将数据转储到XLSX的代码后,我遇到了问题,它需要64位的Office才能打开它们 . 因此,我需要将包含大量工作表的工作簿拆分为单独的XLSX文件,使其在单个工作表上可读 . 我再次使用小型可见性窗口和流处理,并保持整个应用程序运行良好,没有任何OutOfMemory的景点 .
一些代码来读取和拆分表:
和
所以它读写数据 . 我想在你的情况下你应该将你的代码重写为相同的模式:在内存中只保留少量数据 . 所以我建议阅读创建自定义
SheetContentsReader
,它将数据推送到某个数据库,在那里可以轻松处理,聚合等 .