使用Apache Poi从Excel表格中获取单元格的值

21

如何在Java中使用POI获取单元格的值?

我的代码看起来像这样:

String cellformula_total__percentage= "(1-E" + (rowIndex + 2) + "/" + "D" + (rowIndex + 2) + ")*100";
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cell.setCellStyle(this.valueRightAlignStyleLightBlueBackground);
cell.setCellFormula("abs(" + cellformula_total__percentage + ")");

但如果在这种情况下,我如何检查我的单元格值是否包含错误值,例如 #DIV/0!,并将其替换为 N/A?

2个回答

44
你需要使用FormulaEvaluator,如此处所示here 。这将返回单元格中存在的值或公式结果(如果单元格包含公式)。
FileInputStream fis = new FileInputStream("/somepath/test.xls");
Workbook wb = new HSSFWorkbook(fis); //or new XSSFWorkbook("/somepath/test.xls")
Sheet sheet = wb.getSheetAt(0);
FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();

// suppose your formula is in B3
CellReference cellReference = new CellReference("B3"); 
Row row = sheet.getRow(cellReference.getRow());
Cell cell = row.getCell(cellReference.getCol()); 

if (cell!=null) {
    switch (evaluator.evaluateFormulaCell(cell)) {
        case Cell.CELL_TYPE_BOOLEAN:
            System.out.println(cell.getBooleanCellValue());
            break;
        case Cell.CELL_TYPE_NUMERIC:
            System.out.println(cell.getNumericCellValue());
            break;
        case Cell.CELL_TYPE_STRING:
            System.out.println(cell.getStringCellValue());
            break;
        case Cell.CELL_TYPE_BLANK:
            break;
        case Cell.CELL_TYPE_ERROR:
            System.out.println(cell.getErrorCellValue());
            break;

        // CELL_TYPE_FORMULA will never occur
        case Cell.CELL_TYPE_FORMULA: 
            break;
    }
}
如果您需要精确的内容(例如,如果单元格包含公式,则为公式),则可以在此处查看:这里编辑: 添加了一些示例来帮助您。
首先,您需要获取单元格(只是一个示例)。
Row row = sheet.getRow(rowIndex+2);    
Cell cell = row.getCell(1);   

如果你只想使用公式将值设置到单元格中(而不知道结果):

 String formula ="ABS((1-E"+(rowIndex + 2)+"/D"+(rowIndex + 2)+")*100)";    
 cell.setCellFormula(formula);    
 cell.setCellStyle(this.valueRightAlignStyleLightBlueBackground);

如果你想在单元格出现错误时更改消息,你需要修改公式,例如:

IF(ISERR(ABS((1-E3/D3)*100));"N/A"; ABS((1-E3/D3)*100))

(这个公式检查评估是否返回错误,如果是则显示字符串“N/A”,否则显示评估结果)。

如果您想获取与公式相对应的值,则必须使用求值器。

希望这有所帮助,
Guillaume


1
据我所知,如果单元格中没有公式,您不必使用FormulaEvaluator :) 如果您的单元格包含文本或数字值,则可以通过cell.getStringCellValue();cell.getNumericCellValue();获取它们。您的回答适用于单元格包含公式的情况,但是OP并没有表明这种情况。 - posdef
@PATRY:你说得很对... 我只是想指出这一点,以确保没有误解。 - posdef
1
如果出现错误,则单元格的类型为Cell.CELL_TYPE_ERROR。您可以通过getErrorCellValue()方法获取错误值。之后,这取决于您的需求:如果您只需要标准错误消息(“N/A”),则只需检查内容的性质即可。如果您需要不同的错误消息,则使用HashMap将Excel错误消息映射到您自己的消息(这只是一个示例)... - PATRY Guillaume
根据我的经验(POI 3.7),如果单元格不是公式,evaluateFormulaCell()会返回-1,因此您仍然需要稍微不同地处理公式和非公式单元格,即从getCellType()获取单元格类型。我已编辑您的代码以进行额外检查。 - Steve Blackwell
你可以使用WorkbookFactory.create(fis);,这样你就不必显式地创建HSSFWorkbook或XSSFWorkbook。 - YamYamm
显示剩余5条评论

12

可能是由于以下原因:

    for(Row row : sheet) {          
        for(Cell cell : row) {              
            System.out.print(cell.getStringCellValue());

        }
    }       

对于特定类型的单元格,您可以尝试:

switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
    cellValue = cell.getStringCellValue();
    break;

case Cell.CELL_TYPE_FORMULA:
    cellValue = cell.getCellFormula();
    break;

case Cell.CELL_TYPE_NUMERIC:
    if (DateUtil.isCellDateFormatted(cell)) {
        cellValue = cell.getDateCellValue().toString();
    } else {
        cellValue = Double.toString(cell.getNumericCellValue());
    }
    break;

case Cell.CELL_TYPE_BLANK:
    cellValue = "";
    break;

case Cell.CELL_TYPE_BOOLEAN:
    cellValue = Boolean.toString(cell.getBooleanCellValue());
    break;

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接