]> source.dussan.org Git - poi.git/commitdiff
More fixes for Cell.setCellType() when converting from CELL_TYPE_FORMULA to CELL_TYPE...
authorJosh Micich <josh@apache.org>
Thu, 3 Dec 2009 22:18:12 +0000 (22:18 +0000)
committerJosh Micich <josh@apache.org>
Thu, 3 Dec 2009 22:18:12 +0000 (22:18 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@886951 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java

index ad1c53545db9c677e453c249cd0c317ad2fc342b..551d503560edb8b37db7380e4b92d8135c3216e4 100644 (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 + ")");
     }
 
     /**
index a3cc23a79513cd2c559234802ce0e269a8119bed..55aa71cfcf1a3753cea30be6291e49086d86a26a 100644 (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 + ")");
     }
-
 }
index 4e747b289890d19ae735a97c7f837c2c84f3c84e..39d21dd85fa67f2d1f05bc5bd6037f638fd26c84 100644 (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
         */