Reputation: 2771
I am trying to change CellTypes of already filled Cells in Apache POI, but I keep getting an IllegalStateException. The problem should be reproduceable using POI(-ooxml) 3.16.
public static void main(String[] args) throws Exception
{
//Setting up the workbook and the sheet
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet s = wb.createSheet();
//Setting up the CTTable
XSSFTable t = s.createTable();
CTTable ctt = t.getCTTable();
ctt.setId(1);
ctt.setName("CT Table Test");
ctt.setRef("A1:B2");
CTTableColumns cttcs = ctt.addNewTableColumns();
CTTableColumn cttc1 = cttcs.addNewTableColumn();
cttc1.setId(1);
CTTableColumn cttc2 = cttcs.addNewTableColumn();
cttc2.setId(2);
//Creating the cells
XSSFCell c1 = s.createRow(0).createCell(0);
XSSFCell c2 = s.getRow(0).createCell(1);
XSSFCell c3 = s.createRow(1).createCell(0);
XSSFCell c4 = s.getRow(1).createCell(1);
//Inserting values; some numeric strings, some alphabetical strings
c1.setCellValue(/*12*/"12"); //Numbers have to be inputted as a string
c2.setCellValue(/*34*/"34"); //for the code to work
c3.setCellValue("AB");
c4.setCellValue("CD");
//With those lines, the code would also crash
//c1.setCellType(CellType.NUMERIC);
//c2.setCellType(CellType.NUMERIC);
//On write() it produces a "java.lang.IllegalStateException: Cannot get a STRING value from a NUMERIC cell"
FileOutputStream fos = new FileOutputStream("test.xlsx");
wb.write(fos);
fos.flush();
fos.close();
wb.close();
}
Also, when not setting any CellValue for c1 and c2, you can actually set their CellType to NUMERIC and suddenly the code works again. It also works without the CTTable.
Any ideas or workarounds? Or is it a bug of POI (since it tries fetching a string value from any Cell regardless of its CellType)?
Upvotes: 1
Views: 742
Reputation: 48326
You need to use Apache POI 3.17 beta 1 or later for this to work (or a nightly build from after 20170607)
If you do, you can also make your code significantly simpler and cleaner too. As shown in the testNumericCellsInTable()
unit test, your code could simplify to something like:
Workbook wb = new XSSFWorkbook();
Sheet s = wb.createSheet();
// Create some cells, some numeric, some not
Cell c1 = s.createRow(0).createCell(0);
Cell c2 = s.getRow(0).createCell(1);
Cell c3 = s.getRow(0).createCell(2);
Cell c4 = s.createRow(1).createCell(0);
Cell c5 = s.getRow(1).createCell(1);
Cell c6 = s.getRow(1).createCell(2);
c1.setCellValue(12);
c2.setCellValue(34.56);
c3.setCellValue("ABCD");
c4.setCellValue("AB");
c5.setCellValue("CD");
c6.setCellValue("EF");
// Setting up the CTTable
Table t = s.createTable();
t.setName("TableTest");
t.setDisplayName("CT_Table_Test");
t.addColumn();
t.addColumn();
t.addColumn();
t.setCellReferences(new AreaReference(
new CellReference(c1), new CellReference(c6)
));
(Unlike your problem code, this does a mixture of integers, floating point numbers and strings for the table headers, to show the various options)
Upvotes: 2