Java POI:如何读取Excel单元格值而不是计算公式?

Ami*_*oss 53 java excel notimplementedexception apache-poi

我正在使用Apache POI API从Excel文件中获取值.除了含有公式的单元格外,一切都很好.事实上,cell.getStringCellValue()正在返回单元格中使用的公式而不是单元格的值.

我尝试使用evaluateFormulaCell()方法,但它不起作用,因为我使用GETPIVOTDATA Excel公式,并且此公式未在API中实现:

Exception in thread "main" org.apache.poi.ss.formula.eval.NotImplementedException: Error evaluating cell Landscape!K11
    at org.apache.poi.ss.formula.WorkbookEvaluator.addExceptionInfo(WorkbookEvaluator.java:321)
    at org.apache.poi.ss.formula.WorkbookEvaluator.evaluateAny(WorkbookEvaluator.java:288)
    at org.apache.poi.ss.formula.WorkbookEvaluator.evaluate(WorkbookEvaluator.java:221)
    at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluateFormulaCellValue(HSSFFormulaEvaluator.java:320)
    at org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.evaluateFormulaCell(HSSFFormulaEvaluator.java:213)
    at fromExcelToJava.ExcelSheetReader.unAutreTest(ExcelSheetReader.java:193)
    at fromExcelToJava.ExcelSheetReader.main(ExcelSheetReader.java:224)
Caused by: org.apache.poi.ss.formula.eval.NotImplementedException: GETPIVOTDATA
    at org.apache.poi.hssf.record.formula.functions.NotImplementedFunction.evaluate(NotImplementedFunction.java:42)
Run Code Online (Sandbox Code Playgroud)

Gag*_*arr 124

对于公式单元格,excel存储两件事.一个是公式本身,另一个是"缓存"值(论坛被评估为的最后一个值)

如果你想获得最后一个缓存的值(可能不再正确,但只要Excel保存文件并且你没有更改它应该是这样),你需要的东西如下:

 for(Cell cell : row) {
     if(cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
        System.out.println("Formula is " + cell.getCellFormula());
        switch(cell.getCachedFormulaResultType()) {
            case Cell.CELL_TYPE_NUMERIC:
                System.out.println("Last evaluated as: " + cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_STRING:
                System.out.println("Last evaluated as \"" + cell.getRichStringCellValue() + "\"");
                break;
        }
     }
 }
Run Code Online (Sandbox Code Playgroud)

  • 如果有效,请记住"接受"答案. (10认同)
  • 缓存的日期怎么样?日期单元格标记为Cell.CELL_TYPE_NUMERIC。 (2认同)
  • 有没有理由我们应该从cell.getStringCellValue()中选择cell.getRichStringCellValue().toString()(如上面的代码所示)? (2认同)
  • 在 poi 版本 4.0.1 中,我必须根据本文档将代码从 case Cell.CELL_TYPE_NUMERIC: 稍微更改为 case NUMERIC: 等 https://poi.apache.org/apidocs/dev/org/apache/poi/ ss/usermodel/CellType.html (2认同)

Sel*_*ava 11

以前发布的解决方案对我不起作用。cell.getRawValue()返回与单元格中所述相同的公式。以下功能对我有用:

public void readFormula() throws IOException {
    FileInputStream fis = new FileInputStream("Path of your file");
    Workbook wb = new XSSFWorkbook(fis);
    Sheet sheet = wb.getSheetAt(0);
    FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

    CellReference cellReference = new CellReference("C2"); // pass the cell which contains the formula
    Row row = sheet.getRow(cellReference.getRow());
    Cell cell = row.getCell(cellReference.getCol());

    CellValue cellValue = evaluator.evaluate(cell);

    switch (cellValue.getCellType()) {
        case Cell.CELL_TYPE_BOOLEAN:
            System.out.println(cellValue.getBooleanValue());
            break;
        case Cell.CELL_TYPE_NUMERIC:
            System.out.println(cellValue.getNumberValue());
            break;
        case Cell.CELL_TYPE_STRING:
            System.out.println(cellValue.getStringValue());
            break;
        case Cell.CELL_TYPE_BLANK:
            break;
        case Cell.CELL_TYPE_ERROR:
            break;

        // CELL_TYPE_FORMULA will never happen
        case Cell.CELL_TYPE_FORMULA:
            break;
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 似乎是从 [this answer with more information](/sf/ask/390497481/?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)复制的. (3认同)