Fix for cell references on rows > 32768 (bug #43399)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@576939 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2007-09-18 15:01:15 +00:00
parent 031873f7e6
commit 9c57017f5b
5 changed files with 118 additions and 1 deletions

View File

@ -36,6 +36,7 @@
</devs> </devs>
<release version="3.0.2-FINAL" date="2007-??-??"> <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="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">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> <action dev="POI-DEVELOPERS" type="add">43323 - [PATCH] - Support for adding Pictures to ShapeGroups in HSLF.</action>

View File

@ -33,6 +33,7 @@
<changes> <changes>
<release version="3.0.2-FINAL" date="2007-??-??"> <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="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">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> <action dev="POI-DEVELOPERS" type="add">43323 - [PATCH] - Support for adding Pictures to ShapeGroups in HSLF.</action>

View File

@ -35,8 +35,18 @@ public class ReferencePtg extends Ptg
{ {
private final static int SIZE = 5; private final static int SIZE = 5;
public final static byte sid = 0x24; public final static byte sid = 0x24;
private final static int MAX_ROW_NUMBER = 65536;
//public final static byte sid = 0x44; //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; private short field_1_row;
/**
* The column number, between 0 and ??
*/
private short field_2_col; private short field_2_col;
private BitField rowRelative = BitFieldFactory.getInstance(0x8000); private BitField rowRelative = BitFieldFactory.getInstance(0x8000);
private BitField colRelative = BitFieldFactory.getInstance(0x4000); private BitField colRelative = BitFieldFactory.getInstance(0x4000);
@ -93,6 +103,7 @@ public class ReferencePtg extends Ptg
public void writeBytes(byte [] array, int offset) public void writeBytes(byte [] array, int offset)
{ {
array[offset] = (byte) (sid + ptgClass); array[offset] = (byte) (sid + ptgClass);
LittleEndian.putShort(array,offset+1,field_1_row); LittleEndian.putShort(array,offset+1,field_1_row);
LittleEndian.putShort(array,offset+3,field_2_col); LittleEndian.putShort(array,offset+3,field_2_col);
} }
@ -101,11 +112,38 @@ public class ReferencePtg extends Ptg
{ {
field_1_row = row; 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() public short getRow()
{ {
return field_1_row; 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() public boolean isRowRelative()
{ {
@ -153,7 +191,7 @@ public class ReferencePtg extends Ptg
public String toFormulaString(Workbook book) public String toFormulaString(Workbook book)
{ {
//TODO -- should we store a cellreference instance in this ptg?? but .. memory is an issue, i believe! //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() { public byte getDefaultOperandClass() {

View File

@ -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());
}
}