java - 如何在 Apache Poi 中保存带有公式的 Excel?

标签 java excel apache-poi

如果有一个带有公式的单元格并保存文件,那么手动关闭文件后,excel会询问是否保存更改?如何从程序中完整保存文件,因为如果没有这种保存,我无法通过读取文件获得正确的值。

当前文件保存:

        File file = new File("Test.xlsx");
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            workbook.write(out);
            workbook.close();
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

公式更新:

        XSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
        workbook.setForceFormulaRecalculation(true);

公式:

XSSFCell irrCell = row1.createCell(0);
irrCell.setCellFormula("IFERROR(IRR(A2:C2),0)");

文件读取:

        try {
            workbook = new XSSFWorkbook(file);
            System.out.println(workbook.getSheetAt(0).getRow(0).getCell(0).getNumericCellValue());
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        }

单元格值:-20000000、-1000、2399000

程序公式单元格值:0,文件公式单元格值:-0,653687014

最佳答案

这是Microsoft不遵守自己规则的情况之一。 IRR function告诉:

Microsoft Excel uses an iterative technique for calculating IRR. Starting with guess, IRR cycles through the calculation until the result is accurate within 0.00001 percent. If IRR can't find a result that works after 20 tries, the #NUM! error value is returned.

In most cases you do not need to provide guess for the IRR calculation. If guess is omitted, it is assumed to be 0.1 (10 percent).

这正是 apache poiIRR 功能实现的。这就是为什么它会在您的数据样本中出现 #NUM! 错误。但微软似乎做了一些不同的事情。

使用公式 IRR(A2:C2,-0.7)(给定的猜测值为 -0.7),apache poi 为能够评估IRR公式。

为了解决这个问题,可以执行IRR函数描述中也告诉我们的操作:

If IRR gives the #NUM! error value, or if the result is not close to what you expected, try again with a different value for guess.

因此,请尝试以 0.1 为步长从 -1.0 到 1.0 进行猜测,直到获得一个值而不是“#NUM!”错误。

示例:

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

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

class ExcelEvaluateIRRFunction {
 
 public static void main(String[] args) throws Exception {
  
  Workbook workbook = WorkbookFactory.create(new FileInputStream("./Excel.xlsx")); String filePath = "./ExcelNew.xlsx";
  FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();

  Sheet sheet = workbook.getSheetAt(0);
  Row row = sheet.getRow(1); if (row == null) row = sheet.createRow(1);
  row.createCell(0).setCellValue(-20000000d);
  row.createCell(1).setCellValue(-1000d);
  row.createCell(2).setCellValue(2399000d);

  row = sheet.getRow(0); if (row == null) row = sheet.createRow(0);
  Cell cell = row.createCell(0);

  CellValue evaluatedValue = null;
  for (int i = -10; i < 10; i++) {
   double guess = i/10d;
   System.out.println(guess);
   cell.setCellFormula("IRR(A2:C2," + guess + ")");
   evaluator.clearAllCachedResultValues();
   evaluatedValue = evaluator.evaluate(cell);
   System.out.println(evaluatedValue);
   if (evaluatedValue.getCellType() != CellType.ERROR) break;
  }

  evaluator.evaluateFormulaCell(cell);
  System.out.println(cell.getNumericCellValue());

  FileOutputStream out = new FileOutputStream(filePath);
  workbook.write(out);
  out.close() ;
  workbook.close();
 }
}

另请参阅IRR in poi return NaN but correct value in excel查看同一问题的另一个示例。

关于java - 如何在 Apache Poi 中保存带有公式的 Excel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62653045/

相关文章:

java - 处理 JAXB 中的嵌套元素

java - 应用程序关闭后 MediaPlayer 继续播放

excel - 基于单元格值动态隐藏列

excel - 如何从 D 列和 F 列中删除特殊字符?

excel - VBA 代码可以在 MS 应用程序之外运行吗?

apache-poi - 在 POI 模式中找不到 CTBarChart

java.lang.NoClassDefFoundError : org/apache/poi/hssf/usermodel/HSSFWorkbook 错误

java - Tomcat 自动转发到某个页面。找不到设置

java - 使用 AXIS2 1.4 进行 NTLM v.2 身份验证

java - Apache POI 依赖项?