在不使用 excel 的情况下在 java 中评估 excel/other 语言表达式评估的库

Library to evaluate excel/other language expression evaluation in java without using excel

我一直在互联网上搜索可以计算 java 中的 excel 类公式表达式的库 该公式未嵌入 excel.

假设,值也不在 excel 假设 3 个变量 abc 我想要一个评估器 java给定一个用 excel 表达式或其他语言编写的 CONCAT(a,b,c) 字符串,可以给我输出。

我在网上找到了一些java的表达式计算器库,但是我需要定义自己的表达式语言,有没有直接使用excel语言或其他语言的东西?

据我所知,我看过 apache POIjxls 也看过 jsp.el poijxls 从公式已经嵌入 excel 文件中,或者我们需要创建一个电子表格来实际 运行 公式,其中 imo 将比 运行 宁 java 中的公式].对于 jsp.el 我将不得不定义我自己的表达式语言,它不够健壮。

apache poiWorkbookEvaluator 需要练习册是正确的。由于您正在谈论评估 "excel formula-like expressions",这是必要的,因为此类公式中的所有变量都必须是该工作簿中的单元格引用或名称。当 abcExcel names 时,您给出的示例 CONCATENATE(a,b,c) 只能用作 Excel 公式。否则会导致 Excel 中的 #Name? 错误。顺便说一句:Excel 函数是 CONCATENATE 而不是 CONCAT.

但是这个工作簿不一定存放在某个地方。它也只能在随机存取存储器中。

并且公式本身不需要在 sheet 的某个地方。公式也可以作为字符串给出,因为有 WorkbookEvaluator.evaluate(java.lang.String formula, CellReference ref).

示例:

import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Name;

import org.apache.poi.ss.formula.BaseFormulaEvaluator;
import org.apache.poi.ss.formula.WorkbookEvaluator;

import org.apache.poi.ss.formula.eval.*;

import org.apache.poi.ss.util.CellReference;

public class EvaluateExcelFunctions {

 static Object evaluateExcelFormula(String formula, Workbook workbookWithVariables) {
  if (workbookWithVariables.getNumberOfSheets() < 1) workbookWithVariables.createSheet();
  CellReference reference = new CellReference(workbookWithVariables.getSheetName(0), 0 , 0, false, false);
  CreationHelper helper = workbookWithVariables.getCreationHelper();
  FormulaEvaluator formulaevaluator = helper.createFormulaEvaluator();
  WorkbookEvaluator workbookevaluator = ((BaseFormulaEvaluator)formulaevaluator)._getWorkbookEvaluator();
  ValueEval valueeval = null;
  try {
   valueeval = workbookevaluator.evaluate(formula, reference);
  } catch (Exception ex) {
   return ex.toString();
  }
  if (valueeval instanceof StringValueEval) {
   String result = ((StringValueEval)valueeval).getStringValue();
   return result;
  } else if (valueeval instanceof NumericValueEval) {
   double result = ((NumericValueEval)valueeval).getNumberValue();
   return result;
  } else if (valueeval instanceof ErrorEval) {
   String result = ((ErrorEval)valueeval).getErrorString();
   return result;
  }
  return null;  
 }

 public static void main(String[] args) throws Exception {

  Workbook workbook = 
   //new XSSFWorkbook();
   new HSSFWorkbook();

  Name name;
  String formula;
  Object result;

  // example 1 concatenating strings - your example
  name = workbook.createName();
  name.setNameName("_a");
  name.setRefersToFormula("\"Text A \"");
  name = workbook.createName();
  name.setNameName("_b");
  name.setRefersToFormula("\"Text B \"");
  name = workbook.createName();
  name.setNameName("_c");
  name.setRefersToFormula("\"Text C \"");

  formula = "CONCATENATE(_a, _b, _c)";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  // example 2 Pythagorean theorem
  name = workbook.getName("_a"); 
  name.setRefersToFormula("12.34");
  name = workbook.getName("_b");
  name.setRefersToFormula("56.78");

  formula = "SQRT(_a^2 + _b^2)";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  // example 3 complex math formula
  name = workbook.getName("_a"); 
  name.setRefersToFormula("12.34");
  name = workbook.getName("_b");
  name.setRefersToFormula("56.78");
  name = workbook.getName("_c");
  name.setRefersToFormula("90.12");

  formula = "((_a+_b+_c)*_c/_b-_a)/2";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  // example 4 faulty formulas
  name = workbook.getName("_a"); 
  name.setRefersToFormula("56.78");
  name = workbook.getName("_b");
  name.setRefersToFormula("190.12");
  name = workbook.getName("_c");
  name.setRefersToFormula("\"text\"");

  formula = "_a + _c";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  formula = "((_a + _b";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  formula = "_a \ 2";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  formula = "_a^_b";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  formula = "_a/(_b-_b)";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  formula = "CONCAT(_a, _b)";
  result = evaluateExcelFormula(formula, workbook);
  System.out.println(result);

  workbook.close();
 }  
}

此代码已使用 apache poi 4.1.0 进行测试。

注意,Excel 名称不能是所有可能的变量名称。例如,Excel 名称不能是 cC,因为这会与可能的 R1C1 单元格引用发生冲突。这就是为什么我将自己的名字命名为 _a_b_c.

要使用 IF 函数,我必须创建一个 Cell 实例以防止 NullPointerException:

Cell cell = workbookWithVariables.getSheet(workbookWithVariables.getSheetName(0)).createRow(0).createCell(0);
CellReference reference = new CellReference(cell);