Hi there, when upgrading POI-OOXML from an ancient V 3.7 to latest stable 5.2.3, all of a sudden some code caused an IndexOutOfBoundsException when saving the document. Although it is getting thrown in XmlBeans, I guess its more at the XSSF side. Exception in thread "main" java.lang.IndexOutOfBoundsException at org.apache.xmlbeans.impl.store.Xobj.removeElement(Xobj.java:2099) at org.apache.xmlbeans.impl.store.Xobj.remove_element(Xobj.java:2130) at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.removeC(CTRowImpl.java:146) at org.apache.poi.xssf.usermodel.XSSFRow.fixupCTCells(XSSFRow.java:612) at org.apache.poi.xssf.usermodel.XSSFRow.onDocumentWrite(XSSFRow.java:582) at org.apache.poi.xssf.usermodel.XSSFSheet.write(XSSFSheet.java:3806) at org.apache.poi.xssf.usermodel.XSSFSheet.commit(XSSFSheet.java:3749) at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:467) at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:472) at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:221) at CreateExcel.writeToFile(CreateExcel.java:61) at CreateExcel.create(CreateExcel.java:23) at CreateExcel.main(CreateExcel.java:77) The problem was that in some function the first row of a sheet was overwritten 1x by mistake but the header cells have been set multiple times in a loop. Admitedly this is probably not a common use case, but maybe there could be checked something and a meaninful error could be thrown. Finding the main cause took us some hours because the Exception didn't ring anything :) below I pasted a small POC which triggers the Exception when the first row is clobbered twice (second run of the function). Best Martin import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.xssf.usermodel.*; import org.apache.poi.ss.usermodel.*; public class CreateExcel { private final String o_filename; public CreateExcel(String p_filename) { o_filename = p_filename; } public void create() { Workbook wb = new XSSFWorkbook(); fillData(wb, 1); writeToFile(wb); System.out.println("First file is ok"); wb = new XSSFWorkbook(); fillData(wb, 0); writeToFile(wb); } private void fillData(Workbook p_wb, int startAtRow) { Sheet sheet = p_wb.createSheet("sheet123"); Row header =sheet.createRow(0); boolean headerSet =false; for (int rownum =startAtRow; rownum< 4; rownum++) { // if (!headerSet) { fillRow(header,true); headerSet =true; // } Row row =sheet.createRow(rownum); fillRow(row, false); } } public void fillRow(Row row, boolean header) { String text =header ? "header " : "cell"; for (int i =0; i < 10; i++) { Cell cell =row.createCell(i); cell.setCellValue(text +i); } } private void writeToFile(Workbook p_wb) { FileOutputStream fileOut = null; try { fileOut = new FileOutputStream(o_filename); } catch (FileNotFoundException e) { e.printStackTrace(); } try { p_wb.write(fileOut); } catch (IOException e) { e.printStackTrace(); } try { if (fileOut != null) { fileOut.close(); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { CreateExcel createExcel = new CreateExcel("e://wobo.xlsx"); createExcel.create(); } }
Thanks for the nice report with reproducer code, it seems an invalid condition caused this and this was not covered by tests or production code at all until now. Should be fixed in the next release via r1909808