Java 使用ApachePOI将excel中的公式单元格转换为错误单元格

Java 使用ApachePOI将excel中的公式单元格转换为错误单元格,java,excel,excel-formula,apache-poi,xlsx,Java,Excel,Excel Formula,Apache Poi,Xlsx,我使用ApachePOI来访问excel,而我使用的任何公式都会将该行转换为错误行 XSSFWorkbook workbook = new XSSFWorkbook("D://Book.xlsx"); XSSFSheet spreadsheet = workbook.getSheetAt(0); XSSFRow row = spreadsheet.createRow(6); XSSFCell cell = row.createCell(4);

我使用ApachePOI来访问excel,而我使用的任何公式都会将该行转换为错误行

      XSSFWorkbook workbook = new XSSFWorkbook("D://Book.xlsx"); 
      XSSFSheet spreadsheet = workbook.getSheetAt(0);

      XSSFRow row = spreadsheet.createRow(6);
      XSSFCell cell = row.createCell(4);
      cell.setCellType(XSSFCell.CELL_TYPE_FORMULA);
      cell.setCellFormula("LOOKUP(2,1/(A:A<>\"\"),ROW(A:A))");
      workbook.setForceFormulaRecalculation(true);
      FormulaEvaluator evaluator =   workbook.getCreationHelper().createFormulaEvaluator();
      CellValue cellValue = evaluator.evaluate(cell);

      switch (cellValue.getCellType()) {
        case Cell.CELL_TYPE_BOOLEAN:
            System.out.println("Boolean");
            System.out.println(cellValue.getBooleanValue());
            break;
        case Cell.CELL_TYPE_NUMERIC:
            System.out.println("Num");
            System.out.println(cellValue.getNumberValue());
            break;
        case Cell.CELL_TYPE_STRING:
            System.out.println("String");
            System.out.println(cellValue.getStringValue());
            break;
        case Cell.CELL_TYPE_BLANK:
            System.out.println("Blank");
            break;
        case Cell.CELL_TYPE_ERROR:
            System.out.println("Error");
            Byte b = cellValue.getErrorValue();
            System.out.println(b.intValue());
            break;

        case Cell.CELL_TYPE_FORMULA: 
            System.out.println("Formula");
            break;
    }   
      workbook.close();
      System.out.println("written successfully");
请告诉我我缺少哪一部分?

公式
=LOOKUP(2,1/(A:A“”),ROW(A:A))
使用了未记录的Excels功能

部分
1/(A:A“”)
的计算结果为
{1;1;1;#DIV/0!;#DIV/0!…}
。如果
A
中的单元格为
,则
1
1/TRUE
),否则
#DIV/0
1/FALSE

但截至目前,有文件证明:

语法

查找(查找值、查找向量、[结果向量])

需要查找向量。仅包含一行或一行的范围 专栏。查找向量中的值可以是文本、数字或逻辑值 价值观

这里没有提到错误值

以及:

重要提示:lookup_vector中的值必须按升序排列 顺序:…,-2,-1,0,1,2,…,A-Z,假,真;否则,请执行查找 可能无法返回正确的值。大写和小写文本是相同的 相当于

{1;1;1;#DIV/0!#DIV/0!…}
是否真的按升序排列还不清楚

因此,这将在Excel中按预期进行评估。如果编写工作簿并用Excel打开,则公式
=LOOKUP(2,1/(A:A“”)、ROW(A:A))
将位于
E7
中,并将按预期工作

但是对于其他的
求值器
,比如来自apachepoi的求值器,它们严格遵守求值规则,它一定不能工作

在您的数据示例中,我假设值1到9在列
B

cell.setCellFormula("LOOKUP(MAX(B:B),B:B,B:B)");
将按预期进行评估

当然,这不是您想要的—获取列
A
中最后一个填充的单元格。这也可以通过数组公式实现。但是,尽管apache poi可以将数组公式应用于工作表,但据我所知,它直到现在才计算数组公式。

公式
=LOOKUP(2,1/(A:A“”),ROW(A:A))
使用了未记录的Excels功能

部分
1/(A:A“”)
的计算结果为
{1;1;1;#DIV/0!;#DIV/0!…}
。如果
A
中的单元格为
,则
1
1/TRUE
),否则
#DIV/0
1/FALSE

但截至目前,有文件证明:

语法

查找(查找值、查找向量、[结果向量])

需要查找向量。仅包含一行或一行的范围 专栏。查找向量中的值可以是文本、数字或逻辑值 价值观

这里没有提到错误值

以及:

重要提示:lookup_vector中的值必须按升序排列 顺序:…,-2,-1,0,1,2,…,A-Z,假,真;否则,请执行查找 可能无法返回正确的值。大写和小写文本是相同的 相当于

{1;1;1;#DIV/0!#DIV/0!…}
是否真的按升序排列还不清楚

因此,这将在Excel中按预期进行评估。如果编写工作簿并用Excel打开,则公式
=LOOKUP(2,1/(A:A“”)、ROW(A:A))
将位于
E7
中,并将按预期工作

但是对于其他的
求值器
,比如来自apachepoi的求值器,它们严格遵守求值规则,它一定不能工作

在您的数据示例中,我假设值1到9在列
B

cell.setCellFormula("LOOKUP(MAX(B:B),B:B,B:B)");
将按预期进行评估


当然,这不是您想要的—获取列
A
中最后一个填充的单元格。这也可以通过数组公式实现。但是,虽然apache poi可以将数组公式应用到工作表中,但据我所知,它直到现在才计算数组公式。

ya这部分工作正常,谢谢,我也想在java控制台上得到这个结果,比如E7中的8是excel中的,所以我需要java中的8。正如我在回答中已经提到的,使用ApachePOI中的
FormulaEvaluator
,这是不可能的。如果需要获取列
A
中最后填充的行,则循环所有当前行并检查单元格(0)中是否有值。如果可以确定Excel已经计算了此公式,则可以从公式单元格中选择
cell.getCachedForMularResultType()
,然后选择
cell.cell\u TYPE\u NUMERIC
cell.getNumericCellValue()
。但是,您不能在程序中设置公式。公式必须在打开时已经在工作表中。ya该部分正在工作,谢谢,我也想在java控制台上得到这个结果,比如说在E7中,8在excel中,所以我需要java中的8。正如我在回答中已经提到的,使用apache poi中的
FormulaEvaluator
,这是不可能的。如果需要获取列
A
中最后填充的行,则循环所有当前行并检查单元格(0)中是否有值。如果可以确定Excel已经计算了此公式,则可以从公式单元格中选择
cell.getCachedForMularResultType()
,然后选择
cell.cell\u TYPE\u NUMERIC
cell.getNumericCellValue()
。但是,您不能在程序中设置公式。打开时,公式必须已在图纸中。