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:
parent
513534c852
commit
7eea9324d8
@ -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 + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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 + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user