概述
最近在做项目的时候遇到了使用Java调用POI读写Excel的问题,再向一个已经打开的文件写入修改好的数据的时候,源文件被复写为空文件。这个问题涉及到POI读写文件的原理,故在此记录一下,以备日后回顾。
问题程序
//读数据表
Workbook wb = WorkbookFactory.create(new File(sourcePath));
Sheet table = wb.getSheetAt(0);
//写数据表
FileOutputStream fOut = null;
try {
File file = new File(targetFile);
if(!file.exists()){
file.getParentFile().mkdirs();
file.createNewFile();
}
fOut = new FileOutputStream(file);
wb.write(fOut);
fOut.flush();
fOut.close();
wb.close();
} catch (FileNotFoundException e) {
e.printStackTrace(System.out);
} catch (IOException e) {
e.printStackTrace(System.out);
}
测试结果
采用上述程序读写统一Excel文件时会产生问题,也就是无法通过该种方式来修改Excel文件。
问题分析
POI虽然初始时通过加载程序将所有文件内容加载到内存中,但是还是与Excel文件保持着联系。在文件打开状态下,用户尝试向文件写入程序,然后POI会尝试去从源文件中拷贝到新文件中,但是这部分文件已经被擦除了,这便导致了问题。
解决方案
将打开Excel的代码修改为
Workbook wb = WorkbookFactory.create(new FileInputStream(sourcePath));
Sheet table = wb.getSheetAt(0);
通过FileInputStream方式打开文件,文件内容会存在缓存中,POI的workbook与缓存中的文件内容建立联系,所以此时操作文件系统中的原始文件不会导致问题。