]> source.dussan.org Git - poi.git/commitdiff
Merged revisions 614878-614909 via svnmerge from
authorUgo Cei <ugo@apache.org>
Fri, 25 Jan 2008 11:39:29 +0000 (11:39 +0000)
committerUgo Cei <ugo@apache.org>
Fri, 25 Jan 2008 11:39:29 +0000 (11:39 +0000)
https://svn.apache.org/repos/asf/poi/trunk

........
  r614878 | nick | 2008-01-24 15:13:05 +0100 (Thu, 24 Jan 2008) | 1 line

  Add another formula evaluation method, evaluateFormulaCell(cell), which will re-calculate the value for a formula, without affecting the formula itself. Add tests too, and update the documentation
........
  r614909 | nick | 2008-01-24 17:05:27 +0100 (Thu, 24 Jan 2008) | 1 line

  From bug #44254 - avoid some unread bytes warnings, and process the contents of DVALRecord
........

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@615185 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/hssf/eval.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/DVALRecord.java
src/java/org/apache/poi/hssf/record/UncalcedRecord.java
src/java/org/apache/poi/hssf/record/formula/ErrPtg.java
src/java/org/apache/poi/hssf/usermodel/HSSFCell.java
src/scratchpad/src/org/apache/poi/hssf/usermodel/HSSFFormulaEvaluator.java
src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java [new file with mode: 0644]

index a2bd40d73f72da1be7a5f1d2e16cc282b2101a7f..51aeb22461679d232a938b021a28d59ad1c724cb 100644 (file)
@@ -36,6 +36,8 @@
 
                <!-- Don't forget to update status.xml too! -->
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">44254 - Avoid some unread byte warnings, and properly understand DVALRecord</action>
+            <action dev="POI-DEVELOPERS" type="add">Add another formula evaluation method, evaluateFormulaCell(cell), which will re-calculate the value for a formula, without affecting the formula itself.</action>
             <action dev="POI-DEVELOPERS" type="fix">41726 - Fix how we handle signed cell offsets in relative areas and references</action>
             <action dev="POI-DEVELOPERS" type="add">44233 - Support for getting and setting a flag on the sheet, which tells excel to re-calculate all formulas on it at next reload</action>
             <action dev="POI-DEVELOPERS" type="fix">44201 - Enable cloning of sheets with data validation rules</action>
index 1416ad7c29c5a03b41a4c485f5301625a6bb2059..8d635121737af90f2a05f79ad6c627a618d18d53 100644 (file)
                        <p>The following code demonstrates how to use the HSSFFormulaEvaluator 
                                in the context of other POI excel reading code.
                        </p>
-                       <p>There are two ways in which you can use the HSSFFormulaEvalutator API.</p>
+                       <p>There are several ways in which you can use the HSSFFormulaEvalutator API.</p>
 
                        <anchor id="Evaluate"/>
                        <section><title>Using HSSFFormulaEvaluator.<strong>evaluate</strong>(HSSFCell cell)</title>
+                               <p>This evaluates a given cell, and returns the new value,
+                               without affecting the cell</p>
                                <source>
 FileInputStream fis = new FileInputStream("c:/temp/test.xls");
 HSSFWorkbook wb = new HSSFWorkbook(fis);
