Java POI: Как прочитать значение ячейки Excel, а не формула, вычисляющая его? - PullRequest
52 голосов
/ 30 сентября 2011

Я использую API Apache POI для получения значений из файла 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)

Ответы [ 3 ]

121 голосов
/ 30 сентября 2011

Для ячеек формулы 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;
        }
     }
 }
4 голосов
/ 02 декабря 2016

Ранее опубликованные решения не работали для меня. 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;
    }

}
0 голосов
/ 27 апреля 2015

Существует альтернативная команда, в которой вы можете получить необработанное значение ячейки, в которой указана формула. Возвращает тип String. Использование:

cell.getRawValue();
...