我一直在互联网上寻找一个库,该库可以在Java中评估类似于excel公式的表达式。该公式未嵌入到excel中。
比方说,值也不在excel中。让我们说3个变量a
,b
,c
我想要Java中的一个赋值为CONCAT(a,b,c)
的字符串的求值器。用excel表达式或其他语言编写的代码可以给我输出。
我在网上找到了一些用于Java的表达式评估器库,但是我需要定义自己的表达式语言,是否有一些直接使用excel语言或其他语言的东西?
据我了解POI
和jxls
已根据公式进行求值,我查看了Apache jsp.el
和poi
也查看了jxls
嵌入到excel文件中,或者我们需要创建一个电子表格来实际运行公式,imo
比在Java中运行公式要重。对于jsp.el
,我必须定义自己的表达语言,但不够鲁棒。
答案 0 :(得分:1)
<Icon name="md-beer" type="ionicon" color="#887700" />
的{{1}}需要一个工作簿是正确的。而且,由于您正在谈论评估“类似于Excel公式的表达式”,因此这是必需的,因为此类公式中的所有变量必须是单元格引用或该工作簿中的名称。当apache poi
,WorkbookEvaluator
和CONCATENATE(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
名称不能为Excel
或Excel
,因为这可能与可能的c
单元格引用冲突。因此,我将自己的名字命名为C
,R1C1
和_a
。
答案 1 :(得分:1)
要使用IF函数,我必须创建一个Cell实例来防止NullPointerException:
Cell cell = workbookWithVariables.getSheet(workbookWithVariables.getSheetName(0)).createRow(0).createCell(0);
CellReference reference = new CellReference(cell);