我正在使用Java Apache POI库并处理大量的Excel工作表。大约10 MB的数据,包含大量的行和列。一个excel文件中还有8-10个不同的工作表。数据不是富文本格式,而是充满内部函数和公式,例如。 = SUM(A2:A4)
等我对此没有任何顾虑。
此图片仅供参考。实际数据中的函数是不同的,非常复杂:
数据包括字符串,数字和布尔值。我担心的是只将XSSF读取值作为普通文本,不包括在excel中应用的所有公式或函数。所以说,在上面的图像中我只想读取行和列i.e. 10,20,30 etc, Numbers, Total
问题
如果我格式化Excel工作表并删除所有公式和函数并以简单的富文本格式保存数据,我的代码就会运行。但是,当我不修改excel文件并保持数据如上面所示格式时,我遇到GC开销限制超出错误。
我想要什么
我只想阅读充满公式和功能的excel文件。当我删除所有公式并将文本保存为正常的富文本格式时,我的算法有效。
我尝试了什么
正如在线其他资源和stackoverflow中所提到的,我尝试了第一种方法,如下面的代码所示:
fis = new FileInputStream(path);
opc = OPCPackage.open(fis);
XSSFWorkbook workbook = new XSSFWorkbook(opc);
我没有简单地使用FileInputStream
作为输入,而是先通过OPCPackage传递它。它仍显示相同的错误,代码不会在XSSFWorkbook workbook
然后我用XSSFReader
使用了第二种方法。以下是代码:
xssfReader = new XSSFReader(opc);
SharedStringsTable sst = xssfReader.getSharedStringsTable();
XSSFReader.SheetIterator itr = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
while(itr.hasNext()) {
InputStream sheetStream = itr.next();
if(itr.getSheetName().equals(sheetName)) {
// no idea how to extract sheet like I would do in XSSFWorkbook
// I only get Sheet name of desired sheet
} // while ends here
到目前为止,对我来说没有任何作用,如果我使用XSSFWorkbook
,它将超出GC开销限制错误。所以目前我手动删除所有公式和函数然后算法工作,但它没有有效的方法来处理问题。任何帮助或建议表示赞赏。
修改
正如链接here中指出的那样,我尝试分配更多内存,但它仍然无法解决。以下是我尝试分配更多内存的一些快照。
如果我在分配内存方面做错了,请告诉我。我会做必要的改变。
新修改
我已经解决了我在下面的内部评论中提到的问题,将-Xmx8192m
添加到我在eclipse中的运行配置中。我现在正在研究使用SXSSFWorkbook
解决内存问题的其他方法,如下面的答案中所述。
答案 0 :(得分:1)
您是否尝试将文件作为SXSSF工作簿而不是XSSF工作簿打开?
fis = new FileInputStream(path);
opc = OPCPackage.open(fis);
XSSFWorkbook workbook = new XSSFWorkbook(opc);
SXSSFWorkbook wb = new SXSSFWorkbook(workbook);
见https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html。直接来自他们的JavaDoc:"这允许编写非常大的文件而不会耗尽内存,因为在任何时候只有行的可配置部分保存在内存中#34;
答案 1 :(得分:1)
发表评论作为回答:
您显示的内存设置适用于Eclipse IDE和Java Webstart,您实际上是如何启动应用程序的?如果在Eclipse中作为应用程序或单元测试,那么您需要在运行配置中调整内存设置,而不是在您自己的代码运行时实际应用它们。