[英]Modifying existing xlsx spreadsheet using Apache POI leads to unreadable content error
因此,使用Apache POI在Excel中出現不可讀內容錯誤的主題似乎很常見。 然而,我很驚訝我仍然找不到我的問題的一個例子,特別是因為我想要做的事情似乎非常簡單。 這讓我相信一些東西可能只是我對一些java對象的理解,特別是File和FileInputStream。 我通過大量的試驗和錯誤發現了如何讓它發揮作用,但我的問題是為什么一個有用,為什么另一個沒有,並且想要了解潛在的問題。 我認為也可以幫助其他人理解。 這正是我想要做的:
打開現有的xlsx文件,向其中添加工作表,並將其保存為與其原始文件相同的文件名。 實質上,只需修改現有的xlsx文件即可添加工作表。
下面是不起作用的代碼,以及執行的代碼,我想知道為什么使用File對象不起作用。在這兩個示例中,我已經使用名為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中出現無法讀取內容的錯誤,當我選擇修復時,我可以打開它,它只有Voucher_1。 顯然使用WorkbookFactory.create和File對象不起作用,使用FileInputStream的情況不行,但我想知道我對File vs FileInputStream的理解與此問題有關。
非常感謝您的澄清,我真的很感激! 保羅
我相信使用File
與WorkbookFactory
用於讀取Workbook
,然后寫入同一 Workbook
- File
是不是一個好主意,直到如今。 apache POI文檔提到:
文件與InputStreams
打開工作簿(.xls HSSFWorkbook或.xlsx XSSFWorkbook)時,可以從File或InputStream加載工作簿。 使用File對象可以降低內存消耗,而InputStream需要更多內存,因為它必須緩沖整個文件。
但是為什么使用File對象可以降低內存消耗? 這是因為Workbookfactory
然后創建一個RandomAccessFile
,它不需要在內存中完全讀取。 要驗證請閱讀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
。 所以我們不能寫它,也不能關閉它而不關閉整個Workbook
。 因此,在上面的示例中,當Workbook.write(FileOutputStream)
嘗試編寫文件時,將打開RandomAccessFile
進行讀寫(rw模式)。
因此,使用File
可能適合只讀或從一個文件讀取並保存到另一個文件。 但是直到現在,使用File
來讀取和寫入同一個文件並不是一個好主意。 對於這個FileInputStream
和FileOutputStream
更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.