我正在尝试更新现有的Excel文件(xlsx)。
XSSFWorkbook(java.io.File file)
和XSSFWorkbook(OPCPackage pkg)
之类的构造函数以只读模式打开文件,不允许修改。因此,我必须使用XSSFWorkbook(java.io.InputStream is)
,并且内存占用量(JVM内存和Java Heap)太高。我不能使用VM args设置最大内存大小,因为我必须考虑并行运行的其他程序的内存要求。
使用SXSSFWorkbook
是另一种解决方案,但它实际上是XSSFWorkbook
的包装。 XSSFWorkbook
仍然存在相同的问题。
我去过SO的其他职位,找不到任何相关答案。有人可以帮我吗?我可以存储临时文件。
您的问题不清楚。实际上不是“如何不使用XSSFWorkbook
来打开InputStream
?”。但是“如何减少XSSFWorkbook
的内存占用?”。这个问题的答案是:不能减少它,例如现在已编程apache poi
。否则apache poi
开发人员必须非常愚蠢,特别是为了浪费内存而对apache poi
进行了编程。他们还没有。
但是使用了太多的抽象级别。
全部基于XML。但是,编程库的用户不希望被XML所困扰,至少也不想被那种XML所困扰,这种XML在ZIP归档文件中被分成多个文件,这些文件使用特殊关系XML文件链接在一起。因此,在XML之上是ooxml-schemas
,该库将单个文件的XML转换为可用的java
对象。并且存在org.apache.poi.openxml4j.opc.*
来管理关系。
为了获得所有好处,所有可用的java
对象(工作簿,工作表,行,单元格,图形,表格,数据透视表,图表等)以及这些must]的关系应为可以随时使用。否则将临时文件从*.xlsx
ZIP存档中删除后,必须使用它们临时存储它们。我认为直接在ZIP文件系统中工作不是一种选择,因为这种文件系统类型发生了更改。
但是apache poi
不提供使用临时文件。仅SXSSF
将临时文件用于工作表,而仅用于写入新的*.xlsx
文件,而不用于读取和更新此类文件。
附加,为尽可能与二进制BIFF
*.xls
文件格式兼容,添加了另一个级别。这是SS
和XSSF
级别,提供apache poi
的高级级别。因此,除了内存中的低级java
类之外,现在还有用于工作簿,图纸,行,单元格,工程图,表格,数据透视表,图表等的其他ooxml-schemas
对象。
所以...大的*.xlsx
文件的内存已满。 ;-)
解决方案?
为了尽可能地节省内存,请解压缩*.xlsx
ZIP存档并直接使用其中的XML。当然,这非常费力,尤其是在创建新内容以及考虑到关系时。我在这里的答案中显示了一些简单的示例。例如:How to modify a large Excel file when memory is an issue和How to set cell background color in excel using java + poi。
或者对apache poi
的扩展进行编程,该扩展使用临时文件而不是全部保存在内存中。当然,这也是费力的,并且对于不使用临时文件提供的系统也有缺点。