import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.RichTextString;
+import org.apache.poi.ss.util.NumberToTextConverter;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.util.POILogger;
int sstIndex = ((LabelSSTRecord)_record).getSSTIndex();
return _book.getWorkbook().getSSTString(sstIndex).getString();
case CELL_TYPE_NUMERIC:
- return String.valueOf(((NumberRecord)_record).getValue());
+ return NumberToTextConverter.toText(((NumberRecord)_record).getValue());
case CELL_TYPE_ERROR:
return HSSFErrorConstants.getText(((BoolErrRecord) _record).getErrorValue());
case CELL_TYPE_FORMULA:
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator
- return "";
+ // just use cached formula result instead
+ break;
+ default:
+ throw new IllegalStateException("Unexpected cell type (" + _cellType + ")");
}
- throw new RuntimeException("Unexpected cell type (" + _cellType + ")");
+ FormulaRecordAggregate fra = ((FormulaRecordAggregate)_record);
+ FormulaRecord fr = fra.getFormulaRecord();
+ switch (fr.getCachedResultType()) {
+ case CELL_TYPE_BOOLEAN:
+ return fr.getCachedBooleanValue() ? "TRUE" : "FALSE";
+ case CELL_TYPE_STRING:
+ return fra.getStringValue();
+ case CELL_TYPE_NUMERIC:
+ return NumberToTextConverter.toText(fr.getValue());
+ case CELL_TYPE_ERROR:
+ return HSSFErrorConstants.getText(fr.getCachedErrorValue());
+ }
+ throw new IllegalStateException("Unexpected formula result type (" + _cellType + ")");
}
/**
}
break;
case CELL_TYPE_FORMULA:
+ checkFormulaCachedValueType(CELL_TYPE_STRING, getBaseCellType(false));
rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : "");
break;
default:
return rt;
}
- /**
+ private static void checkFormulaCachedValueType(int expectedTypeCode, int cachedValueType) {
+ if (cachedValueType != expectedTypeCode) {
+ throw typeMismatch(expectedTypeCode, cachedValueType, true);
+ }
+ }
+
+ /**
* Set a string value for the cell.
*
* @param str value to set the cell to. For formulas we'll set the formula
default:
throw new IllegalArgumentException("Illegal cell type: " + cellType);
}
+ if (cellType != CELL_TYPE_FORMULA && _cell.isSetF()) {
+ _cell.unsetF();
+ }
}
/**
XSSFRichTextString rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(sstIndex));
return rt.getString();
case CELL_TYPE_NUMERIC:
- return String.valueOf(Double.parseDouble(_cell.getV()));
case CELL_TYPE_ERROR:
- return _cell.getV();
+ return _cell.getV();
case CELL_TYPE_FORMULA:
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator
- return "";
+ // just use cached formula result instead
+ break;
+ default:
+ throw new IllegalStateException("Unexpected cell type (" + cellType + ")");
}
- throw new RuntimeException("Unexpected cell type (" + cellType + ")");
+ cellType = getBaseCellType(false);
+ String textValue = _cell.getV();
+ switch (cellType) {
+ case CELL_TYPE_BOOLEAN:
+ if (TRUE_AS_STRING.equals(textValue)) {
+ return "TRUE";
+ }
+ if (FALSE_AS_STRING.equals(textValue)) {
+ return "FALSE";
+ }
+ throw new IllegalStateException("Unexpected boolean cached formula value '"
+ + textValue + "'.");
+ case CELL_TYPE_STRING:
+ case CELL_TYPE_NUMERIC:
+ case CELL_TYPE_ERROR:
+ return textValue;
+ }
+ throw new IllegalStateException("Unexpected formula result type (" + cellType + ")");
}
-
}
switch (type) {
case Cell.CELL_TYPE_NUMERIC:
cell.getNumericCellValue();
- fail();
break;
case Cell.CELL_TYPE_STRING:
cell.getStringCellValue();
- fail();
break;
case Cell.CELL_TYPE_BOOLEAN:
cell.getBooleanCellValue();
- fail();
break;
case Cell.CELL_TYPE_FORMULA:
cell.getCellFormula();
- fail();
break;
case Cell.CELL_TYPE_ERROR:
cell.getErrorCellValue();
- fail();
break;
}
+ fail("Should get exception when reading cell type (" + type + ").");
} catch (IllegalStateException e){
- ;
+ // expected during successful test
+ assertTrue(e.getMessage().startsWith("Cannot get a"));
}
}
}
assertEquals(true, cell.getBooleanCellValue());
}
+ /**
+ * Test for a bug observed around svn r886733 when using
+ * {@link FormulaEvaluator#evaluateInCell(Cell)} with a
+ * string result type.
+ */
+ public final void testConvertStringFormulaCell() {
+ Cell cellA1 = createACell();
+ cellA1.setCellFormula("\"abc\"");
+
+ // default cached formula result is numeric zero
+ assertEquals(0.0, cellA1.getNumericCellValue(), 0.0);
+
+ FormulaEvaluator fe = cellA1.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+
+ fe.evaluateFormulaCell(cellA1);
+ assertEquals("abc", cellA1.getStringCellValue());
+
+ fe.evaluateInCell(cellA1);
+ if (cellA1.getStringCellValue().equals("")) {
+ throw new AssertionFailedError("Identified bug with writing back formula result of type string");
+ }
+ assertEquals("abc", cellA1.getStringCellValue());
+ }
+ /**
+ * similar to {@link #testConvertStringFormulaCell()} but checks at a
+ * lower level that {#link {@link Cell#setCellType(int)} works properly
+ */
+ public final void testSetTypeStringOnFormulaCell() {
+ Cell cellA1 = createACell();
+ FormulaEvaluator fe = cellA1.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
+
+ cellA1.setCellFormula("\"DEF\"");
+ fe.clearAllCachedResultValues();
+ fe.evaluateFormulaCell(cellA1);
+ assertEquals("DEF", cellA1.getStringCellValue());
+ cellA1.setCellType(Cell.CELL_TYPE_STRING);
+ assertEquals("DEF", cellA1.getStringCellValue());
+
+ cellA1.setCellFormula("25.061");
+ fe.clearAllCachedResultValues();
+ fe.evaluateFormulaCell(cellA1);
+ confirmCannotReadString(cellA1);
+ assertEquals(25.061, cellA1.getNumericCellValue(), 0.0);
+ cellA1.setCellType(Cell.CELL_TYPE_STRING);
+ assertEquals("25.061", cellA1.getStringCellValue());
+
+ cellA1.setCellFormula("TRUE");
+ fe.clearAllCachedResultValues();
+ fe.evaluateFormulaCell(cellA1);
+ confirmCannotReadString(cellA1);
+ assertEquals(true, cellA1.getBooleanCellValue());
+ cellA1.setCellType(Cell.CELL_TYPE_STRING);
+ assertEquals("TRUE", cellA1.getStringCellValue());
+
+ cellA1.setCellFormula("#NAME?");
+ fe.clearAllCachedResultValues();
+ fe.evaluateFormulaCell(cellA1);
+ confirmCannotReadString(cellA1);
+ assertEquals(ErrorConstants.ERROR_NAME, cellA1.getErrorCellValue());
+ cellA1.setCellType(Cell.CELL_TYPE_STRING);
+ assertEquals("#NAME?", cellA1.getStringCellValue());
+ }
+
+ private static void confirmCannotReadString(Cell cell) {
+ assertProhibitedValueAccess(cell, Cell.CELL_TYPE_STRING);
+ }
+
/**
* Test for bug in convertCellValueToBoolean to make sure that formula results get converted
*/