如何使用apache poi从公式单元格中读取单元格值

时间:2013-07-07 07:30:38

标签: java apache-poi

我正在尝试从excel文件中读取所有数据,该文件也有一些公式单元格, 但我不知道哪个细胞是配方细胞。如何从细胞中读取所有值,而不管细胞的类型。

我的代码看起来像这样

FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
while (rows.hasNext()) {
     row = (HSSFRow) rows.next();
     Iterator cells = row.cellIterator();
     while (cells.hasNext()) {
             cell = (HSSFCell) cells.next();
             if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
                  ar.add(cell.getStringCellValue());
             } else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                 ar.add(cell.getNumericCellValue());
             }else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
                 ar.add(evaluator.evaluateFormulaCell(cell));
             } else {
                 ar.add("");
             }
     }
}

我将公式单元格值设为0

4 个答案:

答案 0 :(得分:7)

您正在寻找的方法是Cell.getCachedFormulaResultType - 对于公式单元格,它会告诉您公式结果的类型

您的代码可以是:

private void handleCell(int type, Cell cell) {
         if (type == HSSFCell.CELL_TYPE_STRING) {
              ar.add(cell.getStringCellValue());
         } else if (type == HSSFCell.CELL_TYPE_NUMERIC) {
             ar.add(cell.getNumericCellValue());
         } else if (type == HSSFCell.CELL_TYPE_BOOLEAN) {
             ar.add(cell.getBooleanCellValue());
         } else if (type == HSSFCell.CELL_TYPE_FORMULA) {
             // Re-run based on the formula type
             handleCell(cell.getCachedFormulaResultType(), cell);
         } else {
             ar.add("");
         }
}

public void handleSheet(Sheet sheet) {
    for (Row row : sheet) {
       for (Cell cell : row) {
           handleCell(cell.getCellType(), cell);
       }
    }
}

请注意,迭代器仅提供文件中定义的单元格,因此如果从未使用过单元格,则会出现间隙。如果您需要获取包含缺失单元格的每个单元格,请参阅Iterating vs Fetching docs

答案 1 :(得分:4)

使用Cell.getCachedFormulaResultType我们获取缓存的公式值;因此我们必须评估公式以获得新值

public static void main(String args[]) {
    FileInputStream inp = null;
    try {            
        inp = new FileInputStream("E:\\Hasangi\\tets\\test\\book.xls");

        HSSFWorkbook workbook = new HSSFWorkbook(inp);
        FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
        HSSFSheet sheet = workbook.getSheetAt(0);
        Row row = sheet.getRow(2);
        Cell cell = row.getCell(0);

        cell.setCellValue(1235487845);
        handleSheet(sheet, evaluator);
        FileOutputStream fileOut = new FileOutputStream("E:\\Hasangi\\tets\\test\\book.xls");
        workbook.write(fileOut);
        fileOut.close();
    } catch (IOException ex) {
        Logger.getLogger(xlreader.class.getName()).log(Level.SEVERE, null, ex);
    }
}

private static void handleCell(int type, Cell cell, FormulaEvaluator evaluator) {
    if (type == HSSFCell.CELL_TYPE_STRING) {
      System.out.println(cell.getStringCellValue());
    } else if (type == HSSFCell.CELL_TYPE_NUMERIC) {
       System.out.println(cell.getNumericCellValue());
    } else if (type == HSSFCell.CELL_TYPE_BOOLEAN) {
       System.out.println(cell.getBooleanCellValue());
    } else if (type == HSSFCell.CELL_TYPE_FORMULA) {
        // Re-run based on the formula type
        evaluator.evaluateFormulaCell(cell);
        handleCell(cell.getCachedFormulaResultType(), cell, evaluator);
    } else {
       System.out.println("");
    }
}

public static void handleSheet(Sheet sheet,FormulaEvaluator evaluator) {
    for (Row row : sheet) {
        for (Cell cell : row) {
            handleCell(cell.getCellType(), cell,evaluator);
        }
    }
}

答案 2 :(得分:1)

这是我的功能:

public void getValueOfFormulaCell() throws IOException
{
    FileInputStream xlsfile = new FileInputStream(new File("D:\\Desktop\\Temp\\marks.xls"));
    HSSFWorkbook objWorkbook = new HSSFWorkbook(xlsfile);
    Sheet sheet = objWorkbook.getSheetAt(0);
    FormulaEvaluator evaluator = objWorkbook.getCreationHelper().createFormulaEvaluator();

    // suppose your formula is in B4
    CellReference cellReference = new CellReference("B4"); 
    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;
    }               
    }

答案 3 :(得分:0)

上面的帖子起作用了,并且它帮助我编写了同样有效的以下程序。 以下代码读取具有公式,错误,字符串,数字的Excel文件(.xlsx)。 它读取Excel文件并将其转换为PIPE分隔的字符串以写入文本文件。

public String readExcelFile(String filepathname)
{
    String extractedText = null;
    try 
    {

        InputStream is = new FileInputStream(filepathname);
        XSSFWorkbook myExcelBook = new XSSFWorkbook(is);
        XSSFSheet myExcelSheet = myExcelBook.getSheet("VendorCentral");

        // Get iterator to all the rows in current sheet

        Iterator<Row> rowIterator = myExcelSheet.iterator();

        //Traversing through each row of xlsx file

        int rowNum=0;
        StringBuffer rowContents;

        StringBuffer sheetContents = new StringBuffer();

        XSSFFormulaEvaluator evaluator = myExcelBook.getCreationHelper().createFormulaEvaluator();

        while (rowIterator.hasNext())
        {
            Row row = rowIterator.next();
            rowNum++;

            rowContents = new StringBuffer();

            //For each row, iterate through each column
            Iterator<Cell> cellIterator = row.cellIterator();

            while (cellIterator.hasNext())
            {
                Cell cell = cellIterator.next();

                switch (cell.getCellType())
                {
                    case Cell.CELL_TYPE_STRING:
                        rowContents.append(cell.getStringCellValue() + DELIM_CHAR); 
                        break;

                    case Cell.CELL_TYPE_NUMERIC:
                        rowContents.append(cell.getNumericCellValue()  + DELIM_CHAR); 
                        break;

                    case Cell.CELL_TYPE_BOOLEAN:
                        rowContents.append(cell.getBooleanCellValue()  + DELIM_CHAR); 
                        break;

                    case Cell.CELL_TYPE_BLANK:
                        rowContents.append(""  + DELIM_CHAR); 
                        break;

                    case Cell.CELL_TYPE_ERROR:
                        rowContents.append("#Error"  + DELIM_CHAR); 
                        break;

                    case Cell.CELL_TYPE_FORMULA:
                        CellValue cellValue = evaluator.evaluate(cell );
                        System.out.println("cellValue.formatAsString: " + cellValue.formatAsString());
                        System.out.println("cellValue.getStringValue: " + cellValue.getStringValue()  );

                        rowContents.append(cellValue.formatAsString()  + DELIM_CHAR); 
                        break;

                    default:
                        rowContents.append(""  + DELIM_CHAR); 

                }

            }

            if (rowContents.length() > 0)
                rowContents.deleteCharAt(rowContents.length()-1);

            System.out.println("Row " + rowNum + ": " + rowContents.toString() );
            sheetContents.append("Row " + rowNum + ": " + rowContents.toString() + "\n" );
        }


        myExcelBook.close();
        if (sheetContents.length() > 0)
            sheetContents.deleteCharAt(sheetContents.length()-1);

        extractedText = sheetContents.toString();

    } catch (Exception e) 
    {
        e.printStackTrace();
    }
    return extractedText;
}