Apache POI xlsx读取,带#值的单元格 - 错误意外单元格类型(5)

时间:2013-10-31 16:13:52

标签: java apache-poi xlsx

你能解决这个问题。

我需要将每个单元格读取为String值。在这种情况下,我使用的是appache poi lib。以及使每个细胞正常化的方法:

String getNormilizedCell(Cell cell){
return new DataFormatter().formatCellValue(cell);}

但是在In .xlsx文件中我遇到了这样的价值:

|#N / A |#N / A | ... | ... | ...

我收到错误 [意外的单元格类型(5)] ,我不知道如何处理这个错误。在谷歌我找不到必要的信息。

3 个答案:

答案 0 :(得分:4)

DataFormatter课程仅处理CELL_TYPE_FORMULACELL_TYPE_NUMERICCELL_TYPE_STRINGCELL_TYPE_BOOLEANCELL_TYPE_BLANK。它不处理CELL_TYPE_ERROR,即5

您必须首先检测错误单元格类型,然后专门处理它,参考error cell value codes

if (cell.getCellType() == Cell.CELL_TYPE_ERROR) {
    byte errorValue = cell.getErrorCellValue();
    switch(errorValue) {
    case ERROR_DIV_0:
        return "#DIV/0!";
    case ERROR_NA:
        return "#N/A";
    case ERROR_NAME:
        return "#NAME?";
    case ERROR_NULL:
        return "#NULL!";
    case ERROR_NUM:
        return "#NUM!";
    case ERROR_REF:
        return "#REF!";
    case ERROR_VALUE:
        return "#VALUE!";
    default:
        return "Unknown error value: " + errorValue + "!";
    }
} else {
    return new DataFormatter().formatCellValue(cell);
}

答案 1 :(得分:2)

您需要升级Apache POI的副本!

r1537552开始,DataFormatter现在很乐意为您格式化错误单元格。它将使用FormulaError constants

返回Excel显示的错误字符串

答案 2 :(得分:1)

正如@Gagravarr所说,DataFormatter现在处理大多数错误(我使用poi-3.11-beta2)。但是,正如我的评论中所说,一些公式错误仍然会引发异常。

例如,当xxx不是真正的函数时评估类似=xxx()的公式时,Excel会显示#NAME?,但我们会得到“不知道如何评估名称'xxx'”运行时异常。

幸运的是,处理起来很简单:

public String readCellValue(Cell cell)
{
    switch (cell.getCellType())
    {
    case Cell.CELL_TYPE_BLANK:
        return "(blank)";
    case Cell.CELL_TYPE_BOOLEAN:
        return String.valueOf(cell.getBooleanCellValue());
    case Cell.CELL_TYPE_ERROR:
        return String.valueOf(cell.getErrorCellValue());
    case Cell.CELL_TYPE_FORMULA:
        return readFormattedCellValue(cell);
    case Cell.CELL_TYPE_NUMERIC:
        return String.valueOf(cell.getNumericCellValue());
    case Cell.CELL_TYPE_STRING:
        return cell.getStringCellValue();
    default:
        return "Unknown type!";
    }
}

public String readFormattedCellValue(Cell cell)
{
    try
    {
        return formatter.formatCellValue(cell, evaluator);
    }
    catch (RuntimeException e)
    {
        return e.getMessage(); // Error from evaluator, for example "Don't know how to evaluate name 'xxx'" if we have =xxx() in cell
    }
}

对于记录,formatterevaluator的创建方式与转换为CSV示例类似:

    try (FileInputStream fis = new FileInputStream(file))
    {
        // Open the workbook and then create the FormulaEvaluator and
        // DataFormatter instances that will be needed to, respectively,
        // force evaluation of formulae found in cells and create a
        // formatted String encapsulating the cells contents.
        workbook = WorkbookFactory.create(fis);
        evaluator = workbook.getCreationHelper().createFormulaEvaluator();
        formatter = new DataFormatter(true);
    }

由于某些未知原因,WorkbookFactory仅存在于poi-ooml-3.11-beta2.jar中,而不存在于poi-3.11-beta2.jar中。