2 回答
TA贡献1829条经验 获得超7个赞
apache poi
需要工作簿是正确的WorkbookEvaluator
。并且由于您正在谈论评估“类似 excel 公式的表达式”,这是必要的,因为此类公式中的所有变量都必须是该工作簿中的单元格引用或名称。您给出的示例CONCATENATE(a,b,c)
只能Excel
在a
,b
和c
是Excel
names 时用作公式。否则会#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。
TA贡献1875条经验 获得超3个赞
要使用 IF 函数,我必须创建一个 Cell 实例以防止出现 NullPointerException:
Cell cell = workbookWithVariables.getSheet(workbookWithVariables.getSheetName(0)).createRow(0).createCell(0);
CellReference reference = new CellReference(cell);
添加回答
举报