You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2008/01/16 14:14:34 UTC

svn commit: r612445 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/hssf/model/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/usermodel/ testcases/org/apache/poi/hssf/data/ testcases/org/apache/poi/hssf/usermodel/

Author: nick
Date: Wed Jan 16 05:14:31 2008
New Revision: 612445

URL: http://svn.apache.org/viewvc?rev=612445&view=rev
Log:
Patch to support UncalcedRecord and usermodel code for it, to indicate formulas on a sheet need recalculating (from bug #44233)

Added:
    poi/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java   (with props)
    poi/trunk/src/testcases/org/apache/poi/hssf/data/UncalcedRecord.xls   (with props)
Modified:
    poi/trunk/src/documentation/content/xdocs/changes.xml
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java
    poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
    poi/trunk/src/testcases/org/apache/poi/hssf/data/TestDataValidation.xls
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java

Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Wed Jan 16 05:14:31 2008
@@ -36,6 +36,7 @@
 
 		<!-- Don't forget to update status.xml too! -->
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <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>
             <action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes</action>
             <action dev="POI-DEVELOPERS" type="add">43008 - Add a moveCell method to HSSFRow, and deprecate setCellNum(), which didn't update things properly</action>

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Wed Jan 16 05:14:31 2008
@@ -33,6 +33,7 @@
 	<!-- Don't forget to update changes.xml too! -->
     <changes>
         <release version="3.0.2-FINAL" date="2008-??-??">
+            <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>
             <action dev="POI-DEVELOPERS" type="fix">44200 - Enable cloning of sheets with notes</action>
             <action dev="POI-DEVELOPERS" type="add">43008 - Add a moveCell method to HSSFRow, and deprecate setCellNum(), which didn't update things properly</action>

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/Sheet.java Wed Jan 16 05:14:31 2008
@@ -97,6 +97,8 @@
     protected ScenarioProtectRecord      scenprotect       =     null;
     protected PasswordRecord             password          =     null;
 
+    /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ 
+    protected boolean uncalced = false;
 	
     public static final byte PANE_LOWER_RIGHT = (byte)0;
     public static final byte PANE_UPPER_RIGHT = (byte)1;
@@ -161,6 +163,9 @@
                     break;
                 }
             }
