Apache poi 文件损坏,无法写入现有工作簿
Apache poi file getting corrupted and unable to write to existing workbook
我正在尝试使用以下代码读写工作簿:
public static void main(String args[]) {
String absoluteFilePath = System.getProperty("user.dir") + File.separator + "abc.xlsx";
System.out.println("Readin file : " + absoluteFilePath);
Workbook workbook = null;
try {
workbook = WorkbookFactory.create(new File(absoluteFilePath));
//reading and writing on sheets of workbook
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
System.out.println("Writing to workbook and Closing the file");
FileOutputStream fileOutputStream = new FileOutputStream(
new File(absoluteFilePath));
workbook.write(fileOutputStream);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我第一次 运行 代码时,我在 workbook.write(fileOutputStream);
得到这个异常
Exception in thread "main" org.apache.poi.POIXMLException: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:148)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:199)
at NewNewDriver.main(NewNewDriver.java:129)
Caused by: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
at org.apache.poi.openxml4j.opc.PackagePart.getInputStream(PackagePart.java:500)
at org.apache.poi.POIXMLProperties.<init>(POIXMLProperties.java:75)
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:146)
... 2 more
在此之后,工作簿被破坏,我减少到 0kb,我在 WorkbookFactory.create()
上得到这个异常:
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:167)
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:117)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:225)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:164)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:145)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:105)
at NewNewDriver.main(NewNewDriver.java:27)
Closing the file
Exception in thread "main" java.lang.NullPointerException
at NewNewDriver.main(NewNewDriver.java:129)
我应该在哪里以及如何使用 FileOutputStream,workbook.write(),即使我正在使用 WorkbookFactory,我是否也应该使用 FileInputStream?
------------编辑--------------------我的代码可以正常工作
我使用 FileInputStream 而不是 WorkbookFactory 来创建工作簿,并在关闭 FileOutputStream 后将其关闭。成功了。
Where and how should I use the FileOutputStream, workbook.write()
不在 finally
块中。如果您遇到任何类型的异常,您肯定不想将可能的垃圾写入文件。 workbook
甚至可以是 finally
块中的 null
。
将该代码移至 try
块的末尾。
我想我已经发现了你的问题:
workbook = WorkbookFactory.create(new File(absoluteFilePath));
....
FileOutputStream fileOutputStream = new FileOutputStream(
new File(absoluteFilePath));
workbook.write(fileOutputStream);
您正在打开一个文件,然后在它仍然打开并在使用时试图稍后覆盖它,这是不受支持的
您需要做的是将更新后的文件写入不同的文件名。如果要替换它,则需要在关闭原始文件后执行第二步。
就目前而言,您已经开始覆盖文件,然后 POI 尝试将原始文件的某些部分复制到新文件,但失败了,因为它试图读取的原始文件已被删除!
(底层包代码NPOIFSFileSystem和OPCPackage都支持就地写入和就地更新,但是HSSFWorkbook/XSSFWorkbook/XWPFDocument等高层代码只支持写出到新文件,并没有社区对就地写作的兴趣足以增加支持)
我正在尝试使用以下代码读写工作簿:
public static void main(String args[]) {
String absoluteFilePath = System.getProperty("user.dir") + File.separator + "abc.xlsx";
System.out.println("Readin file : " + absoluteFilePath);
Workbook workbook = null;
try {
workbook = WorkbookFactory.create(new File(absoluteFilePath));
//reading and writing on sheets of workbook
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
System.out.println("Writing to workbook and Closing the file");
FileOutputStream fileOutputStream = new FileOutputStream(
new File(absoluteFilePath));
workbook.write(fileOutputStream);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我第一次 运行 代码时,我在 workbook.write(fileOutputStream);
Exception in thread "main" org.apache.poi.POIXMLException: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:148)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:199)
at NewNewDriver.main(NewNewDriver.java:129)
Caused by: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
at org.apache.poi.openxml4j.opc.PackagePart.getInputStream(PackagePart.java:500)
at org.apache.poi.POIXMLProperties.<init>(POIXMLProperties.java:75)
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:146)
... 2 more
在此之后,工作簿被破坏,我减少到 0kb,我在 WorkbookFactory.create()
上得到这个异常:
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:167)
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:117)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:225)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:164)
at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:145)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:105)
at NewNewDriver.main(NewNewDriver.java:27)
Closing the file
Exception in thread "main" java.lang.NullPointerException
at NewNewDriver.main(NewNewDriver.java:129)
我应该在哪里以及如何使用 FileOutputStream,workbook.write(),即使我正在使用 WorkbookFactory,我是否也应该使用 FileInputStream?
------------编辑--------------------我的代码可以正常工作 我使用 FileInputStream 而不是 WorkbookFactory 来创建工作簿,并在关闭 FileOutputStream 后将其关闭。成功了。
Where and how should I use the FileOutputStream, workbook.write()
不在 finally
块中。如果您遇到任何类型的异常,您肯定不想将可能的垃圾写入文件。 workbook
甚至可以是 finally
块中的 null
。
将该代码移至 try
块的末尾。
我想我已经发现了你的问题:
workbook = WorkbookFactory.create(new File(absoluteFilePath));
....
FileOutputStream fileOutputStream = new FileOutputStream(
new File(absoluteFilePath));
workbook.write(fileOutputStream);
您正在打开一个文件,然后在它仍然打开并在使用时试图稍后覆盖它,这是不受支持的
您需要做的是将更新后的文件写入不同的文件名。如果要替换它,则需要在关闭原始文件后执行第二步。
就目前而言,您已经开始覆盖文件,然后 POI 尝试将原始文件的某些部分复制到新文件,但失败了,因为它试图读取的原始文件已被删除!
(底层包代码NPOIFSFileSystem和OPCPackage都支持就地写入和就地更新,但是HSSFWorkbook/XSSFWorkbook/XWPFDocument等高层代码只支持写出到新文件,并没有社区对就地写作的兴趣足以增加支持)