Java POI XSSF VLookup 公式

Java POI XSSF VLookup formula

我正在尝试使用 Java 和 Apache POI 将简单的 VLookup 公式放入我的“.xlsx”文件中。
这个公式有外部参考,对我不起作用。

因此,为了向您提供更多详细信息,我使用的是 poi 和 poi-ooxml 版本 3.13 和 excel 2007。
我以这种方式将公式放入单元格(其中单元格是一个单元格):

cell.setCellType(Cell.CELL_TYPE_FORMULA);
cell.setCellFormula("StringContainingFormula");

然后评估公式,我尝试了三种不同的方法但没有运气。 (wb 是 XSSFWorkbook)。

1

FormulaEvaluator mainWorkbookEvaluator = wb.getCreationHelper().createFormulaEvaluator();
Map<String,FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
workbooks.put("SpreadsheetName.xlsx", mainWorkbookEvaluator);
mainWorkbookEvaluator.setupReferencedWorkbooks(workbooks);
mainWorkbookEvaluator.evaluateAll();

2

XSSFEvaluationWorkbook.create(wb);
Workbook nwb = wb;
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
for (Sheet sheet : nwb) {
    for (Row r : sheet) {
        for (Cell c : r) {
            if (c.getCellType() == Cell.CELL_TYPE_FORMULA) {
                try {
                    //evaluator.evaluateFormulaCell(c);
                    evaluator.evaluate(c);
                } catch (Exception e) {
                    System.out.println("Error occured in 'EvaluateFormulas' : " + e);
                }
            }
        }
    }
}

3

XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);  

问题是,它写入 Excel 文件,然后在评估时抛出错误:

java.lang.IllegalArgumentException: Invalid sheetIndex: -1

现在如果我打开 Excel 文件,它会给我警告:

Automatic update of links has been disabled

如果我启用内容,公式会正确显示结果,如果我不做任何事情而不是公式导致 #N/A.
现在,如果我 select 包含公式的单元格并单击公式栏并按回车键,则公式会显示结果。

更新:

因此,我通过进入 Excel 选项禁用了警告消息,它开始在单元格内给我公式。
但是,当我尝试使用

从中获取结果值时
if (cell.getCachedFormulaResultType == Cell.CELL_TYPE_STRING) {
    System.out.println("Last evaluated as \"" + cell.getRichStringCellValue() + "\"");
}

它从来没有给我 getCachedFormulaResultType 作为 CELL_TYPE_STRING,它总是 return CELL_TYPE_NUMERIC。它应该是 return 字符串值。我正在扩展 URL 和其他值(由“|” - "cat|dog|bird" 分隔的单词)。

我很感激任何help/suggestion。

好吧,它似乎起作用了。你要温柔对待excel;如果先打开外部工作簿,然后再打开主工作簿,效果会更好。如果你不这样做,它会给出一条关于不安全链接的消息,但除此之外,一切似乎都很好。评估器仅适用于单个单元格,因此如果您想重新计算整个电子表格,则必须循环。此外,外部引用必须已经由 excel 链接,POI 尚未实现该功能。这是我在 github:

中输入的内容
    // Open workbooks
    Path pathBook1 = Paths.get("c:/users/karl/scsb/Vlookup/Book1.xlsx");
    InputStream is = Files.newInputStream(pathBook1);
    XSSFWorkbook book1 = new XSSFWorkbook(is);
    // Add Linked Cell
    // The workbook must already have been linked to Book2.xlsx by Excel
    // The linkExternalWorkbook has not yet been implemented: SEE BUG #57184
    Cell cell = book1.getSheetAt(0).createRow(2).createCell(0);
    cell.setCellFormula("A2+[Book2.xlsx]Sheet1!A1");
    // Create evaluator after the new cell has been added.
    FormulaEvaluator mainEvaluator = book1.getCreationHelper().createFormulaEvaluator();
    XSSFWorkbook book2 = new XSSFWorkbook("c:/users/karl/scsb/Vlookup/Book2.xlsx");
    Map<String, FormulaEvaluator> workbooks = new HashMap<String, FormulaEvaluator>();
    workbooks.put("Book1.xlsx", mainEvaluator);
    workbooks.put("Book2.xlsx", book2.getCreationHelper().createFormulaEvaluator());
    mainEvaluator.setupReferencedWorkbooks(workbooks);
//  mainEvaluator.evaluateAll();                            // doesn't work.
//  XSSFFormulaEvaluator.evaluateAllFormulaCells(book1);    // doesn't work.
    mainEvaluator.evaluateFormulaCell(cell);
    System.out.println(cell.getNumericCellValue());
    book2.close();
    // Close and write workbook 1
    is.close();
    OutputStream os = Files.newOutputStream(pathBook1);
    book1.write(os);
    os.close();
    book1.close();

我最近遇到了同样的问题。问题是,对于当前的 POI,无法编写文档、将公式添加到特定字段并在此时仍不存在的文档上执行公式评估。我用来解决它的技巧是:

  1. 将所有数据和公式写入工作簿
  2. 在关闭此文档之前添加workbook.setForceFormulaRecalculation(true);
  3. 编写并关闭文档
  4. 再次打开同一个文档,只做FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); evaluator.evaluateAll();
  5. 再次写入并关闭

因此,由于我没有任何其他选择,我不得不将引用的数据复制到主工作簿(我知道这不是个好主意,以防数据量很大)才能正常工作。
所以我所做的是:

  1. 从外部工作簿复制引用数据。
  2. 在主工作簿上创建新工作表(您需要在其中编写公式)并粘贴引用数据。
  3. 现在编写公式,这次使用新创建的工作表(粘贴数据)而不是外部工作簿。
    注意*:你需要先把所有的数据(包括公式)都写好,然后再去计算公式。
  4. 如果您已经关闭,然后打开工作簿进行阅读,并像这样评估所有公式(wb 是 XSSFWorkbook):

XSSFFormulaEvaluator.evaluateAllFormulaCells(wb);