Apache POI 不更新公式

Apache POI does not update formulas

我正在使用 Apache POI 库来使用 excel sheet 中的一些公式,但这些公式似乎没有在运行时更新。如果我保存一个工作簿并重新打开它,它们将被重新计算。有没有办法在运行时计算它们?

我的代码是:

FileInputStream excelFile = new FileInputStream(new File(FILE_NAME));
Workbook workbook = new XSSFWorkbook(excelFile);
Sheet datatypeSheet = workbook.getSheetAt(1);

datatypeSheet.getRow(19).getCell(2).setCellValue(0);  // set C20=0
workbook.setForceFormulaRecalculation(true); 

System.out.println(workbook.getSheetAt(1).getRow(19).getCell(8).getNumericCellValue()); // prints out the result

FileOutputStream out = new FileOutputStream(new File(FILE_NAME));
workbook.write(out);
out.close();

我也试过:

FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
evaluator.clearAllCachedResultValues();
evaluator.notifySetFormula(workbook.getSheetAt(1).getRow(19).getCell(8));
evaluator.evaluate(workbook.getSheetAt(1).getRow(19).getCell(8));

但它们总是 return 旧值。

Workbook.setForceFormulaRecalculation 明确地只在下次打开工作簿时强制重新计算过程 Excel。所以按设计工作。

但是使用FormulaEvaluator才是正确的方法。但是你应该使用 FormulaEvaluator.evaluateFormulaCell 而不是 FormulaEvaluator.evaluate.

来自 FormulaEvaluator.evaluate:

If cell contains a formula, the formula is evaluated and returned, else the CellValue simply copies the appropriate cell value from the cell and also its cell type.

单元格中没有更新公式的结果。

对面FormulaEvaluator.evaluateFormulaCell:

If cell contains formula, it evaluates the formula, and saves the result of the formula. The cell remains as a formula cell.

单元格中公式的结果也被保存了。

ExcelExample.xlsx 的第二个 sheet 单元格 C20 包含一个数字并且单元格 I20 包含一个公式 C20 作为参数.

import org.apache.poi.ss.usermodel.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;

class ExcelEvaluateCell {

 public static void main(String[] args) throws Exception {
     
  Workbook workbook = WorkbookFactory.create(new FileInputStream("./ExcelExample.xlsx"));
  FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();  
 
  System.out.println(workbook.getSheetAt(1).getRow(19).getCell(2).getNumericCellValue()); // prints value of C20
  
  System.out.println(workbook.getSheetAt(1).getRow(19).getCell(8).getCellFormula()); // prints formula in I20
  System.out.println(workbook.getSheetAt(1).getRow(19).getCell(8).getNumericCellValue()); // prints result of formula in in I20
  
  workbook.getSheetAt(1).getRow(19).getCell(2).setCellValue(0); // set C20 = 0
  
  evaluator.evaluateFormulaCell(workbook.getSheetAt(1).getRow(19).getCell(8)); // evaluates formula in cell I20 and updates the result
  System.out.println(workbook.getSheetAt(1).getRow(19).getCell(8).getNumericCellValue()); // prints new result of formula in in I20
 
  FileOutputStream out = new FileOutputStream("./ExcelExampleNew.xlsx");
  workbook.write(out);
  out.close();
  workbook.close();
 }
}