Using a File
代替FileInputStream
用于开设一个Workbook
导致较低的内存占用,因为这样,在情况下XSSF
(*.xlsx
), the 压缩包 https://poi.apache.org/apidocs/org/apache/poi/openxml4j/opc/ZipPackage.html将从*.xlsx
直接文件而不是读取整个文件ZIP
内容进入内存。
但这也意味着,ZipPackage
获取文件打开直到Workbook
将被关闭。所以直到Workbook
将被关闭,没有任何东西可以同时写入该文件。所以,既然不可能写出Workbook
内容返回到同一文件Workbook
被打开,使用File
相反FileInputStream
用于开设一个Workbook
如果你只想从中阅读就可以了Workbook
然后。但如果您想读取和写入同一个文件,则它不起作用。然后FileInputStream
and FileOutputStream
是需要的。
所以在你的情况下,你尝试阅读Workbook newWB
from a File
然后写下Workbook
到同一个文件中使用
fileOut = new FileOutputStream(newWorkbook);
newWB.write(fileOut);
当文件已经打开时。这失败了。
But:
fisNew = new FileInputStream(newWorkbook);
oldWB = WorkbookFactory.create(new File(oldWorkbook));
newWB = WorkbookFactory.create(fisNew);
...
fileOut = new FileOutputStream(newWorkbook);
newWB.write(fileOut);
fileOut.close();
oldWB.close();
newWB.close();
应该管用。
顺便说一句:如果您使用的是File
,那么你不应该使用FileInputStream
对于同一个文件。所以不要使用fisOld
.
使用的另一个缺点File
代替FileInputStream
用于开设一个Workbook
是在关闭时Workbook
因此隐式关闭底层文件系统(POIFSFileSystem
的情况下HSSF
and ZipPackage
的情况下XSSF
) 文件获得更新的最后修改日期。文件没有发生任何更改,但文件已被打开并新写入文件系统。这就是更新最后修改日期的原因。
2017 年 9 月 21 日编辑:
使用的缺点File
似乎比一开始想象的还要大。OPCPackage.close https://poi.apache.org/apidocs/org/apache/poi/openxml4j/opc/OPCPackage.html#close--还将所有更改保存到底层OPCPackage
。所以如果你要开一个XSSFWorkbook
从一个文件,然后想要将更改写入另一个文件write(java.io.OutputStream stream)
,那么关闭时源文件也会被改变OPCPackage
。仅当以下情况时才会出现此问题write(java.io.OutputStream stream)
使用自XSSFWorkbook
自那以后POIXMLDocument.write https://poi.apache.org/apidocs/dev/org/apache/poi/ooxml/POIXMLDocument.html#write-java.io.OutputStream-被称为哪个调用POIXMLDocumentPart.onSave https://poi.apache.org/apidocs/dev/org/apache/poi/ooxml/POIXMLDocumentPart.html#onSave-java.util.Set-其中“保存底层 OOXML 包中的更改。”。所以OPCPackage
在关闭前更新所有更改。
简短示例:
import org.apache.poi.ss.usermodel.*;
import java.io.File;
import java.io.FileOutputStream;
class ReadAndWriteExcelWorkbook {
public static void main(String[] args) throws Exception {
Workbook workbook = WorkbookFactory.create(new File("file.xlsx"));
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(0);
if (row == null) row = sheet.createRow(0);
Cell cell = row.getCell(0);
if (cell == null) cell = row.createCell(0);
cell.setCellValue("changed");
FileOutputStream out = new FileOutputStream("fileNew.xlsx");
workbook.write(out);
out.close();
workbook.close();
}
}
在此代码之后两个文件fileNew.xlsx
也file.xlsx
被改变。