我有一个template.xls
文件,我正在从某些数据库查询中添加数据。我添加数据并生成一个名为 yyyyMMddHHmmss.xls
的新文件。这很好用。文件大小越来越大,所以我正在尝试对xlsx
文件做同样的事情。当我第一次生成文件时,它工作得很好。如果我再次运行该过程(即使我重新启动我的 java 应用程序(,它会以某种方式将最后一个文件保留在内存中并将数据附加到该文件。在这两种情况下,它都从未修改的文件中提取源文件template.xls(x)
。
两者之间的代码是相同的,只是我在后一种情况下传递xlsx
而不是xls
。
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(Objects.requireNonNull(classLoader.getResource("template.xlsx")).getFile());
Workbook workbook = WorkbookFactory.create(file);
// write data
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String currentDate = formatter.format(date);
FileOutputStream fileOutputStream = new FileOutputStream(currentDate + ".xlsx");
workbook.write(fileOutputStream);
fileOutputStream.close();
workbook.close();
我正在使用Java 8u201
和org.apache.poi:poi:4.1.0
(也尝试过4.0.1
(
正如 Apache POI - FileInputStream 工作中所述,File 对象已经失败 (NullPointerException(,从File
创建XSSFWorkbook
有一个缺点,在该工作簿中所做的所有更改都将始终存储在该文件中,而XSSFWorkbook.write
。即使write
写入另一个文件也是如此。但是,甚至不可能显式写入同一文件,因为File
在创建工作簿后保持打开状态,因此写入同一文件会导致异常。
File
XSSFWorkbook
因此,使用
Workbook workbook = WorkbookFactory.create(file);
当file
是*.xlsx
文件时,这不是一个好主意。相反,需要使用FileInputstream
创建Workbook
:
Workbook workbook = WorkbookFactory.create(new FileInputStream(file));
尽管链接的 SO Q/A 来自 2017 年,但使用 apache poi 4.1.0
时,今天总是也不会发生同样的问题。