在工作簿评估之后有效地确定更新的单元格

时间:2017-09-15 01:44:30

标签: apache-poi

在调用FormulaEvaluator :: evaluateAll后,是否有一种有效的方法来确定哪些单元格已更改?

我可以看到有一个IEvaluationListener接口可能很有用,但它在外部不可用(似乎仅用于测试)。

1 个答案:

答案 0 :(得分:1)

我查找了evaluateAll的工作原理并找到了BaseFormulaEvaluator.evaluateAllFormulaCells

此代码可以访问所有已评估的单元格。它只需复制/粘贴即可使用。由于它与apache poi使用的evaluateAll相同,因此它应与[{1}}一样高效。

在评估之前,您可以获得单元格的旧值,在评估之后,您可以获得单元格的新值。因此,您可以确定评估是否已更改某些内容。当然,这些变化会影响表现,但我认为没有办法避免这种情况。

evaluateAll

此示例期望第一个工作表中的import org.apache.poi.ss.usermodel.*; import java.io.InputStream; import java.io.FileInputStream; class ExcelEvaluateAllFormulas { public static void evaluateAllFormulaCells(Workbook wb) { FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); evaluateAllFormulaCells(wb, evaluator); } protected static void evaluateAllFormulaCells(Workbook wb, FormulaEvaluator evaluator) { for(int i=0; i<wb.getNumberOfSheets(); i++) { Sheet sheet = wb.getSheetAt(i); for(Row r : sheet) { for (Cell c : r) { if (c.getCellTypeEnum() == CellType.FORMULA) { CellType celltype = c.getCachedFormulaResultTypeEnum(); Object oldvalue = null; if (celltype == CellType.NUMERIC) { oldvalue = c.getNumericCellValue(); } else if (celltype == CellType.BOOLEAN) { oldvalue = c.getBooleanCellValue(); } else if (celltype == CellType.STRING) { oldvalue = c.getStringCellValue(); } else if (celltype == CellType.ERROR) { oldvalue = "Err: " + c.getErrorCellValue(); } if (oldvalue == null) oldvalue = "no value"; System.out.print(c.getSheet().getSheetName() + "!" + c.getAddress() + ":old value:" + oldvalue); celltype = evaluator.evaluateFormulaCellEnum(c); Object newvalue = null; if (celltype == CellType.NUMERIC) { newvalue = c.getNumericCellValue(); } else if (celltype == CellType.BOOLEAN) { newvalue = c.getBooleanCellValue(); } else if (celltype == CellType.STRING) { newvalue = c.getStringCellValue(); } else if (celltype == CellType.ERROR) { newvalue = "Err: " + c.getErrorCellValue(); } if (newvalue == null) newvalue = "no value"; System.out.println("->new value:" + newvalue); if (oldvalue.equals(newvalue)) { System.out.println("Value has not changed."); } else { System.out.println("Value has changed."); } } } } } } public static void main(String[] args) throws Exception{ InputStream inp = new FileInputStream("ExcelWithFormulas.xlsx"); Workbook workbook = WorkbookFactory.create(inp); workbook.getSheetAt(0).getRow(1).getCell(0).setCellValue(0.5); evaluateAllFormulaCells(workbook); workbook.close(); } } 值在某些公式中用作参考。因此,在评估时,更改此值会导致公式单元格中的新值。