为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

胡说叔叔 2023-05-10 15:12:00
我一直在互联网上搜索可以在 java 中评估类似 excel 公式的表达式的库 该公式未嵌入 excel 中。比方说,这些值也不在 excel 中 比方说 3 个变量,,a我想要一个 java 中的求值器,它给定一个像用 excel 表达式或其他语言写的字符串,可以给我输出。bcCONCAT(a,b,c)我在网上找到了一些java的表达式计算器库,但是我需要定义自己的表达式语言,有没有直接使用excel语言或其他语言的东西?我查看了 apache POI,jxls也查看了jsp.el我所了解的poi,并jxls根据已经嵌入到 excel 文件中的公式进行了评估,或者我们需要创建一个电子表格来实际运行该公式,这imo将比在 java 中运行该公式更重。因为jsp.el我必须定义我自己的表达语言,它不够健壮。
查看完整描述

2 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

apache poi需要工作簿是正确的WorkbookEvaluator。并且由于您正在谈论评估“类似 excel 公式的表达式”,这是必要的,因为此类公式中的所有变量都必须是该工作簿中的单元格引用或名称。您给出的示例CONCATENATE(a,b,c)只能Excela,bcExcelnames 时用作公式。否则会#Name?导致Excel. 顺便说一句:Excel函数是CONCATENATE而不是CONCAT

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

公式本身不需要在工作表中的某个地方。该公式也可以作为字符串给出,因为有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名称不能是c或,因为这会与可能的单元格引用C发生冲突。R1C1这就是为什么我命名我的名字_a,_b和_c。


查看完整回答
反对 回复 2023-05-10
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

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


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

CellReference reference = new CellReference(cell);


查看完整回答
反对 回复 2023-05-10
  • 2 回答
  • 0 关注
  • 233 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信