使用Apache POI 5.3.0调用WORKDAY函数evaluate时抛出IllegalStateException
问题结论
这是Apache POI v5.3.0中的已知Bug,并非API使用错误,该问题已被提交为Bug 69418。
问题详情
使用Apache POI v5.3.0时,当WORKDAY函数的Days参数为单元格引用(如WORKDAY(TODAY(), A1)),调用公式计算器的evaluate()方法会抛出IllegalStateException。堆栈跟踪显示问题根源在于OperandResolver.coerceValueToDouble方法无法处理LazyRefEval类型的参数。
而当Days参数为常量(如WORKDAY(TODAY(), 3))或嵌套函数调用(如WORKDAY(TODAY(), INT(A1)))时,公式可正常计算并返回预期结果。
临时解决办法
捕获IllegalStateException后,直接调用对应Cell的getNumericCellValue()方法获取预计算值。
代码示例
package org.example.poi; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class FormulaISE { private static final String LOG_KEY = "log4j2.loggerContextFactory"; private static final String LOG_VALUE = "org.apache.logging.log4j.simple.SimpleLoggerContextFactory"; public static void main(String[] args) { System.setProperty(LOG_KEY, LOG_VALUE); var book = new XSSFWorkbook(); var sheet = book.createSheet(); var row = sheet.createRow(0); var cellA1 = row.createCell(0); cellA1.setCellValue(3); var cellB1 = row.createCell(1); // 正常情况:常量参数 //cellB1.setCellFormula("WORKDAY(TODAY(), 3)"); // 触发Bug的情况:单元格引用参数 cellB1.setCellFormula("WORKDAY(TODAY(), A1)"); // 正常情况:函数嵌套调用参数 //cellB1.setCellFormula("WORKDAY(TODAY(), INT(A1))"); var eval = book.getCreationHelper().createFormulaEvaluator(); try { var cellValue = eval.evaluate(cellB1); if (cellValue.getCellType().equals(CellType.NUMERIC)) { System.out.println(DateUtil.getLocalDateTime(cellValue.getNumberValue())); } } catch (IllegalStateException e) { // 临时解决:直接获取单元格预计算值 if (cellB1.getCellType() == CellType.NUMERIC) { System.out.println(DateUtil.getLocalDateTime(cellB1.getNumericCellValue())); } e.printStackTrace(); } } }
堆栈跟踪
Exception in thread "main" java.lang.IllegalStateException: Failed to evaluate cell: Sheet0!B1, value: WORKDAY(TODAY(), A1) at org.apache.poi.xssf.usermodel.BaseXSSFFormulaEvaluator.evaluateFormulaCellValue(BaseXSSFFormulaEvaluator.java:76) at org.apache.poi.ss.formula.BaseFormulaEvaluator.evaluate(BaseFormulaEvaluator.java:109) at org.example.poi.FormulaISE.main(FormulaISE.java:27) Caused by: java.lang.IllegalStateException: Unexpected arg eval type (org.apache.poi.ss.formula.LazyRefEval) at org.apache.poi.ss.formula.eval.OperandResolver.coerceValueToDouble(OperandResolver.java:270) at org.apache.poi.ss.formula.atp.ArgumentsEvaluator.evaluateNumberArg(ArgumentsEvaluator.java:116) at org.apache.poi.ss.formula.atp.WorkdayFunction.evaluate(WorkdayFunction.java:67) at org.apache.poi.ss.formula.UserDefinedFunction.evaluate(UserDefinedFunction.java:77) at org.apache.poi.ss.formula.OperationEvaluatorFactory.evaluate(OperationEvaluatorFactory.java:135) at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateFormula(WorkbookEvaluator.java:537) at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:264) at org.apache.poi.ss.formula.WorkbookEvaluator.evaluate(WorkbookEvaluator.java:205) at org.apache.poi.xssf.usermodel.BaseXSSFFormulaEvaluator.evaluateFormulaCellValue(BaseXSSFFormulaEvaluator.java:63) ... 2 more
内容的提问来源于stack exchange,提问作者trashgod
相关产品推荐
相关产品推荐

