0
有没有一种有效的方法来确定在调用FormulaEvaluator :: evaluateAll后哪些单元格发生了更改?工作簿评估后有效确定更新的单元格
我可以看到有一个接口IEvaluationListener可能是有用的,但它不是外部可用的(似乎只用于测试)。
有没有一种有效的方法来确定在调用FormulaEvaluator :: evaluateAll后哪些单元格发生了更改?工作簿评估后有效确定更新的单元格
我可以看到有一个接口IEvaluationListener可能是有用的,但它不是外部可用的(似乎只用于测试)。
我查找了如何evaluateAll
工作,发现BaseFormulaEvaluator.evaluateAllFormulaCells。
此代码可以访问所有评估过的单元格。它可以通过复制/粘贴来使用。由于它与apache poi
使用相同,而evaluateAll
它应该如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();
}
}
该实施例期望的A2
在第一片材的值被用作在一些公式参考。因此,改变这个值会导致公式单元格在评估时出现新的值。