在Java Apache POI中更新现有Excel文件而不使用InputStream
我正在尝试更新现有的Excel文件(xlsx) 构造函数,如在Java Apache POI中更新现有Excel文件而不使用InputStream,java,excel,apache-poi,xssf,Java,Excel,Apache Poi,Xssf,我正在尝试更新现有的Excel文件(xlsx) 构造函数,如xssf工作簿(java.io.File文件)和xssf工作簿(OPCPackage pkg)以只读模式打开文件,不允许修改。因此,我必须使用xssf工作簿(java.io.InputStream is),内存占用(JVM内存和java堆)太高。我不能使用VM参数来设置最大内存大小,因为我必须考虑并行运行的其他程序的内存需求 使用SXSSFWorkbook是另一种解决方案,但它本质上是XSSFWorkbook的包装器。与XSSFWork
xssf工作簿(java.io.File文件)
和xssf工作簿(OPCPackage pkg)
以只读模式打开文件,不允许修改。因此,我必须使用xssf工作簿(java.io.InputStream is)
,内存占用(JVM内存和java堆)太高。我不能使用VM参数来设置最大内存大小,因为我必须考虑并行运行的其他程序的内存需求
使用SXSSFWorkbook
是另一种解决方案,但它本质上是XSSFWorkbook
的包装器。与XSSFWorkbook
相同的问题仍然存在
我去了SO的其他帖子,找不到任何相关的答案。有人能帮我吗?我可以存储临时文件。你的问题不清楚。实际上,这不是“如何在不使用输入流的情况下打开
xssfoolk
”,而是“如何减少xssfoolk
?”的内存占用”。这个问题的答案是:它不能被简化,比如apachepoi
现在已经被编程了。否则apache-poi
开发人员一定会像编程apache-poi
那样愚蠢,尤其是为了浪费内存。他们没有
但是使用了太多的抽象级别
所有这些都基于XML。但是编程库的用户不想麻烦使用XML,至少不想麻烦使用这种XML,这种XML在一个ZIP存档中被分割成多个文件,这些文件使用特殊关系XML文件链接在一起。因此,在XML之上还有ooxml模式
,一个库,它将单个文件的XML转换成可用的java
对象。还有org.apache.poi.openxml4j.opc.*
来管理这些关系
为了从中获益,所有可用的java
对象(工作簿、工作表、行、单元格、图形、表格、透视表、图表等)以及它们之间的关系必须在内存中才能使用。或者,在将它们从*.xlsx
ZIP存档中取出后,必须使用临时文件临时存储它们。在我看来,直接在ZIP文件系统中工作不是一个选项,因为这种类型的文件系统中的更改行为
但是使用临时文件不是ApachePOI提供的。只有SXSSF
将临时文件用于工作表,但仅用于写入新的*.xlsx
文件,而不用于读取和更新此类文件
另外,为了尽可能与二进制BIFF
*.xls
文件格式兼容,添加了另一个级别。这是SS
和XSSF
级别,它提供了apachepoi
的高级类。正因为如此,现在有了用于工作簿、工作表、行、单元格、图形、表格、数据透视表、图表等的附加java
对象。。除了内存中的低级ooxml模式
类之外
所以。。。大*.xlsx
文件时内存已满。;-)
解决方案
为了尽可能对内存友好,请解压缩*.xlsx
ZIP归档文件并直接使用其中的XML。当然,这是非常费劲的,尤其是在创造新的内容和考虑到这些关系时。我在这里的回答中给出了一些简单的例子。例如:和
或者为apachepoi
编程一个扩展,它使用临时文件而不是将所有文件都保存在内存中。当然,这也很费劲,对于不提供使用临时文件的系统也有缺点。我使用新的SXSSFWorkbook(-1)和SXSSFSheet.flushRows()获得了很好的效果(内存使用率较低),但这是为了创建新文件,而不是更新文件。我想你应该试试SXSSFWorkbook