Could you hepl me with such issue.
I need to read each cell as String value. In this case I am using appache poi lib. and such method for normilizing each cell:
String getNormilizedCell(Cell cell){
return new DataFormatter().formatCellValue(cell);}
But when In .xlsx file I faced with such value:
|#N/A|#N/A|...|...|...
I am getting error [Unexpected Cell type (5)] and I don't know how to handle this. In google I can't find necessary information.
The DataFormatter
class only handles CELL_TYPE_FORMULA
, CELL_TYPE_NUMERIC
, CELL_TYPE_STRING
, CELL_TYPE_BOOLEAN
, and CELL_TYPE_BLANK
. It doesn't handle CELL_TYPE_ERROR
, which is 5
.
You'll have to work around this by first detecting the error cell type and then handling it specially, referring to the 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);
}
You need to upgrade your copy of Apache POI!
As of r1537552 DataFormatter is now happy to format Error cells for you. It'll give you back the error string that Excel displays, using the FormulaError constants
As said by @Gagravarr, DataFormatter handles most errors now (I use poi-3.11-beta2). But, as said in my comment, some formula errors can still throw exceptions.
For example, when evaluating a formula like =xxx()
when xxx isn't a real function, Excel displays #NAME?
but we get a "Don't know how to evaluate name 'xxx'" runtime exception.
Fortunately, it is simple to handle:
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
}
}
For the record, formatter
and evaluator
are created like in the convert to CSV example:
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);
}
For some unknown reason, the WorkbookFactory
lives only in the poi-ooml-3.11-beta2.jar, not in the poi-3.11-beta2.jar one.