【问题标题】:Apache POI can't format filled cells as numericApache POI 无法将填充单元格格式化为数字
【发布时间】:2017-06-07 08:13:13
【问题描述】:

我正在尝试更改 Apache POI 中已填充单元的 CellTypes,但我不断收到 IllegalStateException。使用 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();
}

此外,当没有为 c1 和 c2 设置任何 CellValue 时,您实际上可以将它们的 CellType 设置为 NUMERIC,然后代码突然又可以工作了。它也可以在没有 CTTable 的情况下工作。

有什么想法或解决方法吗?还是 POI 的错误(因为它尝试从任何 Cell 中获取字符串值,而不管 CellType 是什么)?

【问题讨论】:

  • 为什么要明确设置单元格类型?为什么不让 Apache POI 根据提供的值自动检测类型?
  • @Gagravarr 如代码 cmets 所述,“自动检测”的数字将使代码崩溃!我选择c1.setCellValue("12"); c1.setCellType(CellType.NUMERIC); 还是只选择c1.setCellValue(12); 都没有关系。事实是,如果最后,当我想将工作簿写入文件时,CTTable 中有任何数字单元格,它会抛出 IllegalStateException :(

标签: java excel exception apache-poi


【解决方案1】:

您需要使用 Apache POI 3.17 beta 1 或更高版本才能使其工作(或从 20170607 之后的每晚构建)

如果你这样做了,你也可以使你的代码更加简单和干净。如in the testNumericCellsInTable() unit test 所示,您的代码可以简化为:

    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)
    ));

(与您的问题代码不同,它混合了整数、浮点数和表头字符串,以显示各种选项)

【讨论】:

  • 我认为您的代码遗漏了一些强制转换并且方法名称错误,但除此之外,它可以在新版本中使用!该死的POI...
  • 我的代码是从 Apache POI 中通过的单元测试中剪切和粘贴的!不过,您需要从今天开始使用一个版本...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 2020-06-15
相关资源
最近更新 更多