Apache POI - 读取修改excel文件 [英] Apache POI - reading modifies excel file
问题描述
每当我使用 Apatche POI 打开 excel 文件时,该文件都会被修改,即使我只是在读取文件而不进行任何修改.
Whenever I open a excel file using the Apatche POI the file gets modified, even though I'm just reading the file and not making any modification.
以这样的测试代码为例.
Take for instance such test code.
public class ApachePoiTest {
@Test
public void readingShouldNotModifyFile() throws Exception {
final File testFile = new File("C:/work/src/test/resources/Book2.xlsx");
final byte[] originalChecksum = calculateChecksum(testFile);
Assert.assertTrue("Calculating checksum modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
try (Workbook wb = WorkbookFactory.create(testFile)) {
Assert.assertNotNull("Reading file with Apache POI", wb);
}
Assert.assertTrue("Reading file with Apache POI modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
}
@Test
public void readingInputStreamShouldNotModifyFile() throws Exception {
final File testFile = new File("C:/work/src/test/resources/Book2.xlsx");
final byte[] originalChecksum = calculateChecksum(testFile);
Assert.assertTrue("Calculating checksum modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
try (InputStream is = new FileInputStream(testFile); Workbook wb = WorkbookFactory.create(is)) {
Assert.assertNotNull("Reading file with Apache POI", wb);
}
Assert.assertTrue("Reading file with Apache POI modified file",
MessageDigest.isEqual(originalChecksum, calculateChecksum(testFile)));
}
private byte[] calculateChecksum(final File file) throws Exception {
final MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
try (InputStream is = new FileInputStream(file)) {
final byte[] bytes = new byte[2048];
int numBytes;
while ((numBytes = is.read(bytes)) != -1) {
md.update(bytes, 0, numBytes);
}
return md.digest();
}
}
}
Test readingShouldNotModifyFile
总是失败,因为文件总是被 Apache POI 修改.在对使用 MS Office 新创建的空白 Excel 文件进行测试时,Apache POI 会将文件从 8.1 kb 剪切到 6.2 kb 并损坏文件.
Test readingShouldNotModifyFile
always fails, because the file gets always modified by Apache POI. More to it when testing on a blank excel file freshly created with MS Office, Apache POI cuts the file from 8.1 kb to 6.2 kb and corrupts the file.
测试:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
还有 3.12 版
我可以通过其他方式阻止 Apache POI 修改我的文件,然后传递 InputStream
而不是 File
.我不想传递 InputStream
因为我担心 Apache 的警告,它需要更多内存并且对 InputStream
有一些特定要求.
Can I prevent Apache POI from modifying my files by other means then passing InputStream
instead of File
. I don't want to pass InputStream
because I'm concerned about Apache's warning that it takes more memory and has some specific requirements to the InputStream
.
推荐答案
您的问题是您没有传入 readonly 标志,因此 Apache POI 默认以读/写方式打开文件.
Your problem is that you're not passing in the readonly flag, so Apache POI is defaulting to opening the file read/write.
您需要使用 重载 WorkbookFactory.create 方法,该方法采用只读标志 + 将该只读标志设置为 true
You need to use the overloaded WorkbookFactory.create method which takes a readonly flag + set that readonly flag to true
换行
try (InputStream is = new FileInputStream(testFile); Workbook wb = WorkbookFactory.create(is)) {
到
try (IWorkbook wb = WorkbookFactory.create(testFile,null,true)) {
并且您的文件将以只读方式打开而没有任何更改
and your file will be opened read-only with no changes
这篇关于Apache POI - 读取修改excel文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!