git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@886951 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_6
@@ -50,6 +50,7 @@ import org.apache.poi.ss.usermodel.CellStyle; | |||
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; | |||
@@ -811,14 +812,29 @@ public class HSSFCell implements Cell { | |||
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 + ")"); | |||
} | |||
/** |
@@ -271,6 +271,7 @@ public final class XSSFCell implements Cell { | |||
} | |||
break; | |||
case CELL_TYPE_FORMULA: | |||
checkFormulaCachedValueType(CELL_TYPE_STRING, getBaseCellType(false)); | |||
rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : ""); | |||
break; | |||
default: | |||
@@ -280,7 +281,13 @@ public final class XSSFCell implements Cell { | |||
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 | |||
@@ -697,6 +704,9 @@ public final class XSSFCell implements Cell { | |||
default: | |||
throw new IllegalArgumentException("Illegal cell type: " + cellType); | |||
} | |||
if (cellType != CELL_TYPE_FORMULA && _cell.isSetF()) { | |||
_cell.unsetF(); | |||
} | |||
} | |||
/** | |||
@@ -903,14 +913,32 @@ public final class XSSFCell implements Cell { | |||
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 + ")"); | |||
} | |||
} |
@@ -102,27 +102,24 @@ public abstract class BaseTestCell extends TestCase { | |||
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")); | |||
} | |||
} | |||
} | |||
@@ -346,6 +343,73 @@ public abstract class BaseTestCell extends TestCase { | |||
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 | |||
*/ |