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
在第一片材的值被用作在一些公式參考。因此,改變這個值會導致公式單元格在評估時出現新的值。