使用Apache POI修改现有的xlsx电子表格导致不可读的内容错误
所以在使用Apache POI的Excel中,不可读的内容错误的话题似乎很常见。 然而,我很惊讶,我仍然无法find我的问题的一个例子,特别是因为它似乎非常简单,我正在努力。 这导致我相信有些东西可能只是通过我对一些java对象的了解,特别是File和FileInputStream。 我通过大量的试验和错误发现了如何使它工作,但我的问题是为什么一个工作,为什么另一个不工作,并希望了解潜在的问题。 我认为这也可以帮助别人理解。 这正是我想要做的:
打开一个现有的xlsx文件,为其添加一个表单,并将其保存为与原始文件相同的文件名。 实质上,只需修改现有的xlsx文件即可添加工作表。
下面是不工作的代码,以及代码,我想知道为什么使用File对象不起作用。在这两个示例中,我已经创build了一个名为Voucher_1的工作表的TravelVouchers.xlsx文件,它可以工作罚款打开它。
以下代码导致travelVouchersWkBk.write(fileOut);
上的NullPointerException travelVouchersWkBk.write(fileOut);
线:
File travelVouchersFile = new File("./Output/TravelVouchers.xlsx"); Workbook travelVouchersWkBk = WorkbookFactory.create(travelVouchersFile); travelVouchersWkBk.createSheet("Voucher_2"); FileOutputStream fileOut = new FileOutputStream(travelVouchersFile); travelVouchersWkBk.write(fileOut); fileOut.flush(); fileOut.close();
虽然下面的代码很好:
File travelVouchersFile = new File("./Output/TravelVouchers.xlsx"); FileInputStream fileIn = new FileInputStream(travelVouchersFile); Workbook travelVouchersWkBk = WorkbookFactory.create(fileIn); travelVouchersWkBk.createSheet("Voucher_2"); fileIn.close(); FileOutputStream fileOut = new FileOutputStream(travelVouchersFile); travelVouchersWkBk.write(fileOut); fileOut.flush(); fileOut.close();
在不起作用的代码中,会导致excel中出现无法读取的内容,并且当我select修复时,我可以打开它,并且只有Voucher_1。 所以显然使用WorkbookFactory.create与File对象不起作用,在哪里使用FileInputStream呢,但我想知道我不了解File vs FileInputStream,因为它涉及到这个问题。
非常感谢您的澄清,我真的很感激! 保罗
我相信使用WorkbookFactory
的File
读取Workbook
,然后写入相同的 Workbook
– File
是不是一个好主意,直到现在。 apache POI文档提到:
文件与InputStreams
打开工作簿时,可以使用.xls HSSFWorkbook或.xlsx XSSFWorkbook,可以从File或InputStream中加载工作簿。 使用File对象可以降低内存消耗,而InputStream需要更多的内存,因为它必须缓冲整个文件。
但为什么使用File对象可以降低内存消耗? 这是因为Workbookfactory
然后创build一个RandomAccessFile
不需要在内存中完全读取。 要validation,请阅读WorkbookFactory.java
的来源 – > public static Workbook create(File file, String password, boolean readOnly)
, NPOIFSFileSystem.java
– > private NPOIFSFileSystem(FileChannel channel, File srcFile, boolean readOnly, boolean closeChannelOnError)
, FileBackedDataSource.java
– > private static RandomAccessFile newSrcFile(File file, String mode)
。
但据我所知,没有可能访问这个RandomAccessFile
。 所以我们不能写信给它,也不能在不closures整个Workbook
情况下closures它。 所以在上面的例子中,随着Workbook.write(FileOutputStream)
尝试写入文件, RandomAccessFile
将被打开以进行读写(rw模式)。
所以使用File
可能对于只读或者从一个文件读取并保存到另一个文件来说是好的。 但是直到现在,使用File
读取和写入相同的文件并不是一个好主意。 对于这个FileInputStream
和FileOutputStream
更好。