根据经验,SAX确实对内存性能有很大帮助。从4GB +到300MB左右。
一些有用的链接和其他提示:
从https://poi.apache.org/spreadsheet/limitations.html
文件大小/内存使用
有Excel文件格式的一些固有的限制。这些是在SpreadsheetVersion类中定义的 。只要你有足够的主内存,你应该能够处理达到这些限制的文件。 对于使用默认POI类的大型文件,您可能需要非常大量的内存。
有办法克服的,如果需要的主内存限制:对于 编写非常大的文件,有SXSSFWorkbook允许做数据的 流写出到文件(用什么 你可以做一定的限制因为只有部分文件保存在内存中)。对于阅读 非常大的文件,看一下示例XLSX2CSV,其中显示了如何以流式方式读取文件(同样有一些限制 ,您可以从文件中读出哪些信息,但有多种方法可以获得 如果有必要,大多数情况下)。
而且
https://poi.apache.org/faq.html#faq-N10165
- 我认为POI占用了太多的记忆!我能做什么?这一个出现了很多,但通常原因并不是你可能最初想到的。所以,首先要检查的是 - 问题的来源是什么 ?你的文件?你的代码?你的环境?还是Apache POI?
(如果你在这里,你可能认为这是Apache的POI。然而,经常 是不是!适度的笔记本电脑,一个体面的,但不能过度堆大小, 从起步,能够正常在几秒钟内读取或写入包含100列和100000行的文件,包括启动JVM的 时间。
Apache POI附带一些程序和一些示例程序,可用于执行一些基本的性能检查。对于测试文件 的生成,要使用的类位于示例包中, SSPerformanceTest(viewvc)。运行SSPerformanceTest,参数为 写入类型(HSSF,XSSF或SXSSF),数字行,列数 ,以及是否应保存文件。如果在3秒内无法通过 在HSSF和SXSSF中以50,000行和50列运行,并且在10秒内(并且理想情况下所有3个都小于!),则 问题与您的环境有关。
接下来,使用示例程序ToCSV(viewvc)尝试使用HSSF或XSSF读取文件 。相关的是XLSX2CSV(viewvc),它使用SAX 解析.xlsx。针对问题文件和由SSPerformanceTest生成的相同大小的简单问题文件运行此操作。如果这是 慢,那么可能会出现Apache POI问题,该问题与文件的处理方式为 (POI提供了一些假设,并非总是在所有文件上都为 )。如果这些测试速度很快,那么任何性能 问题都出现在您的代码中!
而且
文件VS InputStreams http://poi.apache.org/spreadsheet/quick-guide.html#FileInputStream
When opening a workbook, either a .xls HSSFWorkbook, or a .xlsx XSSFWorkbook, the Workbook can be loaded from either a File or an InputStream. Using a File object allows for lower memory consumption, while an InputStream requires more memory as it has to buffer the whole file.
If using WorkbookFactory, it's very easy to use one or the other:
// Use a file
Workbook wb = WorkbookFactory.create(new File("MyExcel.xls"));
// Use an InputStream, needs more memory
Workbook wb = WorkbookFactory.create(new FileInputStream("MyExcel.xlsx"));
如果直接使用HSSFWorkbook或XSSFWorkbook,你通常应该 经过NPOIFSFileSystem或OPCPackage,拥有完全控制 生命周期(包括关闭文件时完成):
// HSSFWorkbook, File
NPOIFSFileSystem fs = new NPOIFSFileSystem(new File("file.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true);
....
fs.close();
// HSSFWorkbook, InputStream, needs more memory
NPOIFSFileSystem fs = new NPOIFSFileSystem(myInputStream);
HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true);
// XSSFWorkbook, File
OPCPackage pkg = OPCPackage.open(new File("file.xlsx"));
XSSFWorkbook wb = new XSSFWorkbook(pkg);
....
pkg.close();
// XSSFWorkbook, InputStream, needs more memory
OPCPackage pkg = OPCPackage.open(myInputStream);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
....
pkg.close();
尝试增加堆大小:问题: http://stackoverflow.com/questions/1565388/increase-heap-size-in-java –
因为SAX是一个很好的解决方案,你不要不想使用它,csv格式可以是很好的选择,CSV格式可以通过Excel打开,很好的理由是考虑使用可以流式处理的格式,而不是一次读入内存。将内容类型设置为application/vnd.ms-excel和扩展类型“.xls”。 –