Browse Source

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
tags/REL_3_6
Josh Micich 14 years ago
parent
commit
ce310ec11a

+ 19
- 3
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java 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.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 + ")");
}

/**

+ 34
- 6
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java View File

@@ -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 + ")");
}

}

+ 70
- 6
src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java View File

@@ -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
*/

Loading…
Cancel
Save