apache - org.apache.poi.ss.formula.eval.NotImplementedException : DATEDIF

标签 apache apache-poi

我在Excel工作表中使用了一个公式:=DATEDIF(TODAY(),E2,"y") & "years"& DATEDIF(TODAY(),E2,"ym") & "months "& DATEDIF (TODAY(),E2,"md") & "days"其中 E2 = 2015 年 8 月 14 日

在执行 HSSFFormulaEvaluator.evaluateAllFormulaCells(wb) 时,我收到异常

org.apache.poi.ss.formula.eval.NotImplementedFunctionException: DATEDIF

请帮忙。

最佳答案

从 Apache POI 版本 3.12 开始,不支持 DATEDIF()。您可以通过运行以下命令来检查支持哪些功能:

Collection<String> supportedFuncs = WorkbookEvaluator.getSupportedFunctionNames();

这个link描述如何编写用户定义的函数并将其注册到公式计算器:

Two base interfaces to start your implementation

All Excel formula function classes implement either org.apache.poi.hssf.record.formula.functions.Function or org.apache.poi.hssf.record.formula.functions.FreeRefFunction interface. Function is a common interface for the functions defined in the binary Excel format (BIFF8): these are "classic" Excel functions like SUM, COUNT, LOOKUP, etc. FreeRefFunction is a common interface for the functions from the Excel Analysis Toolpack and for User-Defined Functions. In the future these two interfaces are expected be unified into one, but for now you have to start your implementation from two slightly different roots.

Which interface to start from?

You are about to implement a function XXX and don't know which interface to start from: Function or FreeRefFunction. Use the following code to check whether your function is from the excel Analysis Toolpack:

if(AnalysisToolPack.isATPFunction(functionName)){
    // the function implements org.apache.poi.hssf.record.formula.functions.Function
} else {
    // the function implements org.apache.poi.hssf.record.formula.functions.FreeRefFunction
}

Walkthrough of an "evaluate()" implementation.

Here is the fun part: lets walk through the implementation of the excel function SQRT()

AnalysisToolPack.isATPFunction("SQRTPI") returns false so the base interface is Function. There are sub-interfaces that make life easier when implementing numeric functions or functions with fixed number of arguments, 1-arg, 2-arg and 3-arg function:

  • org.apache.poi.hssf.record.formula.functions.NumericFunction
  • org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction
  • org.apache.poi.hssf.record.formula.functions.Fixed2ArgFunction
  • org.apache.poi.hssf.record.formula.functions.Fixed3ArgFunction
  • org.apache.poi.hssf.record.formula.functions.Fixed4ArgFunction

Since SQRTPI takes exactly one argument we start our implementation from org.apache.poi.hssf.record.formula.functions.Fixed1ArgFunction:

Function SQRTPI = new Fixed1ArgFunction() {
    public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0) {
        try {
            // Retrieves a single value from a variety of different argument types according to standard
            // Excel rules.  Does not perform any type conversion.
            ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex);

            // Applies some conversion rules if the supplied value is not already a number.
            // Throws EvaluationException(#VALUE!) if the supplied parameter is not a number
            double arg = OperandResolver.coerceValueToDouble(ve);

            // this where all the heavy-lifting happens
            double result = Math.sqrt(arg*Math.PI);

            // Excel uses the error code #NUM! instead of IEEE _NaN_ and _Infinity_,
            // so when a numeric function evaluates to Double.NaN or Double.Infinity,
            // be sure to translate the result to the appropriate error code
            if (Double.isNaN(result) || Double.isInfinite(result)) {
                throw new EvaluationException(ErrorEval.NUM_ERROR);
            }

            return new NumberEval(result);
        } catch (EvaluationException e){
            return e.getErrorEval();
        }
    }
}

Now when the implementation is ready we need to register it in the formula evaluator:

WorkbookEvaluator.registerFunction("SQRTPI", SQRTPI);

Voila! The formula evaluator now recognizes SQRTPI!

-- https://poi.apache.org/components/spreadsheet/eval-devguide.html

关于apache - org.apache.poi.ss.formula.eval.NotImplementedException : DATEDIF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31129907/

相关文章:

macos - 在 Mac OS X Mountain Lion 上编译 apache2 的问题

regex - 在子文件夹中重写 .htaccess

php - Homebrew PHP 7.1 (macOS Sierra) Apache 语法错误

java - 仅在需要时以百分比和小数点显示小数位

java - Apache POI : Multiple cell comments in one cell are not allowed

java - Apache POI 无法检测哈希格式的数字

apache - 网站结帐在最新版本的 Chrome/Firefox 中不起作用; Apache SSL 密码问题

python - 在同一个 apache 服务器上运行 django 和 flask

java - 使用 Apache POI 打开电子表格时内存不足

java - Apache POI XWPF 添加形状到标题