+            else if (rec.getSid() == UncalcedRecord.sid) {
+            	retval.uncalced = true; 
+            }
             else if (rec.getSid() == DimensionsRecord.sid)
             {
                 // Make a columns aggregate if one hasn't ready been created.
@@ -736,8 +741,14 @@
         {
             Record record = (( Record ) records.get(k));
             
-            //Once the rows have been found in the list of records, start
-            //writing out the blocked row information. This includes the DBCell references
+            // Don't write out UncalcedRecord entries, as
+            //  we handle those specially just below
+            if (record instanceof UncalcedRecord) {
+            	continue;
+            }
+            
+            // Once the rows have been found in the list of records, start
+            //  writing out the blocked row information. This includes the DBCell references
             if (record instanceof RowRecordsAggregate) {
               pos += ((RowRecordsAggregate)record).serialize(pos, data, cells);   // rec.length;
             } else if (record instanceof ValueRecordsAggregate) {
@@ -745,8 +756,14 @@
             } else {
               pos += record.serialize(pos, data );   // rec.length;
             }
-            //If the BOF record was just serialized then add the IndexRecord
+            
+            // If the BOF record was just serialized then add the IndexRecord
             if (record.getSid() == BOFRecord.sid) {
+              // Add an optional UncalcedRecord
+              if (uncalced) {
+            	  UncalcedRecord rec = new UncalcedRecord();
+            	  pos += rec.serialize(pos, data);
+              }
               //Can there be more than one BOF for a sheet? If not then we can
               //remove this guard. So be safe it is left here.
               if (rows != null && !haveSerializedIndex) {
@@ -2184,6 +2201,11 @@
                     retval += 2;
             }
         }
+        // Add space for UncalcedRecord
+        if (uncalced) {
+        	retval += UncalcedRecord.getStaticRecordSize();
+        }
+        
         return retval;
     }
 
@@ -2651,8 +2673,22 @@
     public boolean isDisplayRowColHeadings() {
 	    return windowTwo.getDisplayRowColHeadings();
     }
+    
 
     /**
+	 * @return whether an uncalced record must be inserted or not at generation
+	 */
+	public boolean getUncalced() {
+		return uncalced;
+	}
+	/**
+	 * @param uncalced whether an uncalced record must be inserted or not at generation
+	 */
+	public void setUncalced(boolean uncalced) {
+		this.uncalced = uncalced;
+	}
+
+	/**
      * Returns the array of margins.  If not created, will create.
      *
      * @return the array of marings.

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/RecordFactory.java Wed Jan 16 05:14:31 2008
@@ -76,7 +76,7 @@
                 WriteProtectRecord.class, FilePassRecord.class, PaneRecord.class,
                 NoteRecord.class, ObjectProtectRecord.class, ScenarioProtectRecord.class, 
                 FileSharingRecord.class, ChartTitleFormatRecord.class,
-                DVRecord.class, DVALRecord.class
+                DVRecord.class, DVALRecord.class, UncalcedRecord.class
             };
     }
     private static Map           recordsMap  = recordsToMap(records);

Added: poi/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java?rev=612445&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java (added)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java Wed Jan 16 05:14:31 2008
@@ -0,0 +1,81 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record;
+
+import org.apache.poi.util.LittleEndian;
+
+/**
+ * Title: Uncalced Record
+ * <P>
+ * If this record occurs in the Worksheet Substream, it indicates that the formulas have not 
+ * been recalculated before the document was saved.
+ * 
+ * @author Olivier Leprince
+ */
+
+public class UncalcedRecord extends Record 
+{
+	public final static short sid = 0x5E;
+
+	/**
+	 * Default constructor
+	 */
+	public UncalcedRecord() {
+	}
+	/**
+	 * read constructor
+	 */
+	public UncalcedRecord(RecordInputStream in) {
+		super(in);
+	}
+
+	public short getSid() {
+		return sid;
+	}
+
+	protected void validateSid(short id) {
+		if (id != sid) {
+			throw new RecordFormatException("NOT AN UNCALCED RECORD");
+		}
+	}
+
+	protected void fillFields(RecordInputStream in) {
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		buffer.append("[UNCALCED]\n");
+		buffer.append("[/UNCALCED]\n");
+		return buffer.toString();
+	}
+
+	public int serialize(int offset, byte[] data) {
+		LittleEndian.putShort(data, 0 + offset, sid);
+		LittleEndian.putShort(data, 2 + offset, (short) 2);
+		LittleEndian.putShort(data, 4 + offset, (short) 0); // unused
+		return getRecordSize();
+	}
+
+	public int getRecordSize() {
+		return UncalcedRecord.getStaticRecordSize();
+	}
+
+	public static int getStaticRecordSize() {
+		return 6;
+	}
+}

Propchange: poi/trunk/src/java/org/apache/poi/hssf/record/UncalcedRecord.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java Wed Jan 16 05:14:31 2008
@@ -595,6 +595,26 @@
     }
 
     /**
+     * Whether a record must be inserted or not at generation to indicate that 
+     * formula must be recalculated when workbook is opened.
+     * @param value true if an uncalced record must be inserted or not at generation
+     */
+    public void setForceFormulaRecalculation(boolean value)
+    {
+    	sheet.setUncalced(value);
+    }
+    /**
+     * Whether a record must be inserted or not at generation to indicate that 
+     * formula must be recalculated when workbook is opened.
+     * @return true if an uncalced record must be inserted or not at generation
+     */
+    public boolean getForceFormulaRecalculation()
+    {
+    	return sheet.getUncalced();
+    }
+
+    
+    /**
      * determines whether the output is vertically centered on the page.
      * @param value true to vertically center, false otherwise.
      */

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/data/TestDataValidation.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/TestDataValidation.xls?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
Binary files - no diff available.

Added: poi/trunk/src/testcases/org/apache/poi/hssf/data/UncalcedRecord.xls
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/data/UncalcedRecord.xls?rev=612445&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/src/testcases/org/apache/poi/hssf/data/UncalcedRecord.xls
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java?rev=612445&r1=612444&r2=612445&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java Wed Jan 16 05:14:31 2008
@@ -19,14 +19,18 @@
 
 package org.apache.poi.hssf.usermodel;
 
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.model.Sheet;
 import org.apache.poi.hssf.record.HCenterRecord;
