groovy 修改单元格公式后,Apache POI的FormulaEvaluator不起作用

jvlzgdj9  于 8个月前  发布在  Apache
关注(0)|答案(1)|浏览(91)

我正在使用Apache POI编写一些测试用例期望的电子表格.
到目前为止,这些期望都是以字符串单元格值的形式出现的。它们包含一些预期的美元金额...
下面是示例行:
| 会员ID| NPI编号|成员前缀|会员名|会员姓氏|成员后缀|付款频率(A,M,S,Q)|孩子是会员吗?|预期费用|预期频率折扣|预期家庭折扣|预计净额|预计分期付款总额|预期分期付款净额|测试用例步骤2是否通过?|
| --|--|--|--|--|--|--|--|--|--|--|--|--|--|--|
| 139 | 1209360364 ||2019 - 07 -28 01:28:49|随机成员||一|真正|2,362美元|三百二十六块|一百一十六块九毛一|1919.09美元|2,362美元|1919.09美元|真正|
我确保美元金额具有 * 会计数字格式 *。
我确实注意到需要让Excel计算预期净金额(一个单元格减去其他一些单元格的总和),而不是我的代码,通过输入这样的公式:

=I34-(J34+K34)

这在电子表格中起作用:按回车键后,计算值。然而,当我尝试以编程方式读取它时,我遇到了一些问题:
util方法:

public static double GetDollarAmount(Cell cell) { 
        switch (cell.getCellType()) { 
            case CellType.NUMERIC.code:
                return cell.getNumericCellValue();
            case CellType.STRING.code:
                return SMDNumberUtils.parseDouble(cell.getStringCellValue());
            case CellType.FORMULA.code:
                return cell.getSheet().getWorkbook()
                    .getCreationHelper()
                    .createFormulaEvaluator()
                    .evaluate(cell)
                    .getNumberValue();
                    
            default: 
                throw new IllegalStateException("Cell Type ${cell.getCellTypeEnum().name} not yet supported!")
        }
    }

对于公式类型的单元格失败,因为它返回0,而不是示例行中的1919.09。当我检查evaluate()调用返回的CellValue时,我看到了一个带有#VALUE!CellValue(通常在尝试对字符串值使用数值公式时抛出)
甚至当我试图调整代码重写公式时,通过在任何单元格引用周围 Package “VALUE()”:

public static double GetDollarAmount(Cell cell) { 
        switch (cell.getCellType()) { 
            case CellType.NUMERIC.code:
                return cell.getNumericCellValue();
            case CellType.STRING.code:
                return SMDNumberUtils.parseDouble(cell.getStringCellValue());
            case CellType.FORMULA.code:
                
                FormulaEvaluator evaluator = cell.getSheet().getWorkbook()
                    .getCreationHelper()
                    .createFormulaEvaluator();
            
                CellValue cellValue = evaluator.evaluate(cell);
                    
                if (!cellValue.getCellTypeEnum().equals(CellType.ERROR))
                    return cellValue.getNumberValue();
                    
                cell.setCellFormula(cell.getCellFormula()
                    .replaceAll(/[A-Z]+\d+/, { match ->
                        return "VALUE($match)"
                    }))
                
                return evaluator.evaluate(cell)
                    .getNumberValue();
                    
            default: 
                throw new IllegalStateException("Cell Type ${cell.getCellTypeEnum().name} not yet supported!")
        }
    }

它仍然失败,同样的问题!什么都没变,只是我们有了一个安全的配方!

我如何解决这个问题,因为我的测试框架Katalon Studio让我在Apache POIv3.17上卡住了?

wgxvkvu9

wgxvkvu91#

我能够解决这个问题,通过一些代码的调整:

public static double GetDollarAmount(Cell cell) { 
    switch (cell.getCellType()) { 
        case CellType.NUMERIC.code:
            return cell.getNumericCellValue();
        case CellType.STRING.code:
            return SMDNumberUtils.parseDouble(cell.getStringCellValue());
        case CellType.FORMULA.code:
            CellValue cellValue = this.EvaluateCellFormula(cell);
                
            if (!cellValue.getCellTypeEnum().equals(CellType.ERROR))
                return cellValue.getNumberValue();
                
            cell.setCellFormula(cell.getCellFormula()
                .replaceAll(/[A-Z]+\d+/, { match ->
                    return "VALUE($match)"
                }))
            
            return this.EvaluateCellFormula(cell)
                .getNumberValue();
                
        default: 
            throw new IllegalStateException("Cell Type ${cell.getCellTypeEnum().name} not yet supported!")
    }
}

public static CellValue EvaluateCellFormula(Cell cell) { 
    return cell.getSheet().getWorkbook()
            .getCreationHelper()
            .createFormulaEvaluator()
            .evaluate(cell)

看起来我们需要新的FormulaEvaluator每次我们evaluate().

相关问题