@@ -102,12 +104,60 @@ switch (cellValue.getCellType()) {
                                </p>
                        </section>
 
+                       <anchor id="EvaluateFormulaCell"/>
+                       <section><title>Using HSSFFormulaEvaluator.<strong>evaluateFormulaCell</strong>(HSSFCell cell)</title>
+                               <p><strong>evaluateFormulaCell</strong>(HSSFCell cell) 
+                               will check to see if the supplied cell is a formula cell. 
+                               If it isn't, then no changes will be made to it. If it is, 
+                               then the formula is evaluated. The value for the formula
+                               is saved alongside it, to be displayed in excel. The
+                               formula remains in the cell, just with a new value</p>
+                               <p>The return of the function is the type of the
+                               formula result, such as HSSFCell.CELL_TYPE_BOOLEAN</p>
+                               <source>
+FileInputStream fis = new FileInputStream("/somepath/test.xls");
+HSSFWorkbook wb = new HSSFWorkbook(fis);
+HSSFSheet sheet = wb.getSheetAt(0);
+HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+
+// suppose your formula is in B3
+CellReference cellReference = new CellReference("B3"); 
+HSSFRow row = sheet.getRow(cellReference.getRow());
+HSSFCell cell = row.getCell(cellReference.getCol()); 
+evaluator.setCurrentRow(row);
+
+if (cell!=null) {
+       switch (<strong>evaluator.evaluateFormulaCell</strong>(cell)) {
+               case HSSFCell.CELL_TYPE_BOOLEAN:
+                   System.out.println(cell.getBooleanCellValue());
+                   break;
+               case HSSFCell.CELL_TYPE_NUMERIC:
+                   System.out.println(cell.getNumberCellValue());
+                   break;
+               case HSSFCell.CELL_TYPE_STRING:
+                   System.out.println(cell.getStringCellValue());
+                   break;
+               case HSSFCell.CELL_TYPE_BLANK:
+                   break;
+               case HSSFCell.CELL_TYPE_ERROR:
+                   System.out.println(cell.getErrorCellValue());
+                   break;
+               
+               // CELL_TYPE_FORMULA will never occur
+               case HSSFCell.CELL_TYPE_FORMULA: 
+                   break;
+       }
+}
+                               </source>
+                       </section>
+
                        <anchor id="EvaluateInCell"/>
                        <section><title>Using HSSFFormulaEvaluator.<strong>evaluateInCell</strong>(HSSFCell cell)</title>
                                <p><strong>evaluateInCell</strong>(HSSFCell cell) will check to
                                see if the supplied cell is a formula cell. If it isn't,
                                then no changes will be made to it. If it is, then the
-                               formula is evaluated, and the new value saved into the cell.</p>
+                               formula is evaluated, and the new value saved into the cell,
+                               in place of the old formula.</p>
                                <source>
 FileInputStream fis = new FileInputStream("/somepath/test.xls");
 HSSFWorkbook wb = new HSSFWorkbook(fis);
@@ -154,14 +204,14 @@ for(int sheetNum = 0; sheetNum &lt; wb.getNumberOfSheets(); sheetNum++) {
        HSSFSheet sheet = wb.getSheetAt(sheetNum);
        HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
 
-       for(Iterator rit = s.rowIterator(); rit.hasNext();) {
+       for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
                HSSFRow r = (HSSFRow)rit.next();
                evaluator.setCurrentRow(r);
 
                for(Iterator cit = r.cellIterator(); cit.hasNext();) {
                        HSSFCell c = (HSSFCell)cit.next();
                        if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
-                               evaluator.evaluateInCell(c);
+                               evaluator.evaluateFormulaCell(c);
                        }
                }
        }
index 56b868b8753c003f225654672e8f39b7d420cca3..feabdf76b40b9917fd6a8f0ebb4ed7a973c303d8 100644 (file)
@@ -33,6 +33,8 @@
        <!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">44254 - Avoid some unread byte warnings, and properly understand DVALRecord</action>
+            <action dev="POI-DEVELOPERS" type="add">Add another formula evaluation method, evaluateFormulaCell(cell), which will re-calculate the value for a formula, without affecting the formula itself.</action>
             <action dev="POI-DEVELOPERS" type="fix">41726 - Fix how we handle signed cell offsets in relative areas and references</action>
             <action dev="POI-DEVELOPERS" type="add">44233 - Support for getting and setting a flag on the sheet, which tells excel to re-calculate all formulas on it at next reload</action>
             <action dev="POI-DEVELOPERS" type="fix">44201 - Enable cloning of sheets with data validation rules</action>
index 858f525ca0c28ce9c09956e40a3967334f74b7c0..2846f5066c3b93df9ab2d904d6cbb19f04ad9abc 100644 (file)
@@ -29,19 +29,22 @@ import org.apache.poi.util.LittleEndian;
 
 public class DVALRecord extends Record
 {
-    public final static short sid = 0x01B2;
+       public final static short sid = 0x01B2;
 
-    //unknown field ; it's size should be 10
-    private short field_unknown     = 0x0000;
+       /** Options of the DVAL */
+       private short field_1_options;
+       /** Horizontal position of the dialog */
+       private int field_2_horiz_pos;
+       /** Vertical position of the dialog */
+       private int field_3_vert_pos;
 
-    //Object ID of the drop down arrow object for list boxes ;
-    //in our case this will be always FFFF , until
-    //MSODrawingGroup and MSODrawing records are implemented
-    private int  field_cbo_id      = 0xFFFFFFFF;
+       /** Object ID of the drop down arrow object for list boxes ;
+        * in our case this will be always FFFF , until
+        * MSODrawingGroup and MSODrawing records are implemented */
+       private int  field_cbo_id      = 0xFFFFFFFF;
 
-    //Number of following DV records
-    //Default value is 1
-    private int  field_3_dv_no     = 0x00000000;
+       /** Number of following DV Records */
+       private int  field_5_dv_no     = 0x00000000;
 
     public DVALRecord()
     {
@@ -66,17 +69,38 @@ public class DVALRecord extends Record
         }
     }
 
-    protected void fillFields(RecordInputStream in)
-    {
-        for ( int i=0; i<5; i++)
-        {
-               this.field_unknown = in.readShort();
-        }
+       protected void fillFields(RecordInputStream in)
+       {
+               this.field_1_options = in.readShort();
+               this.field_2_horiz_pos = in.readInt();
+               this.field_3_vert_pos = in.readInt();
         this.field_cbo_id    = in.readInt(); 
-        this.field_3_dv_no   = in.readInt();
-    }
+        this.field_5_dv_no   = in.readInt();
+       }
+
 
     /**
+        * @param field_1_options the options of the dialog
+        */
+       public void setOptions(short field_1_options) {
+               this.field_1_options = field_1_options;
+       }
+
+       /**
+        * @param field_2_horiz_pos the Horizontal position of the dialog
+        */
+       public void setHorizontalPos(int field_2_horiz_pos) {
+               this.field_2_horiz_pos = field_2_horiz_pos;
+       }
+
+       /**
+        * @param field_3_vert_pos the Vertical position of the dialog
+        */
+       public void setVerticalPos(int field_3_vert_pos) {
+               this.field_3_vert_pos = field_3_vert_pos;
+       }
+
+       /**
      * set the object ID of the drop down arrow object for list boxes
      * @param cboID - Object ID
      */
@@ -91,10 +115,33 @@ public class DVALRecord extends Record
      */
     public void setDVRecNo(int dvNo)
     {
-        this.field_3_dv_no = dvNo;
+        this.field_5_dv_no = dvNo;
     }
 
+    
+    
     /**
+        * @return the field_1_options
+        */
+       public short getOptions() {
+               return field_1_options;
+       }
+
+       /**
+        * @return the Horizontal position of the dialog
+        */
+       public int getHorizontalPos() {
+               return field_2_horiz_pos;
+       }
+
+       /**
+        * @return the the Vertical position of the dialog
+        */
+       public int getVerticalPos() {
+               return field_3_vert_pos;
+       }
+
+       /**
      * get Object ID of the drop down arrow object for list boxes
      */
     public int getObjectID( )
@@ -107,29 +154,32 @@ public class DVALRecord extends Record
      */
     public int getDVRecNo( )
     {
-        return this.field_3_dv_no;
+        return this.field_5_dv_no;
     }
 
 
-    public String toString()
-    {
-        StringBuffer buffer = new StringBuffer();
+       public String toString()
+       {
+               StringBuffer buffer = new StringBuffer();
 
-        buffer.append("[DVAL]\n");
-        buffer.append("    .comboObjectID   = ").append(Integer.toHexString(this.getObjectID())).append("\n");
-        buffer.append("    .DVRecordsNumber = ").append(Integer.toHexString(this.getDVRecNo())).append("\n");
-        buffer.append("[/DVAL]\n");
-        return buffer.toString();
-    }
+               buffer.append("[DVAL]\n");
+               buffer.append("    .options      = ").append(this.getOptions()).append('\n');
+               buffer.append("    .horizPos     = ").append(this.getHorizontalPos()).append('\n');
+               buffer.append("    .vertPos      = ").append(this.getVerticalPos()).append('\n');
+               buffer.append("    .comboObjectID   = ").append(Integer.toHexString(this.getObjectID())).append("\n");
+               buffer.append("    .DVRecordsNumber = ").append(Integer.toHexString(this.getDVRecNo())).append("\n");
+               buffer.append("[/DVAL]\n");
+               return buffer.toString();
+       }
 
     public int serialize(int offset, byte [] data)
     {
         LittleEndian.putShort(data, 0 + offset, this.sid);
         LittleEndian.putShort(data, 2 + offset, ( short)(this.getRecordSize()-4));
-        for ( int i=0; i<5; i++)
-        {
-          LittleEndian.putShort(data, 4 + i*2 + offset, (short)this.field_unknown);
-        }
+               
+               LittleEndian.putShort(data, 4 + offset, this.getOptions());
+               LittleEndian.putInt(data, 6 + offset, this.getHorizontalPos());
+               LittleEndian.putInt(data, 10 + offset, this.getVerticalPos());
         LittleEndian.putInt(data, 14 + offset, this.getObjectID());
         LittleEndian.putInt(data, 18 + offset, this.getDVRecNo());
         return getRecordSize();
@@ -149,9 +199,11 @@ public class DVALRecord extends Record
     public Object clone()
     {
       DVALRecord rec = new DVALRecord();
-      rec.field_unknown = this.field_unknown;
+      rec.field_1_options = field_1_options;
+      rec.field_2_horiz_pos = field_2_horiz_pos;
+      rec.field_3_vert_pos = field_3_vert_pos;
       rec.field_cbo_id = this.field_cbo_id;
-      rec.field_3_dv_no = this.field_3_dv_no;
+      rec.field_5_dv_no = this.field_5_dv_no;
       return rec;
     }
-}
\ No newline at end of file
+}
index c3243f2585c3c9b6956f4792efe2e03e9a489fb2..a67b0b5af4adb9b2eed6868bd0ef87778869b7b1 100644 (file)
@@ -55,6 +55,7 @@ public class UncalcedRecord extends Record
        }
 
        protected void fillFields(RecordInputStream in) {
+               short unused = in.readShort();
        }
 
        public String toString() {
index e382d4e7599b64b383e802c7ad17ed33badb558b..34bad6f32c359e2a3085c2c9625c73be3c4af8e3 100644 (file)
@@ -29,7 +29,7 @@ import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
 public class ErrPtg extends Ptg
 {
     public static final short sid  = 0x1c;
-    private static final int  SIZE = 7;
+    private static final int  SIZE = 2;
     private byte              field_1_error_code;
 
     /** Creates new ErrPtg */
index f7e90d0ce4ebaf3f77712ee93dfc16d39abf486d..33417dad7f28e8171f3ff16f497e1e846cd928cb 100644 (file)
@@ -538,7 +538,13 @@ public class HSSFCell implements Cell
         {
             setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex);
         }
-        (( NumberRecord ) record).setValue(value);
+        
+        // Save into the apropriate record
+        if(record instanceof FormulaRecordAggregate) {
+               (( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value);
+        } else {
+               (( NumberRecord ) record).setValue(value);
+        }
     }
 
     /**
index 2a9fc6c64bdfbc1ec2d8d3c2cec6b79ef1b89e3a..f60a6adaaca3fcf8dce6b438a7c1f024ae5853fe 100644 (file)
@@ -217,14 +217,66 @@ public class HSSFFormulaEvaluator {
     
     
     /**
-     * If cell contains formula, it evaluates the formula, and puts the 
-     * formula result back into the cell.
-     * Else if cell does not contain formula, this method leaves the cell 
-     * unchanged. Note that the same instance of HSSFCell is returned to 
+     * If cell contains formula, it evaluates the formula,
+     *  and saves the result of the formula. The cell
+     *  remains as a formula cell.
+     * Else if cell does not contain formula, this method leaves
+     *  the cell unchanged. 
+     * Note that the type of the formula result is returned,
+     *  so you know what kind of value is also stored with
+     *  the formula. 
+     * <pre>
+     * int evaluatedCellType = evaluator.evaluateFormulaCell(cell);
+     * </pre>
+     * Be aware that your cell will hold both the formula,
+     *  and the result. If you want the cell replaced with
+     *  the result of the formula, use {@link #evaluateInCell(HSSFCell)}
+     * @param cell The cell to evaluate
+     * @return The type of the formula result (the cell's type remains as HSSFCell.CELL_TYPE_FORMULA however)
+     */
+    public int evaluateFormulaCell(HSSFCell cell) {
+        if (cell != null) {
+            switch (cell.getCellType()) {
+            case HSSFCell.CELL_TYPE_FORMULA:
+                CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook));
+                switch (cv.getCellType()) {
+                case HSSFCell.CELL_TYPE_BOOLEAN:
+                    cell.setCellValue(cv.getBooleanValue());
+                    break;
+                case HSSFCell.CELL_TYPE_ERROR:
+                    cell.setCellValue(cv.getErrorValue());
+                    break;
+                case HSSFCell.CELL_TYPE_NUMERIC:
+                    cell.setCellValue(cv.getNumberValue());
+                    break;
+                case HSSFCell.CELL_TYPE_STRING:
+                    cell.setCellValue(cv.getRichTextStringValue());
+                    break;
+                case HSSFCell.CELL_TYPE_BLANK:
+                    break;
+                case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula
+                    break;
+                }
+                return cv.getCellType();
+            }
+        }
+        return -1;
+    }
+        
+    /**
+     * If cell contains formula, it evaluates the formula, and
+     *  puts the formula result back into the cell, in place
+     *  of the old formula.
+     * Else if cell does not contain formula, this method leaves
+     *  the cell unchanged. 
+     * Note that the same instance of HSSFCell is returned to 
      * allow chained calls like:
      * <pre>
      * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType();
      * </pre>
+     * Be aware that your cell value will be changed to hold the
+     *  result of the formula. If you simply want the formula
+     *  value computed for you, use {@link #evaluateFormulaCell(HSSFCell)}
      * @param cell
      */
     public HSSFCell evaluateInCell(HSSFCell cell) {
diff --git a/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java b/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestFormulaEvaluatorDocs.java
new file mode 100644 (file)
index 0000000..cd2acc7
--- /dev/null
@@ -0,0 +1,117 @@
+package org.apache.poi.hssf.usermodel;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests to show that our documentation at
+ *  http://poi.apache.org/hssf/eval.html
+ * all actually works as we'd expect them to
+ */
+public class TestFormulaEvaluatorDocs extends TestCase {
+       protected void setUp() throws Exception {
+               super.setUp();
+       }
+
+       /**
+        * http://poi.apache.org/hssf/eval.html#EvaluateAll
+        */
+       public void testEvaluateAll() throws Exception {
+               HSSFWorkbook wb = new HSSFWorkbook();
+               HSSFSheet s1 = wb.createSheet();
+               HSSFSheet s2 = wb.createSheet();
+               wb.setSheetName(0, "S1");
+               wb.setSheetName(1, "S2");
+               
+               HSSFRow s1r1 = s1.createRow(0);
+               HSSFRow s1r2 = s1.createRow(1);
+               HSSFRow s2r1 = s2.createRow(0);
+               
+               HSSFCell s1r1c1 = s1r1.createCell((short)0);
+               HSSFCell s1r1c2 = s1r1.createCell((short)1);
+               HSSFCell s1r1c3 = s1r1.createCell((short)2);
+               s1r1c1.setCellValue(22.3);
+               s1r1c2.setCellValue(33.4);
+               s1r1c3.setCellFormula("SUM(A1:B1)");
+               
+               HSSFCell s1r2c1 = s1r2.createCell((short)0);
+               HSSFCell s1r2c2 = s1r2.createCell((short)1);
+               HSSFCell s1r2c3 = s1r2.createCell((short)2);
+               s1r2c1.setCellValue(-1.2);
+               s1r2c2.setCellValue(-3.4);
+               s1r2c3.setCellFormula("SUM(A2:B2)");
+               
+               HSSFCell s2r1c1 = s2r1.createCell((short)0);
+               s2r1c1.setCellFormula("S1!A1");
+               
+               // Not evaluated yet
+               assertEquals(0.0, s1r1c3.getNumericCellValue(), 0);
+               assertEquals(0.0, s1r2c3.getNumericCellValue(), 0);
+               assertEquals(0.0, s2r1c1.getNumericCellValue(), 0);
+               
+               // Do a full evaluate, as per our docs
+               // uses evaluateFormulaCell()
+               for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
+                       HSSFSheet sheet = wb.getSheetAt(sheetNum);
+                       HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+
+                       for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
+                               HSSFRow r = (HSSFRow)rit.next();
+                               evaluator.setCurrentRow(r);
+
+                               for(Iterator cit = r.cellIterator(); cit.hasNext();) {
+                                       HSSFCell c = (HSSFCell)cit.next();
+                                       if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
+                                               evaluator.evaluateFormulaCell(c);
+                                               
+                                               // For testing - all should be numeric
+                                               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, evaluator.evaluateFormulaCell(c));
+                                       }
+                               }
+                       }
+               }
+               
+               // Check now as expected
+               assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0);
+               assertEquals("SUM(A1:B1)", wb.getSheetAt(0).getRow(0).getCell((short)2).getCellFormula());
+               assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType());
+               
+               assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0);
+               assertEquals("SUM(A2:B2)", wb.getSheetAt(0).getRow(1).getCell((short)2).getCellFormula());
+               assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType());
+               
+               assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0);
+               assertEquals("S1!A1", wb.getSheetAt(1).getRow(0).getCell((short)0).getCellFormula());
+               assertEquals(HSSFCell.CELL_TYPE_FORMULA, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType());
+               
+               
+               // Now do the alternate call, which zaps the formulas
+               // uses evaluateInCell()
+               for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
+                       HSSFSheet sheet = wb.getSheetAt(sheetNum);
+                       HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+
+                       for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
+                               HSSFRow r = (HSSFRow)rit.next();
+                               evaluator.setCurrentRow(r);
+
+                               for(Iterator cit = r.cellIterator(); cit.hasNext();) {
+                                       HSSFCell c = (HSSFCell)cit.next();
+                                       if(c.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
+                                               evaluator.evaluateInCell(c);
+                                       }
+                               }
+                       }
+               }
+               
+               assertEquals(55.7, wb.getSheetAt(0).getRow(0).getCell((short)2).getNumericCellValue(), 0);
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(0).getCell((short)2).getCellType());
+               
+               assertEquals(-4.6, wb.getSheetAt(0).getRow(1).getCell((short)2).getNumericCellValue(), 0);
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(0).getRow(1).getCell((short)2).getCellType());
+               
+               assertEquals(22.3, wb.getSheetAt(1).getRow(0).getCell((short)0).getNumericCellValue(), 0);
+               assertEquals(HSSFCell.CELL_TYPE_NUMERIC, wb.getSheetAt(1).getRow(0).getCell((short)0).getCellType());
+       }
+}