在Apache POI中使用Excel PERCENTILE函数

我使用的是Apache POI 3.9,我需要使用Excel公式PERCENTILE,并从Java中评估公式。

问题是不支持PERCENTILE。

我得到一个org.apache.poi.ss.formula.eval.NotImplementedException:错误

我有3个可能的解决scheme,我的问题。

  1. 在java中编写我自己的percentile函数,并将其贡献给Apache POI库(请参阅http://poi.apache.org/spreadsheet/eval-devguide.html )

  2. 从Excel表单中的相关单元格转换为Java,并使用一个函数(如百分比计算中的函数)来计算它们

  3. 将PERCENTILE转换为小函数,例如=PERCENTILE(A1:A10,95%)然后=(SMALL(A1:A10,9)+SMALL(A1:A10,10))/2

在这个时候,我需要一个快速的解决scheme。 对我来说,第三个将是最好的,但是并没有给出完全相同的结果。

有没有人有任何想法之前,备选案文2备份有点杂乱?

谢谢Gagravarr为你的鼓励,也为你的后期Apache POI – 如何注册一个非常有用的function

我以如下方式在库中实现了PERCENTILE函数:

  1. 我下载了Apache POI 3.9的源代码
  2. 我检查了src / resources / main / org / apache / poi / ss / formula / function / functionMetadata.txt( 或联机 )中的PERCENTILE函数的ID号码,结果是328
  3. 我因此增加了retval[328] = AggregateFunction.PERCENTILE; 到文件org.apache.poi.ss.formula.eval.FunctionEval.java
  4. 我添加了public static final Function PERCENTILE = new Percentile(); 到相应位置的文件org.apache.poi.ss.formula.functions.AggregateFunction.java。
  5. 我在同一个文件中添加了下面的代码(我基于LargeSmall函数;我查找了与我想要做的最相似的函数的现有代码/types)

     private static final class Percentile extends Fixed2ArgFunction { protected Percentile() { } public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { double dn; try { ValueEval ve1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex); dn = OperandResolver.coerceValueToDouble(ve1); } catch (EvaluationException e1) { // all errors in the second arg translate to #VALUE! return ErrorEval.VALUE_INVALID; } if (dn < 0 || dn > 1) { // has to be percentage return ErrorEval.NUM_ERROR; } double result; try { double[] ds = ValueCollector.collectValues(arg0); int N = ds.length; double n = (N - 1) * dn + 1; if (n == 1d) { result = StatsLib.kthSmallest(ds, 1); } else if (n == N) { result = StatsLib.kthLargest(ds, 1); } else { int k = (int) n; double d = n - k; result = StatsLib.kthSmallest(ds, k) + d * (StatsLib.kthSmallest(ds, k + 1) - StatsLib.kthSmallest(ds, k)); } NumericFunction.checkValue(result); } catch (EvaluationException e) { return e.getErrorEval(); } return new NumberEval(result); } 

    }

  6. 然后,我分别上传这两个文件,然后可以正常使用PERCENTILEfunction。