I don’t know what am I doing wrong. I’m just reading and writing an Excel file, but always get this 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 exists and has the number “1” in each cell from A1 to L50.
Advertisement
Answer
You are attempting to write the Workbook
back to the same file pathname from which it was read. It appears that WorkbookFactory.create
doesn’t “release resources” until the Workbook
is closed.
Note that in order to properly release resources the Workbook should be closed after use.
When you create the FileOutputStream
, you have effectively erased the existing file so that you can write the file data out. However, the Workbook
must still rely on the original file being intact. Then, the data to write no longer exists.
You will need to write to a different temporary filename first. Use Apache POI 3.11 or later, so you can call close()
on the Workbook
, releasing resources.
Close the underlying input resource (File or Stream), from which the Workbook was read. After closing, the Workbook should no longer be used.
This means that the original file must exist until we’re done writing it, so the write must be to another (temporary) file.
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(); }
Then you can delete the original file and rename the newly created temporary file to the original name.
boolean deleteSuccess = srcFile.delete(); boolean renameSuccess = destFile.renameTo(srcFile);