Apache POI - 读取修改excel文件 [英] Apache POI - reading modifies excel file

查看:36
本文介绍了Apache POI - 读取修改excel文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