]> source.dussan.org Git - poi.git/commitdiff
Fix for cell references on rows > 32768 (bug #43399)
authorNick Burch <nick@apache.org>
Tue, 18 Sep 2007 15:01:15 +0000 (15:01 +0000)
committerNick Burch <nick@apache.org>
Tue, 18 Sep 2007 15:01:15 +0000 (15:01 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@576939 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/changes.xml
src/documentation/content/xdocs/status.xml
src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java
src/testcases/org/apache/poi/hssf/data/ReferencePtg.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java [new file with mode: 0644]

index 0f17e7cc3157fed9b64f3cc0a549f7b2f877e72d..bac5f0a16716b19c248a235204a10fd145f907d9 100644 (file)
@@ -36,6 +36,7 @@
     </devs>
 
         <release version="3.0.2-FINAL" date="2007-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">43399 - [PATCH] - Fix for Cell References for rows > 32678</action>
             <action dev="POI-DEVELOPERS" type="fix">43410 - [PATCH] - Improved Formula Parser support for numbers and ranges</action>
             <action dev="POI-DEVELOPERS" type="add">When writing HSLF files out, optionally preserve all OLE2 nodes (default is just the HSLF related nodes)</action>
             <action dev="POI-DEVELOPERS" type="add">43323 - [PATCH] - Support for adding Pictures to ShapeGroups in HSLF.</action>
index 9a3a8d6fa715b88b1073866b894d2f5737887232..9ab70b7fd0d01b3efcbba0e8ec305a4ef322d1c2 100644 (file)
@@ -33,6 +33,7 @@
 
     <changes>
         <release version="3.0.2-FINAL" date="2007-??-??">
+            <action dev="POI-DEVELOPERS" type="fix">43399 - [PATCH] - Fix for Cell References for rows > 32678</action>
             <action dev="POI-DEVELOPERS" type="fix">43410 - [PATCH] - Improved Formula Parser support for numbers and ranges</action>
             <action dev="POI-DEVELOPERS" type="add">When writing HSLF files out, optionally preserve all OLE2 nodes (default is just the HSLF related nodes)</action>
             <action dev="POI-DEVELOPERS" type="add">43323 - [PATCH] - Support for adding Pictures to ShapeGroups in HSLF.</action>
index 7e8758d6f2da8552fc03cbf1e4aa9bf379f7067f..df3e5a70bcbe056ad3b39d73eea02cc75bc6a450 100644 (file)
@@ -35,8 +35,18 @@ public class ReferencePtg extends Ptg
 {
     private final static int SIZE = 5;
     public final static byte sid  = 0x24;
+    private final static int MAX_ROW_NUMBER = 65536;             
     //public final static byte sid = 0x44;
+
+   /** 
+     * The row number, between 0 and 65535, but stored as a signed
+     *  short between -32767 and 32768.
+     * Take care about which version you fetch back!
+     */
     private short            field_1_row;
+    /**
+     * The column number, between 0 and ??
+     */
     private short            field_2_col;
     private BitField         rowRelative = BitFieldFactory.getInstance(0x8000);
     private BitField         colRelative = BitFieldFactory.getInstance(0x4000);
@@ -93,6 +103,7 @@ public class ReferencePtg extends Ptg
     public void writeBytes(byte [] array, int offset)
     {
         array[offset] = (byte) (sid + ptgClass);
+
         LittleEndian.putShort(array,offset+1,field_1_row);
         LittleEndian.putShort(array,offset+3,field_2_col);
     }
@@ -101,11 +112,38 @@ public class ReferencePtg extends Ptg
     {
         field_1_row = row;
     }
+    public void setRow(int row)
+    {
+        if(row < 0 || row >= MAX_ROW_NUMBER) {
+           throw new IllegalArgumentException("The row number, when specified as an integer, must be between 0 and " + MAX_ROW_NUMBER);
+        }
+        
+        // Save, wrapping as needed
+        if(row > Short.MAX_VALUE) {
+               field_1_row = (short)(row - MAX_ROW_NUMBER);
+        } else {
+               field_1_row = (short)row;
+        }
+    }
 
+    /**
+     * Returns the row number as a short, which will be
+     *  wrapped (negative) for values between 32769 and 65535
+     */
     public short getRow()
     {
         return field_1_row;
     }
+    /**
+     * Returns the row number as an int, between 0 and 65535
+     */
+    public int getRowAsInt()
+    {
+       if(field_1_row < 0) {
+               return field_1_row + MAX_ROW_NUMBER;
+       }
+        return field_1_row;
+    }
 
     public boolean isRowRelative()
     {
@@ -153,7 +191,7 @@ public class ReferencePtg extends Ptg
     public String toFormulaString(Workbook book)
     {
         //TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe!
-        return (new CellReference(getRow(),getColumn(),!isRowRelative(),!isColRelative())).toString();
+        return (new CellReference(getRowAsInt(),getColumn(),!isRowRelative(),!isColRelative())).toString();
     }
     
     public byte getDefaultOperandClass() {
diff --git a/src/testcases/org/apache/poi/hssf/data/ReferencePtg.xls b/src/testcases/org/apache/poi/hssf/data/ReferencePtg.xls
new file mode 100644 (file)
index 0000000..d415034
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/ReferencePtg.xls differ
diff --git a/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java b/src/testcases/org/apache/poi/hssf/record/formula/TestReferencePtg.java
new file mode 100644 (file)
index 0000000..226b144
--- /dev/null
@@ -0,0 +1,77 @@
+        
+/* ====================================================================
+   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.formula;
+
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+
+/**
+ * Tests for {@link ReferencePtg}.
+ */
+public class TestReferencePtg extends AbstractPtgTestCase
+{
+    /**
+     * Tests reading a file containing this ptg.
+     */
+    public void testReading() throws Exception
+    {
+        HSSFWorkbook workbook = loadWorkbook("ReferencePtg.xls");
+        HSSFSheet sheet = workbook.getSheetAt(0);
+
+        // First row
+        assertEquals("Wrong numeric value for original number", 55.0,
+                     sheet.getRow(0).getCell((short) 0).getNumericCellValue(), 0.0);
+        assertEquals("Wrong numeric value for referemce", 55.0,
+                     sheet.getRow(0).getCell((short) 1).getNumericCellValue(), 0.0);
+        assertEquals("Wrong formula string for reference", "A1",
+                     sheet.getRow(0).getCell((short) 1).getCellFormula());
+        
+        // Now moving over the 2**15 boundary
+        // (Remember that excel row (n) is poi row (n-1)
+        assertEquals("Wrong numeric value for original number", 32767.0,
+                sheet.getRow(32766).getCell((short) 0).getNumericCellValue(), 0.0);
+        assertEquals("Wrong numeric value for referemce", 32767.0,
+                sheet.getRow(32766).getCell((short) 1).getNumericCellValue(), 0.0);
+        assertEquals("Wrong formula string for reference", "A32767",
+                sheet.getRow(32766).getCell((short) 1).getCellFormula());
+        
+        assertEquals("Wrong numeric value for original number", 32768.0,
+                sheet.getRow(32767).getCell((short) 0).getNumericCellValue(), 0.0);
+        assertEquals("Wrong numeric value for referemce", 32768.0,
+                sheet.getRow(32767).getCell((short) 1).getNumericCellValue(), 0.0);
+        assertEquals("Wrong formula string for reference", "A32768",
+                sheet.getRow(32767).getCell((short) 1).getCellFormula());
+        
+        assertEquals("Wrong numeric value for original number", 32769.0,
+                sheet.getRow(32768).getCell((short) 0).getNumericCellValue(), 0.0);
+        assertEquals("Wrong numeric value for referemce", 32769.0,
+                sheet.getRow(32768).getCell((short) 1).getNumericCellValue(), 0.0);
+        assertEquals("Wrong formula string for reference", "A32769",
+                sheet.getRow(32768).getCell((short) 1).getCellFormula());
+        
+        assertEquals("Wrong numeric value for original number", 32770.0,
+                sheet.getRow(32769).getCell((short) 0).getNumericCellValue(), 0.0);
+        assertEquals("Wrong numeric value for referemce", 32770.0,
+                sheet.getRow(32769).getCell((short) 1).getNumericCellValue(), 0.0);
+        assertEquals("Wrong formula string for reference", "A32770",
+                sheet.getRow(32769).getCell((short) 1).getCellFormula());
+    }
+}
+
+