我有一个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 works, File object fails (NullPointerException)已经说过的那样,从XSSFWorkbook
创建一个File
有一个缺点,那就是在该工作簿中所做的所有更改都会被存储到该文件中,而XSSFWorkbook.write
。即使write
写入另一个文件也是如此。但是明确地写入同一个文件是不可能的,因为File
在创建工作簿之后保持打开,因此写入同一个文件会导致异常。
所以用XSSFWorkbook
创建一个File
Workbook workbook = WorkbookFactory.create(file);
当file
是一个*.xlsx
文件时不是一个好主意。相反,需要使用Workbook
创建FileInputstream
:
Workbook workbook = WorkbookFactory.create(new FileInputStream(file));
尽管链接的SO Q / A是2017年,但使用apache poi 4.1.0
时,同样的问题总是不会出现。