我将Apache POI的how to register custom functions网站上的教程阅读到FormulaEvaluator中,我想用它来定义POI不提供支持的函数MINVERSE。所以,首先我创建了一个定义MINVERSE的类(仅用于测试目的,我定义MINVERSE总是返回值10)。因此,这里是MINVERSE.java:Apache POI - 如何注册一个函数
package simpleboxapi;
import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
public class MINVERSE implements FreeRefFunction{
@Override
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
return new NumberEval(10);
}
}
后来我试过的东西真的很简单:我创建了下面的Excel表:
A1是一个给定的常量和A2是A2 = MINVERSE(A1 )
这里是我的主类代码:
package simpleboxapi;
import java.io.*;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
import org.apache.poi.ss.formula.udf.DefaultUDFFinder;
import org.apache.poi.ss.formula.udf.UDFFinder;
import org.apache.poi.ss.usermodel.*;
public class SimpleBoxAPI {
static String fileName = "workbook.xls";
static Workbook wb;
private static double updateInputVal(String cell, double val) throws IOException, InvalidFormatException{
InputStream inp = new FileInputStream(fileName);
wb = WorkbookFactory.create(inp);
CellReference crInput = new CellReference(cell);
Sheet sheet = wb.getSheetAt(0);
Row rowInput = sheet.getRow(crInput.getRow());
Cell cellInput = rowInput.getCell(crInput.getCol());
cellInput.setCellValue(val);
FileOutputStream fileOut = new FileOutputStream(fileName);
wb.write(fileOut);
fileOut.close();
double cellContents = cellInput.getNumericCellValue();
inp.close();
return cellContents;
}
private static void registerMINVERSE(){
String[] functionNames = {"MINVERSE"};
FreeRefFunction[] functionImpls = {new MINVERSE()};
UDFFinder udfs = new DefaultUDFFinder(functionNames, functionImpls);
UDFFinder udfToolpack = new AggregatingUDFFinder(udfs);
wb.addToolPack(udfToolpack);
}
public static void main(String[] args) throws Exception {
double updatedValue = updateInputVal("A1",55);
System.out.println(updatedValue);
registerMINVERSE();
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
CellReference cr = new CellReference("A2");
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(cr.getRow());
Cell cell = row.getCell(cr.getCol());
System.out.println(evaluator.evaluate(cell).getNumberValue());
}
}
然而,每当我尝试执行它时,我得到以下错误:
org.apache.poi.ss.formula.eval.NotImplementedException: Error evaluating cell 'new sheet'!A2
at org.apache.poi.ss.formula.WorkbookEvaluator.addExceptionInfo(WorkbookEvaluator.java:356)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:297)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluate(WorkbookEvaluator.java:229)
at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluateFormulaCellValue(HSSFFormulaEvaluator.java:354)
at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluate(HSSFFormulaEvaluator.java:185)
at simpleboxapi.SimpleBoxAPI.main(SimpleBoxAPI.java:56)
Caused by: org.apache.poi.ss.formula.eval.NotImplementedException: MINVERSE
at org.apache.poi.ss.formula.functions.NotImplementedFunction.evaluate(NotImplementedFunction.java:42)
at org.apache.poi.ss.formula.OperationEvaluatorFactory.evaluate(OperationEvaluatorFactory.java:132)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateFormula(WorkbookEvaluator.java:491)
at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:287)
... 4 more
有什么建议吗?提前感谢!
是MINVERSE你的自定义功能,抑或是简单地从当前的设定被Apache POI实现那些缺少一个标准的Excel函数? – Gagravarr 2012-04-24 15:07:20
@Gagravarr MINVERSE是Excel的标准功能。它返回矩阵的逆。我可以在Java中实现它,并将进行计算的类注册到评估程序,但是由于某种原因,我不能解释,因为我在我的问题中解释了这个问题。 – 2012-04-24 15:20:14