函数 RANK 有问题。Apache POI 中的均衡器

Problem with function RANK.EQ in Apache POI

提问人:vcima 提问时间:11/17/2023 更新时间:11/17/2023 访问量:47

问:

我目前正在从事一个涉及 Excel 工作表分析的 Java 项目。该项目建立在 Spring Boot 框架之上,利用 Apache POI 版本 5.2.4 进行 Excel 工作表处理。

虽然该应用程序通常运行良好,但我在某些文件中遇到了以下错误的问题:“_xlfn。排名.EQ.”

我试图通过更改Apache POI版本来解决此问题,但不幸的是,这并没有成功。关于如何解决这一问题的任何建议将不胜感激。

提前致谢!

java excel apache-poi

评论

1赞 Axel Richter 11/17/2023
_xlfn.RANK.EQ不是错误,而是以 为前缀的函数名。它以 Excel 为前缀,因为此函数的引入时间晚于 Office Open XML 的官方建议。那么你得到的确切错误是什么?请进行完整的堆栈跟踪。_xlfn
0赞 vcima 11/17/2023
嗨,@AxelRichter!.我的主要问题是我可以成功检索单元格值,因为此功能无法正常工作,我不知道如何解决它。
1赞 Axel Richter 11/17/2023
如果只是获取单元格值,那么从 Apache POI 5.2.0 开始,不需要公式计算。现在可以获取 Excel 上次保存时评估的公式结果。请参见 stackoverflow.com/questions/7608511/...DataFormatter.setUseCachedValuesForFormulaCells
0赞 vcima 11/17/2023
对不起@AxelRichter,我需要在每个单元格中计算公式才能获得正确的值
1赞 Axel Richter 11/17/2023
然后,您需要为尚不支持的函数实现自己的 Java 代码。请参见 poi.apache.org/components/spreadsheet/eval-devguide.html。您可以向 Apache POI 提交增强请求。或者你尝试自己,当你遇到困难时,在这里问一个具体的问题。

答:

1赞 Axel Richter 11/17/2023 #1

RANK.EQ 函数尚未在 Apache POI 中实现。

因此,您可以向 Apache POI 提交增强请求以实施它。或者,您需要为尚不支持的函数实现自己的 Java 代码。请参阅开发公式评估

但似乎并且正在做完全相同的事情。并在 Apache POI 中实现。RANK.EQRANKRANK

因此,所有需要做的就是评估与 相同的 .这可以通过实现 as 来完成,它使用 .RANK.EQRANKRANK.EQorg.apache.poi.ss.formula.functions.FreeRefFunctionorg.apache.poi.ss.formula.functions.Rank

法典:EvaluateRankEQ.java

import java.io.FileInputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
import org.apache.poi.ss.formula.udf.DefaultUDFFinder;
import org.apache.poi.ss.formula.udf.UDFFinder;

public class EvaluateRankEQ {

 public static void main( String[] args ) throws Exception {
  Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelWithRankEQ.xlsx"));    
    
  String[] functionNames = { "_xlfn.Rank.EQ" } ;
  FreeRefFunction[] functionImpls = { new RankEQ() } ;
  UDFFinder udfs = new DefaultUDFFinder( functionNames, functionImpls ) ;
  UDFFinder udfToolpack = new AggregatingUDFFinder( udfs ) ;    
  workbook.addToolPack(udfToolpack);
  
  FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
    
  for (Sheet sheet: workbook) {
   for (Row row : sheet) {
    for (Cell cell : row) {
     CellValue cellValue = formulaEvaluator.evaluate(cell);
     System.out.println(cellValue);
    }
   }   
  }

  workbook.close();
  
 }
}

这是使用:RankEQ.java

import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.formula.functions.Rank;

public final class RankEQ implements FreeRefFunction {
    
 @Override
 public ValueEval evaluate( ValueEval[] args, OperationEvaluationContext ec ) {

  if (args.length == 2) {
   Rank rank = new Rank();
   return rank.evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1]);  
  } else if (args.length == 3) {
   Rank rank = new Rank();
   return rank.evaluate(ec.getRowIndex(), ec.getColumnIndex(), args[0], args[1], args[2]);  
  }
 
  return ErrorEval.VALUE_INVALID;
 }
}