More fixes for Cell.setCellType() when converting from CELL_TYPE_FORMULA to CELL_TYPE_STRING. Similar to issues fixed with bugzilla 46479.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@886951 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2009-12-03 22:18:12 +00:00
parent 513534c852
commit 7eea9324d8
3 changed files with 123 additions and 15 deletions

View File

@ -50,6 +50,7 @@ import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Comment; import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.RichTextString; 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.formula.FormulaType;
import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -811,14 +812,29 @@ public class HSSFCell implements Cell {
int sstIndex = ((LabelSSTRecord)_record).getSSTIndex(); int sstIndex = ((LabelSSTRecord)_record).getSSTIndex();
return _book.getWorkbook().getSSTString(sstIndex).getString(); return _book.getWorkbook().getSSTString(sstIndex).getString();
case CELL_TYPE_NUMERIC: case CELL_TYPE_NUMERIC:
return String.valueOf(((NumberRecord)_record).getValue()); return NumberToTextConverter.toText(((NumberRecord)_record).getValue());
case CELL_TYPE_ERROR: case CELL_TYPE_ERROR:
return HSSFErrorConstants.getText(((BoolErrRecord) _record).getErrorValue()); return HSSFErrorConstants.getText(((BoolErrRecord) _record).getErrorValue());
case CELL_TYPE_FORMULA: case CELL_TYPE_FORMULA:
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator // 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 + ")");
} }
/** /**

View File

@ -271,6 +271,7 @@ public final class XSSFCell implements Cell {
} }
break; break;
case CELL_TYPE_FORMULA: case CELL_TYPE_FORMULA:
checkFormulaCachedValueType(CELL_TYPE_STRING, getBaseCellType(false));
rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : ""); rt = new XSSFRichTextString(_cell.isSetV() ? _cell.getV() : "");
break; break;
default: default:
@ -280,6 +281,12 @@ public final class XSSFCell implements Cell {
return rt; 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. * Set a string value for the cell.
* *
@ -697,6 +704,9 @@ public final class XSSFCell implements Cell {
default: default:
throw new IllegalArgumentException("Illegal cell type: " + cellType); 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)); XSSFRichTextString rt = new XSSFRichTextString(_sharedStringSource.getEntryAt(sstIndex));
return rt.getString(); return rt.getString();
case CELL_TYPE_NUMERIC: case CELL_TYPE_NUMERIC:
return String.valueOf(Double.parseDouble(_cell.getV()));
case CELL_TYPE_ERROR: case CELL_TYPE_ERROR:
return _cell.getV(); return _cell.getV();
case CELL_TYPE_FORMULA: case CELL_TYPE_FORMULA:
// should really evaluate, but HSSFCell can't call HSSFFormulaEvaluator // 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 + ")");
} }
} }

View File

@ -102,27 +102,24 @@ public abstract class BaseTestCell extends TestCase {
switch (type) { switch (type) {
case Cell.CELL_TYPE_NUMERIC: case Cell.CELL_TYPE_NUMERIC:
cell.getNumericCellValue(); cell.getNumericCellValue();
fail();
break; break;
case Cell.CELL_TYPE_STRING: case Cell.CELL_TYPE_STRING:
cell.getStringCellValue(); cell.getStringCellValue();
fail();
break; break;
case Cell.CELL_TYPE_BOOLEAN: case Cell.CELL_TYPE_BOOLEAN:
cell.getBooleanCellValue(); cell.getBooleanCellValue();
fail();
break; break;
case Cell.CELL_TYPE_FORMULA: case Cell.CELL_TYPE_FORMULA:
cell.getCellFormula(); cell.getCellFormula();
fail();
break; break;
case Cell.CELL_TYPE_ERROR: case Cell.CELL_TYPE_ERROR:
cell.getErrorCellValue(); cell.getErrorCellValue();
fail();
break; break;
} }
fail("Should get exception when reading cell type (" + type + ").");
} catch (IllegalStateException e){ } 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()); 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 * Test for bug in convertCellValueToBoolean to make sure that formula results get converted
*/ */