-import org.apache.poi.hssf.record.ProtectRecord;
 import org.apache.poi.hssf.record.PasswordRecord;
+import org.apache.poi.hssf.record.ProtectRecord;
 import org.apache.poi.hssf.record.SCLRecord;
 import org.apache.poi.hssf.record.VCenterRecord;
 import org.apache.poi.hssf.record.WSBoolRecord;
@@ -790,7 +794,81 @@
 		assertTrue(sheet3.getColumnWidth((short)0) <= maxWithRow1And2);
     }
 
-	public static void main(java.lang.String[] args) {
+    /**
+     * Setting ForceFormulaRecalculation on sheets
+     */
+    public void testForceRecalculation() throws Exception {
+        String filename = System.getProperty("HSSF.testdata.path");
+        filename = filename + "/UncalcedRecord.xls";
+        HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(filename));
+        
+        HSSFSheet sheet = workbook.getSheetAt(0);
+        HSSFSheet sheet2 = workbook.getSheetAt(0);
+        HSSFRow row = sheet.getRow(0);
+        row.createCell((short) 0).setCellValue(5);
+        row.createCell((short) 1).setCellValue(8);
+		assertFalse(sheet.getForceFormulaRecalculation());
+		assertFalse(sheet2.getForceFormulaRecalculation());
+
+        // Save and manually verify that on column C we have 0, value in template
+        File tempFile = new File(System.getProperty("java.io.tmpdir")+"/uncalced_err.xls" );
+        tempFile.delete();
+        FileOutputStream fout = new FileOutputStream( tempFile );
+        workbook.write( fout );
+        fout.close();
+        sheet.setForceFormulaRecalculation(true);
+		assertTrue(sheet.getForceFormulaRecalculation());
+
+        // Save and manually verify that on column C we have now 13, calculated value
+        tempFile = new File(System.getProperty("java.io.tmpdir")+"/uncalced_succ.xls" );
+        tempFile.delete();
+        fout = new FileOutputStream( tempFile );
+        workbook.write( fout );
+        fout.close();
+
+        // Try it can be opened
+		HSSFWorkbook wb2 = new HSSFWorkbook(new FileInputStream(tempFile));
+		
+		// And check correct sheet settings found
+		sheet = wb2.getSheetAt(0);
+		sheet2 = wb2.getSheetAt(1);
+		assertTrue(sheet.getForceFormulaRecalculation());
+		assertFalse(sheet2.getForceFormulaRecalculation());
+		
+		// Now turn if back off again
+		sheet.setForceFormulaRecalculation(false);
+		
+        fout = new FileOutputStream( tempFile );
+        wb2.write( fout );
+        fout.close();
+        wb2 = new HSSFWorkbook(new FileInputStream(tempFile));
+        
+		assertFalse(wb2.getSheetAt(0).getForceFormulaRecalculation());
+		assertFalse(wb2.getSheetAt(1).getForceFormulaRecalculation());
+		assertFalse(wb2.getSheetAt(2).getForceFormulaRecalculation());
+		
+		// Now add a new sheet, and check things work
+		//  with old ones unset, new one set
+		HSSFSheet s4 = wb2.createSheet();
+		s4.setForceFormulaRecalculation(true);
+		
+		assertFalse(sheet.getForceFormulaRecalculation());
+		assertFalse(sheet2.getForceFormulaRecalculation());
+		assertTrue(s4.getForceFormulaRecalculation());
+		
+        fout = new FileOutputStream( tempFile );
+        wb2.write( fout );
+        fout.close();
+        
+		HSSFWorkbook wb3 = new HSSFWorkbook(new FileInputStream(tempFile));
+		assertFalse(wb3.getSheetAt(0).getForceFormulaRecalculation());
+		assertFalse(wb3.getSheetAt(1).getForceFormulaRecalculation());
+		assertFalse(wb3.getSheetAt(2).getForceFormulaRecalculation());
+		assertTrue(wb3.getSheetAt(3).getForceFormulaRecalculation());
+    }
+
+    
+    public static void main(java.lang.String[] args) {
 		 junit.textui.TestRunner.run(TestHSSFSheet.class);
 	}    
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org