关闭工作簿的文件句柄(apache poi)

问题描述 投票:0回答:6

我使用

WorkbookFactory.create(new File("path/to/xlsx"))
构建了一个新的工作簿。但是,当我启动应用程序后尝试在 Excel 中编辑文件时,收到一条错误消息,指出该文件正在使用中。我是否必须释放该文件?如果需要,如何释放? (我在 api 文档中找不到类似
Workbook.close()
的内容)或者我必须在其他地方查找吗?

我不知道还能去哪里寻找;该应用程序不会导致 csv 出现这些问题,对于 excel 文件,我只需调用转换器(xls => csv),这是唯一的区别。

(我使用的是POI 3.8)

java file-io apache-poi
6个回答
18
投票

维护传递给

WorkbookFactory.create()
的InputStream的句柄似乎工作得很好,并且在完成工作簿时简单地关闭InputStream。例如:

    InputStream is = // initialize
    try {
        Workbook wb = WorkbookFactory.create(is);
        // use the workbook
    } finally {
        if (is != null) is.close()
    }

13
投票

如果您需要完全控制资源何时关闭,您应该自己预先创建

OPCPackage
,并将其传递到
WorkbookFactory
OPCPackage
提供了您想要的 close 方法。 A
Workbook
将保持打开状态直到垃圾收集

你的代码看起来像这样:

     File f = new File("/path/to/excel/file");
     Workbook wb = null;

     NPOIFSFileSystem npoifs = null;
     OPCPackage pkg = null;
     try {
       npoifs = new NPOIFSFileSystem(f);
       wb = WorkbookFactory.create(npoifs);
     } catch(OfficeXmlFileException ofe) {
       pkg = OPCPackage.open(f);
       wb = WorkbookFactory.create(pkg);
     }
  
     // Use it

     if (npoifs != null) { npoifs.close(); }
     if (pkg != null) { pkg.close(); }

2
投票

如何在 Java 中关闭 POI 工作簿的实例:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;


try{
    File workbookFile = new File("C:\\repo\\yourfile.xslx");
    FileInputStream file = new FileInputStream(workbookFile);
    Workbook wb = WorkbookFactory.create(file);
    Sheet sheet = wb.getSheetAt(0);

    //use the instance of wb.

    file.close();

}
catch(Exception e){
    System.out.println("Fail");
}

2
投票

首先您需要关闭写入工作簿的流:

workBook.write(outputStream);

outputStream.close();

之后您应该关闭工作簿(不再进行任何操作)并处理临时文件:

//Close the workBook
workBook.close();

//deleting the temporary files
workBook.dispose();

2
投票

我使用的是 poi api 版本 5.0.0。此版本中的工作簿有一个 close() 方法,根据 API 文档所述:

“关闭从中读取工作簿的底层输入资源(文件或流)。”

//使用try-catch-finally:

Workbook workbook = null;
try {
    workbook = WorkbookFactory.create(inputStream);
    //....
} catch (IOException ex) {
    //...
}finally {
    workbook.close();
}

//使用 try-with-resources:

try(Workbook workbook = WorkbookFactory.create(fileStream)) {
    //....
} catch (IOException ex) {
    //...
}

0
投票

自 2021 年起,就遇到了同样的问题。:(,当使用 poi 版本 3.9 时。

我只是发现如果我们将poi版本升级到3.17(如果你还在使用Java 7,而poi版本4或更高版本只支持Java 8或更高版本),

然后工作簿将实施

AutoCloseable

因此可以使用

Try-With-Resources
块来自动关闭文件。

这是演示代码。

try (Workbook workbook = WorkbookFactory.create(new File(fileLocation))) {
   // operate on the workbook here...
}

我认为上面的代码比@Gagravarr解决方案更好,因为它复制了create方法在外面所做的事情,不熟悉poi库的开发人员不知道它是什么。


附注 事实上,这个问题被作为 bug 放在 bugzilla 中,请参阅 https://bz.apache.org/bugzilla/show_bug.cgi?id=56537,并已解决,代码已合并到 poi 3.11 或更高版本中。因此任何和我们有同样问题的人都可以看一下它,并在使用完毕后关闭资源。

© www.soinside.com 2019 - 2024. All rights reserved.