簡體   English   中英

如何使用 Apache Poi 中的公式保存 excel?

[英]How to save excel with formula in 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 使用迭代技術計算 IRR。 從猜測開始,IRR 循環計算,直到結果准確在 0.00001% 以內。 如果 IRR 在 20 次嘗試后找不到有效的結果,則 #NUM. 返回錯誤值。

在大多數情況下,您不需要為 IRR 計算提供猜測。 如果省略guess,則假定為0.1(10%)。

這正是apache poiIRR function 實現的。 這就是為什么它獲得#NUM! 您的數據樣本的錯誤。 Microsoft似乎做了一些不同的事情。

使用公式IRR(A2:C2,-0.7) ,給定的猜測值為-0.7apache poi也能夠評估該IRR公式。

為了解決這個問題,人們可以做IRR function 描述也告訴的事情:

如果 IRR 給出 #NUM 錯誤值,或者結果與您的預期不接近。 用不同的猜測值再試一次。

因此,嘗試以 0.1 為步長從 -1.0 guess到 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();
 }
}

另請參閱poi 中的 IRR 返回 NaN 但 excel 中的正確值以獲取相同問題的另一個示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM