0

在评估工作簿中的单元格时,我看到了异常错误。对于上下文,POI 用于使用定义的名称将值输入到 Excel 工作簿中。Excel 然后接受输入并进行各种计算和查找以计算一组输出量,根据它对应的美国州的不同,处理方式不同。我看到的问题是,当评估一组特定的工作表时(我们将在此上下文中使用佛罗里达州),它们的单元格评估为org.apache.poi.ss.formula.eval.ErrorEval [#REF!],从而破坏所有输出值。通常,当我得到不正确的输出时,我可以通过在插入所有输入后保存电子表格来快速找到它们,评估工作簿(使用evaluateAll()),然后将更新的“调试器”版本保存到我的本地计算机。然而,这个问题是,当我检查更新版本时,我的输出量似乎已成功计算,我没有看到任何 #RREF!工作簿中任何地方的错误。

使用各种输入值组合,这表明仅指向一组特定的工作表会导致错误。

更改从 FormulaEvaluatorsevaluateFormulaCell(cell)函数评估工作表的方式,然后在将 cellValue 作为字符串返回的开关中解析响应,以简单地使用evaluateAll().

删除所有指向工作簿的外部链接,并删除潜在麻烦工作表上的条件格式。

启用 POI 日志以尝试查找问题的根本原因。

clearAllCachedResultValues()在执行评估之前使用 FormulaEvaluator 清除缓存的值。

最后确保没有任何电子表格包含任何不受支持的 POI 公式与 FunctionEvalgetSupportedFunctionNames()getNotSupportedFunctionNames().

这些是显示 ErrorEval[#REF!] 问题的第一个 POI 日志。

    ...
    DEBUG - Evaluated Assumed Census!C41 to org.apache.poi.ss.formula.eval.NumberEval [0.0714285714285714]
    DEBUG - Evaluated Lookup Table 1!D41 to org.apache.poi.ss.formula.eval.NumberEval [0.0662525879917184]
    DEBUG - Evaluated Lookup Table 1!E41 to org.apache.poi.ss.formula.eval.NumberEval [0.13768115942029]
    DEBUG - Evaluated Lookup Table 1!E57 to org.apache.poi.ss.formula.eval.NumberEval [0.0196687370600414]
    DEBUG - Evaluated Calc Table 2 FL!O4 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Calc Table 2 FL!O88 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!E165 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!D165 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!D198 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Calc Table 2 FL!Q4 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Calc Table 2 FL!Q88 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!E167 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!D167 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!D200 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Calc Table 2 FL!P4 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Calc Table 2 FL!R4 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Calc Table 2 FL!R88 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    DEBUG - Evaluated Input Sheet!E168 to org.apache.poi.ss.formula.eval.ErrorEval [#REF!]
    ...

此外,这也是当前评估电子表格的方式。

    when (evaluator.evaluateFormulaCell(cell)) {
        CellType.NUMERIC -> cell.numericCellValue
        CellType.STRING -> cell.stringCellValue.toString().toDoubleOrNull() ?: 0.0
        CellType.BOOLEAN -> cell.booleanCellValue.toString().toDoubleOrNull() ?: 0.0
        CellType.ERROR -> cell.errorCellValue.toString().toDoubleOrNull() ?: 0.0
        else -> cell.toString().toDoubleOrNull() ?: 0.0
    }

预期结果是调试器工作表中输出单元格上的值,但结果中的输出值为 0 或 23。调试器电子表格不包含任何 #REF!在使用输入处理并由 POI 评估后出现错误,而是显示我通常期望的有效值。

更新:还尝试将评估更改为evaluator.evaluate(cell).cellType在 switch 语句中使用,现在调试器电子表格显示#REF!到处; 但是,查看 excel 中的所有错误并不能真正帮助指出其根本原因。手动输入值时,电子表格也会正确计算。

4

1 回答 1

0

在工作Calc Table 2 FL表中,该OFFSET公式用于非常大的查询(超过 255 列)。在挖掘 Apache POI 源代码后createOffset,我们能够找到:

    if (absRows.isOutOfBounds(0, 65535)) {
        throw new EvaluationException(ErrorEval.REF_INVALID);
    }

因此,对于 POI,此函数中的列数存在有意限制。我不知道为什么,但肯定想听听它为什么存在

于 2019-06-11T16:11:33.513 回答