I have a workbook with an XML mapping defined (I am using POI 4.1.2).
A mapped cell contains a formula which evaluates to boolean: =AND(B70="";B71=""; B50="No")
I try to export the XML mapping with the following code:
// First ensure that all formulas are evaluated wb.getCreationHelper().createFormulaEvaluator().evaluateAll(); // Export XML map String file = "path/to/file.xml"; XSSFWorkbook xssfWorkbook = (XSSFWorkbook) wb; XSSFMap xssfMap = xssfWorkbook.getCustomXMLMappings().stream().findFirst().get(); XSSFExportToXml exporter = new XSSFExportToXml(xssfMap); OutputStream out = new FileOutputStream(file); exporter.exportToXML(out, false);
The last line results to the following exception:
java.lang.IllegalStateException: Cannot get a NUMERIC value from a BOOLEAN cell at org.apache.poi.xssf.usermodel.XSSFCell.typeMismatch(XSSFCell.java:1035) at org.apache.poi.xssf.usermodel.XSSFCell.getNumericCellValue(XSSFCell.java:319) at org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(DateUtil.java:765) at org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(DateUtil.java:744) at org.apache.poi.xssf.extractor.XSSFExportToXml.mapCellOnNode(XSSFExportToXml.java:281)
When i look into XSSFExportToXml.mapCellOnNode(XSSFCell, Node)
I see the following code:
private void mapCellOnNode(XSSFCell cell, Node node) { String value =""; switch (cell.getCellType()) { case STRING: value = cell.getStringCellValue(); break; case BOOLEAN: value += cell.getBooleanCellValue(); break; case ERROR: value = cell.getErrorCellString(); break; case FORMULA: if (cell.getCachedFormulaResultType() == CellType.STRING) { // cell.getCachedFormulaResultType() returns BOOLEAN value = cell.getStringCellValue(); } else { if (DateUtil.isCellDateFormatted(cell)) { // Results in Exception value = getFormattedDate(cell); } else { value += cell.getNumericCellValue(); } } break; case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { value = getFormattedDate(cell); } else { value += cell.getRawValue(); } break; default: } if (node instanceof Element) { Element currentElement = (Element) node; currentElement.setTextContent(value); } else { node.setNodeValue(value); } }
From my understanding there is a bug in mapCellOnNode
. Inside case FORMULA
the expression cell.getCachedFormulaResultType()
returns BOOLEAN
but inside this block only STRING
and NUMERIC
are considered. This leads to executing DateUtil.isCellDateFormatted(cell)
which results in an Exception.
So my question is: am I right? Is it a bug? Or am I missing something?
Advertisement
Answer
I have applied a fix to the POI code – see https://bz.apache.org/bugzilla/show_bug.cgi?id=65492 – this will be included in next POI release