Patch largely from Josh from bug #44539 - Support for area references in formulas of rows >= 32768
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@634630 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
96198ae3d1
commit
ff78b7ac71
@ -36,6 +36,7 @@
|
||||
|
||||
<!-- Don't forget to update status.xml too! -->
|
||||
<release version="3.1-beta1" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">44539 - Support for area references in formulas of rows >= 32768</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">44536 - Improved support for detecting read-only recommended files</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">28231 - For apparently truncated files, which are somehow still valid, now issue a truncation warning but carry on, rather than giving an exception as before</action>
|
||||
|
@ -33,6 +33,7 @@
|
||||
<!-- Don't forget to update changes.xml too! -->
|
||||
<changes>
|
||||
<release version="3.1-beta1" date="2008-??-??">
|
||||
<action dev="POI-DEVELOPERS" type="add">44539 - Support for area references in formulas of rows >= 32768</action>
|
||||
<action dev="POI-DEVELOPERS" type="add">44536 - Improved support for detecting read-only recommended files</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">43901 - Correctly update the internal last cell number when adding and removing cells (previously sometimes off-by-one)</action>
|
||||
<action dev="POI-DEVELOPERS" type="fix">44504 - Added initial support for recognising external functions like YEARFRAC and ISEVEN (using NameXPtg), via LinkTable support</action>
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -16,7 +15,6 @@
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Stack;
|
||||
@ -34,10 +32,7 @@ import org.apache.poi.hssf.record.formula.*;
|
||||
* record types.
|
||||
* @author Danny Mui at apache dot org
|
||||
*/
|
||||
|
||||
public class SharedFormulaRecord
|
||||
extends Record
|
||||
{
|
||||
public final class SharedFormulaRecord extends Record {
|
||||
public final static short sid = 0x4BC;
|
||||
|
||||
private int field_1_first_row;
|
||||
@ -257,17 +252,18 @@ public class SharedFormulaRecord
|
||||
}
|
||||
}
|
||||
|
||||
private short fixupRelativeColumn(int currentcolumn, short column, boolean relative) {
|
||||
private int fixupRelativeColumn(int currentcolumn, int column, boolean relative) {
|
||||
if(relative) {
|
||||
if((column&128)!=0) column=(short)(column-256);
|
||||
column+=currentcolumn;
|
||||
// mask out upper bits to produce 'wrapping' at column 256 ("IV")
|
||||
return (column + currentcolumn) & 0x00FF;
|
||||
}
|
||||
return column;
|
||||
}
|
||||
|
||||
private short fixupRelativeRow(int currentrow, short row, boolean relative) {
|
||||
private int fixupRelativeRow(int currentrow, int row, boolean relative) {
|
||||
if(relative) {
|
||||
row+=currentrow;
|
||||
// mask out upper bits to produce 'wrapping' at row 65536
|
||||
return (row+currentrow) & 0x00FFFF;
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
public final static byte sid = 0x3b;
|
||||
private final static int SIZE = 11; // 10 + 1 for Ptg
|
||||
private short field_1_index_extern_sheet;
|
||||
private short field_2_first_row;
|
||||
private short field_3_last_row;
|
||||
private short field_4_first_column;
|
||||
private short field_5_last_column;
|
||||
private int field_2_first_row;
|
||||
private int field_3_last_row;
|
||||
private int field_4_first_column;
|
||||
private int field_5_last_column;
|
||||
|
||||
private BitField rowRelative = BitFieldFactory.getInstance( 0x8000 );
|
||||
private BitField colRelative = BitFieldFactory.getInstance( 0x4000 );
|
||||
@ -64,10 +64,10 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
public Area3DPtg(RecordInputStream in)
|
||||
{
|
||||
field_1_index_extern_sheet = in.readShort();
|
||||
field_2_first_row = in.readShort();
|
||||
field_3_last_row = in.readShort();
|
||||
field_4_first_column = in.readShort();
|
||||
field_5_last_column = in.readShort();
|
||||
field_2_first_row = in.readUShort();
|
||||
field_3_last_row = in.readUShort();
|
||||
field_4_first_column = in.readUShort();
|
||||
field_5_last_column = in.readUShort();
|
||||
}
|
||||
|
||||
public Area3DPtg(short firstRow, short lastRow, short firstColumn, short lastColumn,
|
||||
@ -107,10 +107,10 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
{
|
||||
array[0 + offset] = (byte) ( sid + ptgClass );
|
||||
LittleEndian.putShort( array, 1 + offset, getExternSheetIndex() );
|
||||
LittleEndian.putShort( array, 3 + offset, getFirstRow() );
|
||||
LittleEndian.putShort( array, 5 + offset, getLastRow() );
|
||||
LittleEndian.putShort( array, 7 + offset, getFirstColumnRaw() );
|
||||
LittleEndian.putShort( array, 9 + offset, getLastColumnRaw() );
|
||||
LittleEndian.putShort( array, 3 + offset, (short)getFirstRow() );
|
||||
LittleEndian.putShort( array, 5 + offset, (short)getLastRow() );
|
||||
LittleEndian.putShort( array, 7 + offset, (short)getFirstColumnRaw() );
|
||||
LittleEndian.putShort( array, 9 + offset, (short)getLastColumnRaw() );
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
@ -128,32 +128,32 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
field_1_index_extern_sheet = index;
|
||||
}
|
||||
|
||||
public short getFirstRow()
|
||||
public int getFirstRow()
|
||||
{
|
||||
return field_2_first_row;
|
||||
}
|
||||
|
||||
public void setFirstRow( short row )
|
||||
public void setFirstRow( int row )
|
||||
{
|
||||
field_2_first_row = row;
|
||||
}
|
||||
|
||||
public short getLastRow()
|
||||
public int getLastRow()
|
||||
{
|
||||
return field_3_last_row;
|
||||
}
|
||||
|
||||
public void setLastRow( short row )
|
||||
public void setLastRow( int row )
|
||||
{
|
||||
field_3_last_row = row;
|
||||
}
|
||||
|
||||
public short getFirstColumn()
|
||||
public int getFirstColumn()
|
||||
{
|
||||
return (short) ( field_4_first_column & 0xFF );
|
||||
return field_4_first_column & 0xFF;
|
||||
}
|
||||
|
||||
public short getFirstColumnRaw()
|
||||
public int getFirstColumnRaw()
|
||||
{
|
||||
return field_4_first_column;
|
||||
}
|
||||
@ -179,12 +179,12 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
field_4_first_column = column;
|
||||
}
|
||||
|
||||
public short getLastColumn()
|
||||
public int getLastColumn()
|
||||
{
|
||||
return (short) ( field_5_last_column & 0xFF );
|
||||
return field_5_last_column & 0xFF;
|
||||
}
|
||||
|
||||
public short getLastColumnRaw()
|
||||
public int getLastColumnRaw()
|
||||
{
|
||||
return field_5_last_column;
|
||||
}
|
||||
@ -216,7 +216,7 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
*/
|
||||
public void setFirstRowRelative( boolean rel )
|
||||
{
|
||||
field_4_first_column = rowRelative.setShortBoolean( field_4_first_column, rel );
|
||||
field_4_first_column = rowRelative.setBoolean( field_4_first_column, rel );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,7 +224,7 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
*/
|
||||
public void setFirstColRelative( boolean rel )
|
||||
{
|
||||
field_4_first_column = colRelative.setShortBoolean( field_4_first_column, rel );
|
||||
field_4_first_column = colRelative.setBoolean( field_4_first_column, rel );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,7 +233,7 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
*/
|
||||
public void setLastRowRelative( boolean rel )
|
||||
{
|
||||
field_5_last_column = rowRelative.setShortBoolean( field_5_last_column, rel );
|
||||
field_5_last_column = rowRelative.setBoolean( field_5_last_column, rel );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +241,7 @@ public class Area3DPtg extends Ptg implements AreaI
|
||||
*/
|
||||
public void setLastColRelative( boolean rel )
|
||||
{
|
||||
field_5_last_column = colRelative.setShortBoolean( field_5_last_column, rel );
|
||||
field_5_last_column = colRelative.setBoolean( field_5_last_column, rel );
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,16 +36,14 @@ import org.apache.poi.hssf.model.Workbook;
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
|
||||
public class AreaAPtg
|
||||
extends AreaPtg
|
||||
{
|
||||
public final class AreaAPtg extends AreaPtg {
|
||||
public final static short sid = 0x65;
|
||||
|
||||
protected AreaAPtg() {
|
||||
//Required for clone methods
|
||||
}
|
||||
|
||||
public AreaAPtg(short firstRow, short lastRow, short firstColumn, short lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
|
||||
public AreaAPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
|
||||
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
|
||||
}
|
||||
|
||||
|
@ -24,22 +24,22 @@ public interface AreaI {
|
||||
/**
|
||||
* @return the first row in the area
|
||||
*/
|
||||
public short getFirstRow();
|
||||
public int getFirstRow();
|
||||
|
||||
/**
|
||||
* @return last row in the range (x2 in x1,y1-x2,y2)
|
||||
*/
|
||||
public short getLastRow();
|
||||
public int getLastRow();
|
||||
|
||||
/**
|
||||
* @return the first column number in the area.
|
||||
*/
|
||||
public short getFirstColumn();
|
||||
public int getFirstColumn();
|
||||
|
||||
/**
|
||||
* @return lastcolumn in the area
|
||||
*/
|
||||
public short getLastColumn();
|
||||
public int getLastColumn();
|
||||
|
||||
/**
|
||||
* @return isrelative first column to relative or not
|
||||
|
@ -38,10 +38,14 @@ public class AreaPtg
|
||||
{
|
||||
public final static short sid = 0x25;
|
||||
private final static int SIZE = 9;
|
||||
private short field_1_first_row;
|
||||
private short field_2_last_row;
|
||||
private short field_3_first_column;
|
||||
private short field_4_last_column;
|
||||
/** zero based, unsigned 16 bit */
|
||||
private int field_1_first_row;
|
||||
/** zero based, unsigned 16 bit */
|
||||
private int field_2_last_row;
|
||||
/** zero based, unsigned 8 bit */
|
||||
private int field_3_first_column;
|
||||
/** zero based, unsigned 8 bit */
|
||||
private int field_4_last_column;
|
||||
|
||||
private final static BitField rowRelative = BitFieldFactory.getInstance(0x8000);
|
||||
private final static BitField colRelative = BitFieldFactory.getInstance(0x4000);
|
||||
@ -55,9 +59,9 @@ public class AreaPtg
|
||||
AreaReference ar = new AreaReference(arearef);
|
||||
CellReference firstCell = ar.getFirstCell();
|
||||
CellReference lastCell = ar.getLastCell();
|
||||
setFirstRow((short)firstCell.getRow());
|
||||
setFirstRow(firstCell.getRow());
|
||||
setFirstColumn(firstCell.getCol());
|
||||
setLastRow((short)lastCell.getRow());
|
||||
setLastRow(lastCell.getRow());
|
||||
setLastColumn(lastCell.getCol());
|
||||
setFirstColRelative(!firstCell.isColAbsolute());
|
||||
setLastColRelative(!lastCell.isColAbsolute());
|
||||
@ -65,7 +69,13 @@ public class AreaPtg
|
||||
setLastRowRelative(!lastCell.isRowAbsolute());
|
||||
}
|
||||
|
||||
public AreaPtg(short firstRow, short lastRow, short firstColumn, short lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
|
||||
public AreaPtg(int firstRow, int lastRow, int firstColumn, int lastColumn,
|
||||
boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
|
||||
|
||||
checkColumnBounds(firstColumn);
|
||||
checkColumnBounds(lastColumn);
|
||||
checkRowBounds(firstRow);
|
||||
checkRowBounds(lastRow);
|
||||
setFirstRow(firstRow);
|
||||
setLastRow(lastRow);
|
||||
setFirstColumn(firstColumn);
|
||||
@ -76,12 +86,23 @@ public class AreaPtg
|
||||
setLastColRelative(lastColRelative);
|
||||
}
|
||||
|
||||
private static void checkColumnBounds(int colIx) {
|
||||
if((colIx & 0x0FF) != colIx) {
|
||||
throw new IllegalArgumentException("colIx (" + colIx + ") is out of range");
|
||||
}
|
||||
}
|
||||
private static void checkRowBounds(int rowIx) {
|
||||
if((rowIx & 0x0FFFF) != rowIx) {
|
||||
throw new IllegalArgumentException("rowIx (" + rowIx + ") is out of range");
|
||||
}
|
||||
}
|
||||
|
||||
public AreaPtg(RecordInputStream in)
|
||||
{
|
||||
field_1_first_row = in.readShort();
|
||||
field_2_last_row = in.readShort();
|
||||
field_3_first_column = in.readShort();
|
||||
field_4_last_column = in.readShort();
|
||||
field_1_first_row = in.readUShort();
|
||||
field_2_last_row = in.readUShort();
|
||||
field_3_first_column = in.readUShort();
|
||||
field_4_last_column = in.readUShort();
|
||||
//System.out.println(toString());
|
||||
}
|
||||
|
||||
@ -110,10 +131,10 @@ public class AreaPtg
|
||||
|
||||
public void writeBytes(byte [] array, int offset) {
|
||||
array[offset] = (byte) (sid + ptgClass);
|
||||
LittleEndian.putShort(array,offset+1,field_1_first_row);
|
||||
LittleEndian.putShort(array,offset+3,field_2_last_row);
|
||||
LittleEndian.putShort(array,offset+5,field_3_first_column);
|
||||
LittleEndian.putShort(array,offset+7,field_4_last_column);
|
||||
LittleEndian.putShort(array,offset+1,(short)field_1_first_row);
|
||||
LittleEndian.putShort(array,offset+3,(short)field_2_last_row);
|
||||
LittleEndian.putShort(array,offset+5,(short)field_3_first_column);
|
||||
LittleEndian.putShort(array,offset+7,(short)field_4_last_column);
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
@ -124,42 +145,42 @@ public class AreaPtg
|
||||
/**
|
||||
* @return the first row in the area
|
||||
*/
|
||||
public short getFirstRow()
|
||||
public int getFirstRow()
|
||||
{
|
||||
return field_1_first_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the first row
|
||||
* @param row number (0-based)
|
||||
* @param rowIx number (0-based)
|
||||
*/
|
||||
public void setFirstRow(short row)
|
||||
{
|
||||
field_1_first_row = row;
|
||||
public void setFirstRow(int rowIx) {
|
||||
checkRowBounds(rowIx);
|
||||
field_1_first_row = rowIx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return last row in the range (x2 in x1,y1-x2,y2)
|
||||
*/
|
||||
public short getLastRow()
|
||||
public int getLastRow()
|
||||
{
|
||||
return field_2_last_row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param row last row number in the area
|
||||
* @param rowIx last row number in the area
|
||||
*/
|
||||
public void setLastRow(short row)
|
||||
{
|
||||
field_2_last_row = row;
|
||||
public void setLastRow(int rowIx) {
|
||||
checkRowBounds(rowIx);
|
||||
field_2_last_row = rowIx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the first column number in the area.
|
||||
*/
|
||||
public short getFirstColumn()
|
||||
public int getFirstColumn()
|
||||
{
|
||||
return columnMask.getShortValue(field_3_first_column);
|
||||
return columnMask.getValue(field_3_first_column);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +188,7 @@ public class AreaPtg
|
||||
*/
|
||||
public short getFirstColumnRaw()
|
||||
{
|
||||
return field_3_first_column;
|
||||
return (short) field_3_first_column; // TODO
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,7 +204,7 @@ public class AreaPtg
|
||||
* @param rel is relative or not.
|
||||
*/
|
||||
public void setFirstRowRelative(boolean rel) {
|
||||
field_3_first_column=rowRelative.setShortBoolean(field_3_first_column,rel);
|
||||
field_3_first_column=rowRelative.setBoolean(field_3_first_column,rel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,21 +219,21 @@ public class AreaPtg
|
||||
* set whether the first column is relative
|
||||
*/
|
||||
public void setFirstColRelative(boolean rel) {
|
||||
field_3_first_column=colRelative.setShortBoolean(field_3_first_column,rel);
|
||||
field_3_first_column=colRelative.setBoolean(field_3_first_column,rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the first column in the area
|
||||
*/
|
||||
public void setFirstColumn(short column)
|
||||
{
|
||||
field_3_first_column=columnMask.setShortValue(field_3_first_column, column);
|
||||
public void setFirstColumn(int colIx) {
|
||||
checkColumnBounds(colIx);
|
||||
field_3_first_column=columnMask.setValue(field_3_first_column, colIx);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the first column irespective of the bitmasks
|
||||
*/
|
||||
public void setFirstColumnRaw(short column)
|
||||
public void setFirstColumnRaw(int column)
|
||||
{
|
||||
field_3_first_column = column;
|
||||
}
|
||||
@ -220,9 +241,9 @@ public class AreaPtg
|
||||
/**
|
||||
* @return lastcolumn in the area
|
||||
*/
|
||||
public short getLastColumn()
|
||||
public int getLastColumn()
|
||||
{
|
||||
return columnMask.getShortValue(field_4_last_column);
|
||||
return columnMask.getValue(field_4_last_column);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,7 +251,7 @@ public class AreaPtg
|
||||
*/
|
||||
public short getLastColumnRaw()
|
||||
{
|
||||
return field_4_last_column;
|
||||
return (short) field_4_last_column;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,7 +268,7 @@ public class AreaPtg
|
||||
* <code>false</code>
|
||||
*/
|
||||
public void setLastRowRelative(boolean rel) {
|
||||
field_4_last_column=rowRelative.setShortBoolean(field_4_last_column,rel);
|
||||
field_4_last_column=rowRelative.setBoolean(field_4_last_column,rel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -262,16 +283,16 @@ public class AreaPtg
|
||||
* set whether the last column should be relative or not
|
||||
*/
|
||||
public void setLastColRelative(boolean rel) {
|
||||
field_4_last_column=colRelative.setShortBoolean(field_4_last_column,rel);
|
||||
field_4_last_column=colRelative.setBoolean(field_4_last_column,rel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set the last column in the area
|
||||
*/
|
||||
public void setLastColumn(short column)
|
||||
{
|
||||
field_4_last_column=columnMask.setShortValue(field_4_last_column, column);
|
||||
public void setLastColumn(int colIx) {
|
||||
checkColumnBounds(colIx);
|
||||
field_4_last_column=columnMask.setValue(field_4_last_column, colIx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ import org.apache.poi.hssf.model.Workbook;
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
|
||||
public class AreaVPtg
|
||||
public final class AreaVPtg
|
||||
extends AreaPtg
|
||||
{
|
||||
public final static short sid = 0x45;
|
||||
@ -45,7 +45,7 @@ public class AreaVPtg
|
||||
//Required for clone methods
|
||||
}
|
||||
|
||||
public AreaVPtg(short firstRow, short lastRow, short firstColumn, short lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
|
||||
public AreaVPtg(int firstRow, int lastRow, int firstColumn, int lastColumn, boolean firstRowRelative, boolean lastRowRelative, boolean firstColRelative, boolean lastColRelative) {
|
||||
super(firstRow, lastRow, firstColumn, lastColumn, firstRowRelative, lastRowRelative, firstColRelative, lastColRelative);
|
||||
}
|
||||
|
||||
|
@ -18,16 +18,14 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
import org.apache.poi.hssf.util.RangeAddress;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.util.SheetReferences;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.util.RangeAddress;
|
||||
import org.apache.poi.hssf.util.SheetReferences;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Title: Reference 3D Ptg <P>
|
||||
@ -42,8 +40,14 @@ public class Ref3DPtg extends Ptg {
|
||||
public final static byte sid = 0x3a;
|
||||
private final static int SIZE = 7; // 6 + 1 for Ptg
|
||||
private short field_1_index_extern_sheet;
|
||||
private short field_2_row;
|
||||
private short field_3_column;
|
||||
/** The row index - zero based unsigned 16 bit value */
|
||||
private int field_2_row;
|
||||
/** Field 2
|
||||
* - lower 8 bits is the zero based unsigned byte column index
|
||||
* - bit 16 - isRowRelative
|
||||
* - bit 15 - isColumnRelative
|
||||
*/
|
||||
private int field_3_column;
|
||||
private BitField rowRelative = BitFieldFactory.getInstance(0x8000);
|
||||
private BitField colRelative = BitFieldFactory.getInstance(0x4000);
|
||||
|
||||
@ -58,8 +62,8 @@ public class Ref3DPtg extends Ptg {
|
||||
|
||||
public Ref3DPtg(String cellref, short externIdx ) {
|
||||
CellReference c= new CellReference(cellref);
|
||||
setRow((short) c.getRow());
|
||||
setColumn((short) c.getCol());
|
||||
setRow(c.getRow());
|
||||
setColumn(c.getCol());
|
||||
setColRelative(!c.isColAbsolute());
|
||||
setRowRelative(!c.isRowAbsolute());
|
||||
setExternSheetIndex(externIdx);
|
||||
@ -81,8 +85,8 @@ public class Ref3DPtg extends Ptg {
|
||||
public void writeBytes(byte [] array, int offset) {
|
||||
array[ 0 + offset ] = (byte) (sid + ptgClass);
|
||||
LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
|
||||
LittleEndian.putShort(array, 3 + offset , getRow());
|
||||
LittleEndian.putShort(array, 5 + offset , getColumnRaw());
|
||||
LittleEndian.putShort(array, 3 + offset , (short)getRow());
|
||||
LittleEndian.putShort(array, 5 + offset , (short)getColumnRaw());
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
@ -97,19 +101,19 @@ public class Ref3DPtg extends Ptg {
|
||||
field_1_index_extern_sheet = index;
|
||||
}
|
||||
|
||||
public short getRow() {
|
||||
public int getRow() {
|
||||
return field_2_row;
|
||||
}
|
||||
|
||||
public void setRow(short row) {
|
||||
public void setRow(int row) {
|
||||
field_2_row = row;
|
||||
}
|
||||
|
||||
public short getColumn() {
|
||||
return ( short ) (field_3_column & 0xFF);
|
||||
public int getColumn() {
|
||||
return field_3_column & 0xFF;
|
||||
}
|
||||
|
||||
public short getColumnRaw() {
|
||||
public int getColumnRaw() {
|
||||
return field_3_column;
|
||||
}
|
||||
|
||||
@ -119,7 +123,7 @@ public class Ref3DPtg extends Ptg {
|
||||
}
|
||||
|
||||
public void setRowRelative(boolean rel) {
|
||||
field_3_column=rowRelative.setShortBoolean(field_3_column,rel);
|
||||
field_3_column=rowRelative.setBoolean(field_3_column,rel);
|
||||
}
|
||||
|
||||
public boolean isColRelative()
|
||||
@ -128,7 +132,7 @@ public class Ref3DPtg extends Ptg {
|
||||
}
|
||||
|
||||
public void setColRelative(boolean rel) {
|
||||
field_3_column=colRelative.setShortBoolean(field_3_column,rel);
|
||||
field_3_column=colRelative.setBoolean(field_3_column,rel);
|
||||
}
|
||||
public void setColumn(short column) {
|
||||
field_3_column &= 0xFF00;
|
||||
@ -197,5 +201,4 @@ public class Ref3DPtg extends Ptg {
|
||||
ptg.setClass(ptgClass);
|
||||
return ptg;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -16,34 +15,23 @@
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
/*
|
||||
* ValueReferencePtg.java
|
||||
*
|
||||
* Created on November 21, 2001, 5:27 PM
|
||||
*/
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.BitField;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
|
||||
/**
|
||||
* RefNAPtg
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
|
||||
public class RefAPtg extends ReferencePtg
|
||||
{
|
||||
public final class RefAPtg extends ReferencePtg {
|
||||
public final static byte sid = 0x64;
|
||||
|
||||
protected RefAPtg() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RefAPtg(short row, short column, boolean isRowRelative, boolean isColumnRelative) {
|
||||
public RefAPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
|
||||
super(row, column, isRowRelative, isColumnRelative);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -18,27 +17,20 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.BitField;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
|
||||
/**
|
||||
* RefVPtg
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
|
||||
public class RefVPtg extends ReferencePtg
|
||||
{
|
||||
public final class RefVPtg extends ReferencePtg {
|
||||
public final static byte sid = 0x44;
|
||||
|
||||
protected RefVPtg() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RefVPtg(short row, short column, boolean isRowRelative, boolean isColumnRelative) {
|
||||
public RefVPtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
|
||||
super(row, column, isRowRelative, isColumnRelative);
|
||||
}
|
||||
|
||||
|
@ -31,26 +31,22 @@ import org.apache.poi.hssf.record.RecordInputStream;
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
|
||||
public class ReferencePtg extends Ptg
|
||||
{
|
||||
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!
|
||||
/** The row index - zero based unsigned 16 bit value */
|
||||
private int field_1_row;
|
||||
/** Field 2
|
||||
* - lower 8 bits is the zero based unsigned byte column index
|
||||
* - bit 16 - isRowRelative
|
||||
* - bit 15 - isColumnRelative
|
||||
*/
|
||||
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);
|
||||
private BitField column = BitFieldFactory.getInstance(0x3FFF);
|
||||
private int field_2_col;
|
||||
private static final BitField rowRelative = BitFieldFactory.getInstance(0x8000);
|
||||
private static final BitField colRelative = BitFieldFactory.getInstance(0x4000);
|
||||
private static final BitField column = BitFieldFactory.getInstance(0x00FF);
|
||||
|
||||
protected ReferencePtg() {
|
||||
//Required for clone methods
|
||||
@ -62,13 +58,13 @@ public class ReferencePtg extends Ptg
|
||||
*/
|
||||
public ReferencePtg(String cellref) {
|
||||
CellReference c= new CellReference(cellref);
|
||||
setRow((short) c.getRow());
|
||||
setColumn((short) c.getCol());
|
||||
setRow(c.getRow());
|
||||
setColumn(c.getCol());
|
||||
setColRelative(!c.isColAbsolute());
|
||||
setRowRelative(!c.isRowAbsolute());
|
||||
}
|
||||
|
||||
public ReferencePtg(short row, short column, boolean isRowRelative, boolean isColumnRelative) {
|
||||
public ReferencePtg(int row, int column, boolean isRowRelative, boolean isColumnRelative) {
|
||||
setRow(row);
|
||||
setColumn(column);
|
||||
setRowRelative(isRowRelative);
|
||||
@ -79,8 +75,8 @@ public class ReferencePtg extends Ptg
|
||||
|
||||
public ReferencePtg(RecordInputStream in)
|
||||
{
|
||||
field_1_row = in.readShort();
|
||||
field_2_col = in.readShort();
|
||||
field_1_row = in.readUShort();
|
||||
field_2_col = in.readUShort();
|
||||
}
|
||||
|
||||
public String getRefPtgName() {
|
||||
@ -104,33 +100,23 @@ public class ReferencePtg extends Ptg
|
||||
{
|
||||
array[offset] = (byte) (sid + ptgClass);
|
||||
|
||||
LittleEndian.putShort(array,offset+1,field_1_row);
|
||||
LittleEndian.putShort(array,offset+3,field_2_col);
|
||||
LittleEndian.putShort(array, offset+1, (short)field_1_row);
|
||||
LittleEndian.putShort(array, offset+3, (short)field_2_col);
|
||||
}
|
||||
|
||||
public void setRow(short 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;
|
||||
}
|
||||
field_1_row = row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row number as a short, which will be
|
||||
* wrapped (negative) for values between 32769 and 65535
|
||||
*/
|
||||
public short getRow()
|
||||
public int getRow()
|
||||
{
|
||||
return field_1_row;
|
||||
}
|
||||
@ -151,7 +137,7 @@ public class ReferencePtg extends Ptg
|
||||
}
|
||||
|
||||
public void setRowRelative(boolean rel) {
|
||||
field_2_col=rowRelative.setShortBoolean(field_2_col,rel);
|
||||
field_2_col=rowRelative.setBoolean(field_2_col,rel);
|
||||
}
|
||||
|
||||
public boolean isColRelative()
|
||||
@ -160,27 +146,29 @@ public class ReferencePtg extends Ptg
|
||||
}
|
||||
|
||||
public void setColRelative(boolean rel) {
|
||||
field_2_col=colRelative.setShortBoolean(field_2_col,rel);
|
||||
field_2_col=colRelative.setBoolean(field_2_col,rel);
|
||||
}
|
||||
|
||||
public void setColumnRaw(short col)
|
||||
public void setColumnRaw(int col)
|
||||
{
|
||||
field_2_col = col;
|
||||
}
|
||||
|
||||
public short getColumnRaw()
|
||||
public int getColumnRaw()
|
||||
{
|
||||
return field_2_col;
|
||||
}
|
||||
|
||||
public void setColumn(short col)
|
||||
public void setColumn(int col)
|
||||
{
|
||||
field_2_col = column.setShortValue(field_2_col, col);
|
||||
if(col < 0 || col > 0x100) {
|
||||
throw new IllegalArgumentException("Specified colIx (" + col + ") is out of range");
|
||||
}
|
||||
field_2_col = column.setValue(field_2_col, col);
|
||||
}
|
||||
|
||||
public short getColumn()
|
||||
{
|
||||
return column.getShortValue(field_2_col);
|
||||
public int getColumn() {
|
||||
return column.getValue(field_2_col);
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
|
@ -287,15 +287,28 @@ public final class HSSFRow implements Comparable {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the hssfcell representing a given column (logical cell) 0-based. If you
|
||||
* ask for a cell that is not defined....you get a null.
|
||||
* Get the hssfcell representing a given column (logical cell)
|
||||
* 0-based. If you ask for a cell that is not defined....
|
||||
* you get a null.
|
||||
* Short method signature provided to retain binary
|
||||
* compatibility.
|
||||
*
|
||||
* @param cellnum 0 based column number
|
||||
* @return HSSFCell representing that column or null if undefined.
|
||||
*/
|
||||
|
||||
public HSSFCell getCell(short cellnum)
|
||||
{
|
||||
return getCell((int)cellnum);
|
||||
}
|
||||
/**
|
||||
* Get the hssfcell representing a given column (logical cell)
|
||||
* 0-based. If you ask for a cell that is not defined....
|
||||
* you get a null.
|
||||
*
|
||||
* @param cellnum 0 based column number
|
||||
* @return HSSFCell representing that column or null if undefined.
|
||||
*/
|
||||
public HSSFCell getCell(int cellnum) {
|
||||
if(cellnum<0||cellnum>=cells.length) return null;
|
||||
return cells[cellnum];
|
||||
}
|
||||
|
@ -53,9 +53,10 @@ public final class AreaReference {
|
||||
parts[1].length() == 1 &&
|
||||
parts[0].charAt(0) >= 'A' && parts[0].charAt(0) <= 'Z' &&
|
||||
parts[1].charAt(0) >= 'A' && parts[1].charAt(0) <= 'Z') {
|
||||
// Represented internally as x$1 to x$0
|
||||
// Represented internally as x$1 to x$65536
|
||||
// which is the maximum range of rows
|
||||
parts[0] = parts[0] + "$1";
|
||||
parts[1] = parts[1] + "$0";
|
||||
parts[1] = parts[1] + "$65536";
|
||||
}
|
||||
|
||||
_firstCell = new CellReference(parts[0]);
|
||||
@ -98,10 +99,10 @@ public final class AreaReference {
|
||||
*/
|
||||
public static boolean isWholeColumnReference(CellReference topLeft, CellReference botRight) {
|
||||
// These are represented as something like
|
||||
// C$1:C$0 or D$1:F$0
|
||||
// C$1:C$65535 or D$1:F$0
|
||||
// i.e. absolute from 1st row to 0th one
|
||||
if(topLeft.getRow() == 0 && topLeft.isRowAbsolute() &&
|
||||
botRight.getRow() == -1 && botRight.isRowAbsolute()) {
|
||||
botRight.getRow() == 65535 && botRight.isRowAbsolute()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -71,6 +71,14 @@ public final class CellReference {
|
||||
this(null, pRow, pCol, pAbsRow, pAbsCol);
|
||||
}
|
||||
public CellReference(String pSheetName, int pRow, int pCol, boolean pAbsRow, boolean pAbsCol) {
|
||||
// TODO - "-1" is a special value being temporarily used for whole row and whole column area references.
|
||||
// so these checks are currently N.Q.R.
|
||||
if(pRow < -1) {
|
||||
throw new IllegalArgumentException("row index may not be negative");
|
||||
}
|
||||
if(pCol < -1) {
|
||||
throw new IllegalArgumentException("column index may not be negative");
|
||||
}
|
||||
_sheetName = pSheetName;
|
||||
_rowIndex=pRow;
|
||||
_colIndex=pCol;
|
||||
|
@ -14,10 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 8, 2005
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.poi.hssf.record.formula.eval;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||
@ -27,48 +24,60 @@ import org.apache.poi.hssf.record.formula.Ptg;
|
||||
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
||||
*
|
||||
*/
|
||||
public class Area2DEval implements AreaEval {
|
||||
public final class Area2DEval implements AreaEval {
|
||||
// TODO -refactor with Area3DEval
|
||||
private final AreaPtg _delegate;
|
||||
|
||||
private AreaPtg delegate;
|
||||
|
||||
private ValueEval[] values;
|
||||
private final ValueEval[] _values;
|
||||
|
||||
public Area2DEval(Ptg ptg, ValueEval[] values) {
|
||||
this.delegate = (AreaPtg) ptg;
|
||||
this.values = values;
|
||||
if(ptg == null) {
|
||||
throw new IllegalArgumentException("ptg must not be null");
|
||||
}
|
||||
if(values == null) {
|
||||
throw new IllegalArgumentException("values must not be null");
|
||||
}
|
||||
for(int i=values.length-1; i>=0; i--) {
|
||||
if(values[i] == null) {
|
||||
throw new IllegalArgumentException("value array elements must not be null");
|
||||
}
|
||||
}
|
||||
// TODO - check size of array vs size of AreaPtg
|
||||
_delegate = (AreaPtg) ptg;
|
||||
_values = values;
|
||||
}
|
||||
|
||||
public short getFirstColumn() {
|
||||
return delegate.getFirstColumn();
|
||||
public int getFirstColumn() {
|
||||
return _delegate.getFirstColumn();
|
||||
}
|
||||
|
||||
public int getFirstRow() {
|
||||
return delegate.getFirstRow();
|
||||
return _delegate.getFirstRow();
|
||||
}
|
||||
|
||||
public short getLastColumn() {
|
||||
return delegate.getLastColumn();
|
||||
public int getLastColumn() {
|
||||
return _delegate.getLastColumn();
|
||||
}
|
||||
|
||||
public int getLastRow() {
|
||||
return delegate.getLastRow();
|
||||
return _delegate.getLastRow();
|
||||
}
|
||||
|
||||
public ValueEval[] getValues() {
|
||||
return values;
|
||||
return _values;
|
||||
}
|
||||
|
||||
public ValueEval getValueAt(int row, short col) {
|
||||
public ValueEval getValueAt(int row, int col) {
|
||||
ValueEval retval;
|
||||
int index = ((row-getFirstRow())*(getLastColumn()-getFirstColumn()+1))+(col-getFirstColumn());
|
||||
if (index <0 || index >= values.length)
|
||||
if (index <0 || index >= _values.length)
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
else
|
||||
retval = values[index];
|
||||
retval = _values[index];
|
||||
return retval;
|
||||
}
|
||||
|
||||
public boolean contains(int row, short col) {
|
||||
public boolean contains(int row, int col) {
|
||||
return (getFirstRow() <= row) && (getLastRow() >= row)
|
||||
&& (getFirstColumn() <= col) && (getLastColumn() >= col);
|
||||
}
|
||||
@ -82,10 +91,10 @@ public class Area2DEval implements AreaEval {
|
||||
}
|
||||
|
||||
public boolean isColumn() {
|
||||
return delegate.getFirstColumn() == delegate.getLastColumn();
|
||||
return _delegate.getFirstColumn() == _delegate.getLastColumn();
|
||||
}
|
||||
|
||||
public boolean isRow() {
|
||||
return delegate.getFirstRow() == delegate.getLastRow();
|
||||
return _delegate.getFirstRow() == _delegate.getLastRow();
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 8, 2005
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.poi.hssf.record.formula.eval;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.Area3DPtg;
|
||||
@ -28,47 +25,59 @@ import org.apache.poi.hssf.record.formula.Ptg;
|
||||
*
|
||||
*/
|
||||
public final class Area3DEval implements AreaEval {
|
||||
// TODO -refactor with Area3DEval
|
||||
private final Area3DPtg _delegate;
|
||||
|
||||
private Area3DPtg delegate;
|
||||
|
||||
private ValueEval[] values;
|
||||
private final ValueEval[] _values;
|
||||
|
||||
public Area3DEval(Ptg ptg, ValueEval[] values) {
|
||||
this.values = values;
|
||||
this.delegate = (Area3DPtg) ptg;
|
||||
if(ptg == null) {
|
||||
throw new IllegalArgumentException("ptg must not be null");
|
||||
}
|
||||
if(values == null) {
|
||||
throw new IllegalArgumentException("values must not be null");
|
||||
}
|
||||
for(int i=values.length-1; i>=0; i--) {
|
||||
if(values[i] == null) {
|
||||
throw new IllegalArgumentException("value array elements must not be null");
|
||||
}
|
||||
}
|
||||
// TODO - check size of array vs size of AreaPtg
|
||||
_values = values;
|
||||
_delegate = (Area3DPtg) ptg;
|
||||
}
|
||||
|
||||
public short getFirstColumn() {
|
||||
return delegate.getFirstColumn();
|
||||
public int getFirstColumn() {
|
||||
return _delegate.getFirstColumn();
|
||||
}
|
||||
|
||||
public int getFirstRow() {
|
||||
return delegate.getFirstRow();
|
||||
return _delegate.getFirstRow();
|
||||
}
|
||||
|
||||
public short getLastColumn() {
|
||||
return delegate.getLastColumn();
|
||||
public int getLastColumn() {
|
||||
return (short) _delegate.getLastColumn();
|
||||
}
|
||||
|
||||
public int getLastRow() {
|
||||
return delegate.getLastRow();
|
||||
return _delegate.getLastRow();
|
||||
}
|
||||
|
||||
public ValueEval[] getValues() {
|
||||
return values;
|
||||
return _values;
|
||||
}
|
||||
|
||||
public ValueEval getValueAt(int row, short col) {
|
||||
public ValueEval getValueAt(int row, int col) {
|
||||
ValueEval retval;
|
||||
int index = (row-getFirstRow())*(col-getFirstColumn());
|
||||
if (index <0 || index >= values.length)
|
||||
if (index <0 || index >= _values.length)
|
||||
retval = ErrorEval.VALUE_INVALID;
|
||||
else
|
||||
retval = values[index];
|
||||
retval = _values[index];
|
||||
return retval;
|
||||
}
|
||||
|
||||
public boolean contains(int row, short col) {
|
||||
public boolean contains(int row, int col) {
|
||||
return (getFirstRow() <= row) && (getLastRow() >= row)
|
||||
&& (getFirstColumn() <= col) && (getLastColumn() >= col);
|
||||
}
|
||||
@ -83,15 +92,14 @@ public final class Area3DEval implements AreaEval {
|
||||
|
||||
|
||||
public boolean isColumn() {
|
||||
return delegate.getFirstColumn() == delegate.getLastColumn();
|
||||
return _delegate.getFirstColumn() == _delegate.getLastColumn();
|
||||
}
|
||||
|
||||
public boolean isRow() {
|
||||
return delegate.getFirstRow() == delegate.getLastRow();
|
||||
return _delegate.getFirstRow() == _delegate.getLastRow();
|
||||
}
|
||||
|
||||
public int getExternSheetIndex() {
|
||||
return delegate.getExternSheetIndex();
|
||||
return _delegate.getExternSheetIndex();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,13 +42,13 @@ public interface AreaEval extends ValueEval {
|
||||
* returns the 0-based index of the first col in
|
||||
* this area.
|
||||
*/
|
||||
public short getFirstColumn();
|
||||
public int getFirstColumn();
|
||||
|
||||
/**
|
||||
* returns the 0-based index of the last col in
|
||||
* this area.
|
||||
*/
|
||||
public short getLastColumn();
|
||||
public int getLastColumn();
|
||||
|
||||
/**
|
||||
* returns true if the Area's start and end row indexes
|
||||
@ -80,7 +80,7 @@ public interface AreaEval extends ValueEval {
|
||||
* @param row
|
||||
* @param col
|
||||
*/
|
||||
public ValueEval getValueAt(int row, short col);
|
||||
public ValueEval getValueAt(int row, int col);
|
||||
|
||||
/**
|
||||
* returns true if the cell at row and col specified
|
||||
@ -89,7 +89,7 @@ public interface AreaEval extends ValueEval {
|
||||
* @param row
|
||||
* @param col
|
||||
*/
|
||||
public boolean contains(int row, short col);
|
||||
public boolean contains(int row, int col);
|
||||
|
||||
/**
|
||||
* returns true if the specified col is in range
|
||||
|
@ -29,16 +29,22 @@ public final class Ref2DEval implements RefEval {
|
||||
private final ReferencePtg delegate;
|
||||
|
||||
public Ref2DEval(ReferencePtg ptg, ValueEval ve) {
|
||||
if(ve == null) {
|
||||
throw new IllegalArgumentException("ve must not be null");
|
||||
}
|
||||
if(false && ptg == null) { // TODO - fix dodgy code in MultiOperandNumericFunction
|
||||
throw new IllegalArgumentException("ptg must not be null");
|
||||
}
|
||||
value = ve;
|
||||
delegate = ptg;
|
||||
}
|
||||
public ValueEval getInnerValueEval() {
|
||||
return value;
|
||||
}
|
||||
public short getRow() {
|
||||
public int getRow() {
|
||||
return delegate.getRow();
|
||||
}
|
||||
public short getColumn() {
|
||||
public int getColumn() {
|
||||
return delegate.getColumn();
|
||||
}
|
||||
}
|
||||
|
@ -29,16 +29,22 @@ public final class Ref3DEval implements RefEval {
|
||||
private final Ref3DPtg delegate;
|
||||
|
||||
public Ref3DEval(Ref3DPtg ptg, ValueEval ve) {
|
||||
if(ve == null) {
|
||||
throw new IllegalArgumentException("ve must not be null");
|
||||
}
|
||||
if(ptg == null) {
|
||||
throw new IllegalArgumentException("ptg must not be null");
|
||||
}
|
||||
value = ve;
|
||||
delegate = ptg;
|
||||
}
|
||||
public ValueEval getInnerValueEval() {
|
||||
return value;
|
||||
}
|
||||
public short getRow() {
|
||||
public int getRow() {
|
||||
return delegate.getRow();
|
||||
}
|
||||
public short getColumn() {
|
||||
public int getColumn() {
|
||||
return delegate.getColumn();
|
||||
}
|
||||
public int getExternSheetIndex() {
|
||||
|
@ -40,12 +40,12 @@ public interface RefEval extends ValueEval {
|
||||
public ValueEval getInnerValueEval();
|
||||
|
||||
/**
|
||||
* returns the column index.
|
||||
* returns the zero based column index.
|
||||
*/
|
||||
public short getColumn();
|
||||
public int getColumn();
|
||||
|
||||
/**
|
||||
* returns the row index.
|
||||
* returns the zero based row index.
|
||||
*/
|
||||
public short getRow();
|
||||
public int getRow();
|
||||
}
|
||||
|
@ -287,8 +287,8 @@ final class LookupUtils {
|
||||
// It doesn't matter if eval is a 2D or 3D ref, because that detail is never asked of AreaEval.
|
||||
// This code only requires the value array item.
|
||||
// anything would be ok for rowIx and colIx, but may as well get it right.
|
||||
short rowIx = refEval.getRow();
|
||||
short colIx = refEval.getColumn();
|
||||
int rowIx = refEval.getRow();
|
||||
int colIx = refEval.getColumn();
|
||||
AreaPtg ap = new AreaPtg(rowIx, rowIx, colIx, colIx, false, false, false, false);
|
||||
ValueEval value = refEval.getInnerValueEval();
|
||||
return new Area2DEval(ap, new ValueEval[] { value, });
|
||||
|
@ -14,10 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Created on May 5, 2005
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
@ -420,20 +417,20 @@ public class HSSFFormulaEvaluator {
|
||||
}
|
||||
else if (ptg instanceof ReferencePtg) {
|
||||
ReferencePtg refPtg = (ReferencePtg) ptg;
|
||||
short colnum = refPtg.getColumn();
|
||||
short rownum = refPtg.getRow();
|
||||
HSSFRow row = sheet.getRow(rownum);
|
||||
HSSFCell cell = (row != null) ? row.getCell(colnum) : null;
|
||||
int colIx = refPtg.getColumn();
|
||||
int rowIx = refPtg.getRow();
|
||||
HSSFRow row = sheet.getRow(rowIx);
|
||||
HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
|
||||
stack.push(createRef2DEval(refPtg, cell, row, sheet, workbook));
|
||||
}
|
||||
else if (ptg instanceof Ref3DPtg) {
|
||||
Ref3DPtg refPtg = (Ref3DPtg) ptg;
|
||||
short colnum = refPtg.getColumn();
|
||||
short rownum = refPtg.getRow();
|
||||
int colIx = refPtg.getColumn();
|
||||
int rowIx = refPtg.getRow();
|
||||
Workbook wb = workbook.getWorkbook();
|
||||
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(refPtg.getExternSheetIndex()));
|
||||
HSSFRow row = xsheet.getRow(rownum);
|
||||
HSSFCell cell = (row != null) ? row.getCell(colnum) : null;
|
||||
HSSFRow row = xsheet.getRow(rowIx);
|
||||
HSSFCell cell = (row != null) ? row.getCell(colIx) : null;
|
||||
stack.push(createRef3DEval(refPtg, cell, row, xsheet, workbook));
|
||||
}
|
||||
else if (ptg instanceof AreaPtg) {
|
||||
@ -506,10 +503,10 @@ public class HSSFFormulaEvaluator {
|
||||
}
|
||||
|
||||
public static AreaEval evaluateAreaPtg(HSSFSheet sheet, HSSFWorkbook workbook, AreaPtg ap) {
|
||||
short row0 = ap.getFirstRow();
|
||||
short col0 = ap.getFirstColumn();
|
||||
short row1 = ap.getLastRow();
|
||||
short col1 = ap.getLastColumn();
|
||||
int row0 = ap.getFirstRow();
|
||||
int col0 = ap.getFirstColumn();
|
||||
int row1 = ap.getLastRow();
|
||||
int col1 = ap.getLastColumn();
|
||||
|
||||
// If the last row is -1, then the
|
||||
// reference is for the rest of the column
|
||||
@ -518,24 +515,15 @@ public class HSSFFormulaEvaluator {
|
||||
if(row1 == -1 && row0 >= 0) {
|
||||
row1 = (short)sheet.getLastRowNum();
|
||||
}
|
||||
|
||||
ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
|
||||
for (short x = row0; sheet != null && x < row1 + 1; x++) {
|
||||
HSSFRow row = sheet.getRow(x);
|
||||
for (short y = col0; row != null && y < col1 + 1; y++) {
|
||||
values[(x - row0) * (col1 - col0 + 1) + (y - col0)] =
|
||||
getEvalForCell(row.getCell(y), row, sheet, workbook);
|
||||
}
|
||||
}
|
||||
AreaEval ae = new Area2DEval(ap, values);
|
||||
return ae;
|
||||
ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1);
|
||||
return new Area2DEval(ap, values);
|
||||
}
|
||||
|
||||
public static AreaEval evaluateArea3dPtg(HSSFWorkbook workbook, Area3DPtg a3dp) {
|
||||
short row0 = a3dp.getFirstRow();
|
||||
short col0 = a3dp.getFirstColumn();
|
||||
short row1 = a3dp.getLastRow();
|
||||
short col1 = a3dp.getLastColumn();
|
||||
int row0 = a3dp.getFirstRow();
|
||||
int col0 = a3dp.getFirstColumn();
|
||||
int row1 = a3dp.getLastRow();
|
||||
int col1 = a3dp.getLastColumn();
|
||||
Workbook wb = workbook.getWorkbook();
|
||||
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
|
||||
|
||||
@ -547,18 +535,27 @@ public class HSSFFormulaEvaluator {
|
||||
row1 = (short)xsheet.getLastRowNum();
|
||||
}
|
||||
|
||||
ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
|
||||
for (short x = row0; xsheet != null && x < row1 + 1; x++) {
|
||||
HSSFRow row = xsheet.getRow(x);
|
||||
for (short y = col0; row != null && y < col1 + 1; y++) {
|
||||
values[(x - row0) * (col1 - col0 + 1) + (y - col0)] =
|
||||
getEvalForCell(row.getCell(y), row, xsheet, workbook);
|
||||
}
|
||||
}
|
||||
AreaEval ae = new Area3DEval(a3dp, values);
|
||||
return ae;
|
||||
ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1);
|
||||
return new Area3DEval(a3dp, values);
|
||||
}
|
||||
|
||||
private static ValueEval[] evalArea(HSSFWorkbook workbook, HSSFSheet sheet,
|
||||
int row0, int col0, int row1, int col1) {
|
||||
ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)];
|
||||
for (int x = row0; sheet != null && x < row1 + 1; x++) {
|
||||
HSSFRow row = sheet.getRow(x);
|
||||
for (int y = col0; y < col1 + 1; y++) {
|
||||
ValueEval cellEval;
|
||||
if(row == null) {
|
||||
cellEval = BlankEval.INSTANCE;
|
||||
} else {
|
||||
cellEval = getEvalForCell(row.getCell(y), row, sheet, workbook);
|
||||
}
|
||||
values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = cellEval;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the OperationEval concrete impl instance corresponding
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -20,24 +19,24 @@ package org.apache.poi.hssf.model;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.model.FormulaParser.FormulaParseException;
|
||||
import org.apache.poi.hssf.record.formula.FuncVarPtg;
|
||||
import org.apache.poi.hssf.record.formula.NamePtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator.CellValue;
|
||||
|
||||
/**
|
||||
* Test the low level formula parser functionality,
|
||||
* but using parts which need to use the
|
||||
* HSSFFormulaEvaluator, which is in scratchpad
|
||||
*/
|
||||
public class TestFormulaParserSP extends TestCase {
|
||||
|
||||
public TestFormulaParserSP(String name) {
|
||||
super(name);
|
||||
}
|
||||
public final class TestFormulaParserSP extends TestCase {
|
||||
|
||||
public void testWithNamedRange() throws Exception {
|
||||
HSSFWorkbook workbook = new HSSFWorkbook();
|
||||
@ -80,4 +79,32 @@ public class TestFormulaParserSP extends TestCase {
|
||||
assertEquals(FuncVarPtg.class, ptgs[1].getClass());
|
||||
}
|
||||
|
||||
public void testEvaluateFormulaWithRowBeyond32768_Bug44539() {
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell((short)0);
|
||||
cell.setCellFormula("SUM(A32769:A32770)");
|
||||
|
||||
// put some values in the cells to make the evaluation more interesting
|
||||
sheet.createRow(32768).createCell((short)0).setCellValue(31);
|
||||
sheet.createRow(32769).createCell((short)0).setCellValue(11);
|
||||
|
||||
HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
|
||||
fe.setCurrentRow(row);
|
||||
CellValue result;
|
||||
try {
|
||||
result = fe.evaluate(cell);
|
||||
} catch (FormulaParseException e) {
|
||||
if(e.getMessage().equals("Found reference to named range \"A\", but that named range wasn't defined!")) {
|
||||
fail("Identifed bug 44539");
|
||||
}
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, result.getCellType());
|
||||
assertEquals(42.0, result.getNumberValue(), 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -63,12 +63,13 @@ public class TestBug44410 extends TestCase {
|
||||
assertEquals(AreaPtg.class, ops.get(0).getClass());
|
||||
assertEquals(FuncVarPtg.class, ops.get(1).getClass());
|
||||
|
||||
// Actually stored as C1 to C0 (last row is -1)
|
||||
// Actually stored as C1 to C65536
|
||||
// (last row is -1 === 65535)
|
||||
AreaPtg ptg = (AreaPtg)ops.get(0);
|
||||
assertEquals(2, ptg.getFirstColumn());
|
||||
assertEquals(2, ptg.getLastColumn());
|
||||
assertEquals(0, ptg.getFirstRow());
|
||||
assertEquals(-1, ptg.getLastRow());
|
||||
assertEquals(65535, ptg.getLastRow());
|
||||
assertEquals("C:C", ptg.toFormulaString(wb.getWorkbook()));
|
||||
|
||||
// Will show as C:C, but won't know how many
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
@ -21,6 +20,7 @@ package org.apache.poi.hssf.model;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.model.FormulaParser.FormulaParseException;
|
||||
import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
|
||||
import org.apache.poi.hssf.record.formula.AddPtg;
|
||||
import org.apache.poi.hssf.record.formula.AreaPtg;
|
||||
@ -59,18 +59,8 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
* Some tests are also done in scratchpad, if they need
|
||||
* HSSFFormulaEvaluator, which is there
|
||||
*/
|
||||
public class TestFormulaParser extends TestCase {
|
||||
public final class TestFormulaParser extends TestCase {
|
||||
|
||||
public TestFormulaParser(String name) {
|
||||
super(name);
|
||||
}
|
||||
public void setUp(){
|
||||
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
|
||||
}
|
||||
/**
|
||||
* @return parsed token array already confirmed not <code>null</code>
|
||||
*/
|
||||
@ -831,10 +821,27 @@ public class TestFormulaParser extends TestCase {
|
||||
try {
|
||||
parseFormula(formula);
|
||||
throw new AssertionFailedError("expected parse exception");
|
||||
} catch (RuntimeException e) {
|
||||
// TODO - catch more specific exception
|
||||
} catch (FormulaParseException e) {
|
||||
// expected during successful test
|
||||
return;
|
||||
assertNotNull(e.getMessage());
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
fail("Wrong exception:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetFormulaWithRowBeyond32768_Bug44539() {
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet();
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
|
||||
HSSFRow row = sheet.createRow(0);
|
||||
HSSFCell cell = row.createCell((short)0);
|
||||
cell.setCellFormula("SUM(A32769:A32770)");
|
||||
if("SUM(A-32767:A-32766)".equals(cell.getCellFormula())) {
|
||||
fail("Identified bug 44539");
|
||||
}
|
||||
assertEquals("SUM(A32769:A32770)", cell.getCellFormula());
|
||||
}
|
||||
}
|
||||
|
@ -27,15 +27,12 @@ import org.apache.poi.hssf.model.FormulaParser;
|
||||
*
|
||||
* @author Dmitriy Kumshayev
|
||||
*/
|
||||
public class TestAreaPtg extends TestCase
|
||||
{
|
||||
public final class TestAreaPtg extends TestCase {
|
||||
|
||||
AreaPtg relative;
|
||||
AreaPtg absolute;
|
||||
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
super.setUp();
|
||||
protected void setUp() {
|
||||
short firstRow=5;
|
||||
short lastRow=13;
|
||||
short firstCol=7;
|
||||
@ -64,10 +61,9 @@ public class TestAreaPtg extends TestCase
|
||||
}
|
||||
|
||||
|
||||
public void resetColumns(AreaPtg aptg)
|
||||
{
|
||||
short fc = aptg.getFirstColumn();
|
||||
short lc = aptg.getLastColumn();
|
||||
private static void resetColumns(AreaPtg aptg) {
|
||||
int fc = aptg.getFirstColumn();
|
||||
int lc = aptg.getLastColumn();
|
||||
aptg.setFirstColumn(fc);
|
||||
aptg.setLastColumn(lc);
|
||||
assertEquals(fc , aptg.getFirstColumn() );
|
||||
|
Loading…
Reference in New Issue
Block a user