使用以下代码,不会保存对Excel电子表格所做的单元格值更改:
OPCPackage pkg = OPCPackage.open(inputFile);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
ModifyWorkbook();
pkg.close();
以下是我写的解决方法,但我不明白为什么这是必要的。
OPCPackage pkg = OPCPackage.open(inputFile);
XSSFWorkbook wb = new XSSFWorkbook(pkg);
ModifyWorkbook();
File tmp = File.createTempFile("tempSpreadsheet", ".xlsx");
FileOutputStream newExcelFile = new FileOutputStream(tmp);
wb.write(newExcelFile);
newExcelFile.close();
tmp.deleteOnExit();
pkg.close();
主题上的javadoc和指南表明.close()方法应该保存并关闭。在关闭之前检查已修改单元格的值是否表明已进行更改,但单独使用pkg.close()方法不足以在关闭时将这些更改写入文件。
答案 0 :(得分:2)
对OPCPackage.close()
的调用将关闭基础OOXML文件结构。它不会做的是导致XSSF(或任何X ?? F格式)写出他们的更改。所以,你会写出一个未更改的文件....
如果您正在进行低级别修改,则可以打开OPCPackage,进行更改,然后调用close将其写出来。如果您正在执行高级操作,则打开OPCPackage,使用UserModel代码进行更改,然后请求usermodel 写出其更改。这是最后一步,这很重要。
您当前的代码有点像:
File f = new File("test.txt");
Sting s = readFileCompletely(f);
s = s.replaceAll("foo", "bar");
f.close();
// Why hasn't the file contents changed?
读入文件并修改高级对象是不够的,还需要告诉高级对象写出更改。 (出于性能原因,高级对象会将内容缓存在内存中)
答案 1 :(得分:1)
在(XSSF)工作簿上调用close
将调用OPCP.close,其中javadoc声明:
调用
myWorkbook.close()
应该将更改写入文件 从...开始。
但是,当前版本(3.15)似乎遇到了问题。原因本身对我来说不了解,但我发现调用myWorkbook.write()
不仅会提交对输出流的更改,还会在调用close之后提交给当前实例。
因此,合理的解决方法可能是:
try (OutputStream bos = ByteStreams.nullOutputStream()){
workbook.write(bos);
workbook.close();
} catch (IOException e) {
log.error("Could not write Output File", e);
}
这里完成了Guavas ByteStreams。随意使用other null输出流实现。
答案 2 :(得分:0)
在最新版本的POI中,如果默认构造函数正在创建org.apache.poi.xssf.usermodel.XSSFWorkbook的对象,则无需手动进行操作。阅读其默认的构造方法
public XSSFWorkbook() {
super(newPackage());
onWorkbookCreate();
}
protected static OPCPackage newPackage() {
try {
OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
// Main part
PackagePartName corePartName = PackagingURIHelper.createPartName(XSSFRelation.WORKBOOK.getDefaultFileName());
// Create main part relationship
pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT);
// Create main document part
pkg.createPart(corePartName, XSSFRelation.WORKBOOK.getContentType());
pkg.getPackageProperties().setCreatorProperty(DOCUMENT_CREATOR);
return pkg;
} catch (Exception e){
throw new POIXMLException(e);
}
}