Java的Apache POI java.lang.IllegalArgumentException:位置21504超过文件的末尾

我不知道我做错了什么。 我只是读和写一个Excel文件,但总是得到这个exception:

java.lang.IllegalArgumentException: Position 21504 past the end of the file

 public class example { public static void main(String[] args) throws Exception { File destFile = new File("book.xls"); Workbook destBook = WorkbookFactory.create(destFile); try { FileOutputStream out = new FileOutputStream(destFile); destBook.write(out); out.close(); } catch (Exception e) { e.printStackTrace(); } } } 

book.xls存在并且在A1到L50的每个单元格中都有数字“1”。

您正在尝试将Workbook写回到与之相同的文件path名。 看来WorkbookFactory.create不会“释放资源”,直到Workbookclosures。

请注意,为了正确释放资源,工作簿应在使用后closures。

在创buildFileOutputStream ,已经有效地擦除了现有文件,以便可以将文件数据写出。 但是, Workbook仍然必须依赖原始文件完好无损。 然后,写入的数据不再存在。

您将需要先写入不同的临时文件名。 使用Apache POI 3.11或更高版本,以便您可以在Workbook上调用close() ,释放资源。

closures从中读取工作簿的底层input资源(文件或stream)。 closures后,应该不再使用工作簿。

这意味着原始文件必须存在,直到我们完成写入,所以写入必须是另一个(临时)文件。

 File srcFile = new File("book.xls"); File destFile = new File("booktemp.xls"); try { Workbook destBook = WorkbookFactory.create(srcFile); FileOutputStream out = new FileOutputStream(destFile); destBook.write(out); out.close(); destbook.close(); // Available in Apache POI 3.11! } catch (Exception e) { e.printStackTrace(); } 

然后,您可以删除原始文件并将新创build的临时文件重命名为原始名称。

 boolean deleteSuccess = srcFile.delete(); boolean renameSuccess = destFile.renameTo(srcFile);