Apache POI:为什么我在 if 语句中使用 Cell.getCellType() 得到空指针异常,如果单元格为空则不会发生?

Apache POI: Why am I getting a null pointer exception with Cell.getCellType() within an if statement that doesn't occur if the cell is null?

我正在创建一个 Groovy 脚本以将表从 .xlsm 文件导出到 .csv 文件,其中包括适当的公式(而不是生成的数据)。当脚本在当前单元格上调用 .getCellType() 时,我得到一个空指针异常,即使此功能发生在测试单元格是否为空的 if 语句中。

我试过更换

if(cell != null) 

条件为

if(cell.getCellType() != CellType.BLANK)

无果。

代码和完整的错误消息如下。

    #!/usr/bin/env groovy

    @Grab(group = 'org.apache.poi', module = 'poi', version = '4.1.0')
    @Grab(group = 'org.apache.poi', module = 'poi-ooxml', version = '4.1.0')

    import org.apache.poi.xssf.usermodel.XSSFWorkbook
    import org.apache.poi.xssf.usermodel.*
    import org.apache.poi.ss.usermodel.*


    Workbook wb = new XSSFWorkbook("input.xlsm")

    FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator()

    DataFormatter formatter = new DataFormatter()
    PrintStream out = new PrintStream(new FileOutputStream("output.csv"), true, "UTF-8")
    byte[] bom = [(byte)0xEF, (byte)0xBB, (byte)0xBF]
    out.write(bom)

    for (Sheet sheet : wb){
        for (Row row : sheet) {
            boolean firstCell = true
            for(Cell cell : row){
                if (! firstCell) out.print(',')
                if ( cell != null ) {
                    if (fe != null) cell = fe.evaluateInCell()
                    String value = formatter.formatCellValue(cell)
                    if (cell.getCellType() == CellType.FORMULA) {
                        value = "=" + value
                    }
                    out.print(value)
                }

                firstCell = false
            }
            out.println()
        }
    }

错误信息:

Caught: java.lang.NullPointerException: Cannot invoke method 
getCellType() on null object java.lang.NullPointerException: 
Cannot invoke method getCellType() on null object
at ExcelToCSV.run(ExcelToCSV.groovy:28)

我的期望是,在当前单元格不为空的情况下,如果单元格被评估为包含公式,则输出到 .csv 文件的字符串将在其开头附加一个“=” , 否则它只会输出表示单元格内值的字符串。

不幸的是,我在 IDE 跳过断点时遇到问题,目前我无法单步执行代码或查看变量值,这是我也在处理的另一个问题。在我解决这个问题之前,我希望有人能够指出我可能遗漏了什么。

您在 null 检查之后但在调用 cell 方法之前分配给 cell。该赋值必须是空值。

evaluateInCell 接受类型为 Cell 的参数,因此如果您替换行

if (fe != null) cell = fe.evaluateInCell()
// cell == null

if (fe != null) cell = fe.evaluateInCell(cell)

然后你就得到了 javadocs 所说的你应该得到的,它是简单值的未更改单元格或公式的公式结果。

我想您还会发现单元格类型会发生变化以反映公式计算返回值的类型,因此您对 CellType.FORMULA 的测试将始终为假。