Apache POI:为什么在单元格为null的if语句中,Cell.getCellType()会出现null指针异常?

时间:2019-06-07 16:47:21

标签: apache groovy apache-poi xssf

我正在创建一个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)

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

很不幸,我的IDE跳过断点时遇到问题,目前我无法单步执行代码或查看变量值,这是我正在研究的另一个问题。在我解决问题之前,我希望有人能够指出我可能会缺少的东西。

1 个答案:

答案 0 :(得分:1)

您将在执行空检查之后但在调用cell方法之前分配给cell。该分配必须为空值。

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

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

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

然后您将得到javadocs说的应该得到的内容,对于简单值或公式的公式结果,该单元格保持不变。

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