无需使用Excel即可在Java中评估Excel /其他语言表达评估的库

时间:2019-08-02 10:20:00

标签: java excel excel-formula apache-poi expression-evaluation

我一直在互联网上寻找一个库,该库可以在Java中评估类似于excel公式的表达式。该公式未嵌入到excel中。

比方说,值也不在excel中。让我们说3个变量abc我想要Java中的一个赋值为CONCAT(a,b,c)的字符串的求值器。用excel表达式或其他语言编写的代码可以给我输出。

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

据我了解POIjxls已根据公式进行求值,我查看了Apache jsp.elpoi也查看了jxls嵌入到excel文件中,或者我们需要创建一个电子表格来实际运行公式,imo比在Java中运行公式要重。对于jsp.el,我必须定义自己的表达语言,但不够鲁棒。

2 个答案:

答案 0 :(得分:1)

<Icon name="md-beer" type="ionicon" color="#887700" /> 的{​​{1}}需要一个工作簿是正确的。而且,由于您正在谈论评估“类似于Excel公式的表达式”,因此这是必需的,因为此类公式中的所有变量必须是单元格引用或该工作簿中的名称。当apache poiWorkbookEvaluatorCONCATENATE(a,b,c)Excel名称时,给定的示例a只能用作b公式。否则,将导致c中的Excel错误。顺便说一句:#Name?函数是Excel而不是Excel

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

公式本身不必在工作表中的某个位置。由于存在WorkbookEvaluator.evaluate(java.lang.String formula, CellReference ref),因此该公式也可以作为字符串给出。

示例:

CONCATENATE

此代码已使用CONCAT测试。

请注意,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名称不能为ExcelExcel,因为这可能与可能的c单元格引用冲突。因此,我将自己的名字命名为CR1C1_a

答案 1 :(得分:1)

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

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