Whenever I write a XSSFWorkbook out using XSSFWorkbook.write, the book afterwards is left in a state where calling getColumnWidth on one of its sheet causes an IndexOutOfBoundsException. Below is a unit test that isolates the problem (in this case it creates a new Workbook and constucts a sheet and cells, but I also have the same problem when starting from an existing workbook loaded through WorkbookFactory). @Test public void testColumnWidthPOI() throws Exception { XSSFWorkbook workbook = new XSSFWorkbook(); XSSFSheet sheet = workbook.createSheet(); XSSFRow row = sheet.createRow(0); XSSFCell cell = row.createCell(0); cell.setCellValue("hello world"); assertEquals("hello world",workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue()); assertEquals(2048,workbook.getSheetAt(0).getColumnWidth(0)); //<-works //gets a UUID based temporary file File tmpDir = new File(System.getProperty("java.io.tmpdir")); String uuid = UUID.randomUUID().toString(); File f = new File(tmpDir,uuid+".xlsx"); BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(f)); workbook.write(stream); stream.close(); assertTrue(f.exists()); assertEquals("hello world",workbook.getSheetAt(0).getRow(0).getCell(0).getStringCellValue()); assertEquals(2048,workbook.getSheetAt(0).getColumnWidth(0)); //<- throws IndexOutOfBoundsException }
Analysis: Class ColumnHelper has a member worksheet of type CTWorksheetImpl. If I look at it before and after the call to write(), there is a line " <main:cols/>" missing after writing, so it seems writing is removing this line somehow. When looking more closely the onSave() call in XSSFWorkbook.write() invokes XSSFSheet.write(), which causes the removal via worksheet.setColsArray(null); I am not sure why the setColsArray() is done here and if not doing this would have side-effects, but it would solve the problem here and probably some others that are reported in some other Bugs when users try using a Workbook after writing it out once.
I have now removed the setting of colsarray to null in XSSFSheet.write() to not make the Workbook corrupt by writing it out. This fixes this bug, all existing unit tests still run fine, not sure why the code was there initiallly, also the SNV Log did not provide any useful information here.
Reopening this bug as I need to revert the changes done for this Bug for now as it breaks xlsx reading in Excel!
Fix differently now, it seems we need to set the colsArray to null in order to produce valid XLSX-files, so we restore the colsArray after writing the document out.