Browse Source

Framework to set the class of a token


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352651 13f79535-47bb-0310-9956-ffa450edef68
tags/REL_1_10
Avik Sengupta 22 years ago
parent
commit
b35ab14e42

+ 2
- 0
src/java/org/apache/poi/hssf/record/formula/AddPtg.java View File

@@ -124,5 +124,7 @@ public class AddPtg
buffer.append(operands[ 1 ]);
return buffer.toString();
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 21
- 18
src/java/org/apache/poi/hssf/record/formula/Area3DPtg.java View File

@@ -70,7 +70,7 @@ public class Area3DPtg extends Ptg
{
public final static short sid = 0x3b;
private final static int SIZE = 11; // 10 + 1 for Ptg
private short field_1_index_extern_sheet;
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;
@@ -116,20 +116,20 @@ public class Area3DPtg extends Ptg
array[ 0 + offset ] = sid;
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, 5 + offset , getLastRow());
LittleEndian.putShort(array, 7 + offset , getFirstColumnRaw());
LittleEndian.putShort(array, 9 + offset , getLastColumnRaw());
}

public int getSize()
{
return SIZE;
}
public short getExternSheetIndex(){
return field_1_index_extern_sheet;
}
public void setExternSheetIndex(short index){
field_1_index_extern_sheet = index;
}
@@ -177,17 +177,17 @@ public class Area3DPtg extends Ptg
public void setFirstColumn(short column)
{
field_4_first_column &= 0xFF00;
field_4_first_column |= column & 0xFF;
field_4_first_column |= column & 0xFF;
}

public void setFirstColumnRaw(short column)
{
field_4_first_column = column;
field_4_first_column = column;
}

public short getLastColumn()
{
return ( short ) (field_5_last_column & 0xFF);
return ( short ) (field_5_last_column & 0xFF);
}

public short getLastColumnRaw()
@@ -208,32 +208,32 @@ public class Area3DPtg extends Ptg
public void setLastColumn(short column)
{
field_5_last_column &= 0xFF00;
field_5_last_column |= column & 0xFF;
field_5_last_column |= column & 0xFF;
}

public void setLastColumnRaw(short column)
{
field_5_last_column = column;
}
public String getArea(){
RangeAddress ra = new RangeAddress( getFirstColumn(),getFirstRow() + 1, getLastColumn(), getLastRow() + 1);
RangeAddress ra = new RangeAddress( getFirstColumn(),getFirstRow() + 1, getLastColumn(), getLastRow() + 1);
String result = ra.getAddress();
return result;
}
public void setArea(String ref){
RangeAddress ra = new RangeAddress(ref);
String from = ra.getFromCell();
String to = ra.getToCell();
setFirstColumn((short) (ra.getXPosition(from) -1));
setFirstRow((short) (ra.getYPosition(from) -1));
setLastColumn((short) (ra.getXPosition(to) -1));
setLastRow((short) (ra.getYPosition(to) -1));
}

public String toFormulaString()
@@ -243,5 +243,8 @@ public class Area3DPtg extends Ptg
return result;
}

public byte getDefaultOperandClass() {
return Ptg.CLASS_VALUE;
}

}

+ 5
- 1
src/java/org/apache/poi/hssf/record/formula/AreaPtg.java View File

@@ -131,7 +131,7 @@ public class AreaPtg
}

public void writeBytes(byte [] array, int offset) {
array[offset] = sid;
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);
@@ -309,4 +309,8 @@ public class AreaPtg
(new CellReference(getLastRow(),getLastColumn(),!isLastRowRelative(),!isLastColRelative())).toString();
}

public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
}
}

+ 1
- 1
src/java/org/apache/poi/hssf/record/formula/AttrPtg.java View File

@@ -211,5 +211,5 @@ public class AttrPtg
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 3
- 0
src/java/org/apache/poi/hssf/record/formula/ExpPtg.java View File

@@ -96,4 +96,7 @@ public class ExpPtg
{
return "NO IDEA SHARED FORMULA EXP PTG";
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 141
- 14
src/java/org/apache/poi/hssf/record/formula/FormulaParser.java View File

@@ -79,6 +79,12 @@ import java.io.File;
*/
public class FormulaParser {
public static int FORMULA_TYPE_CELL = 0;
public static int FORMULA_TYPE_SHARED = 1;
public static int FORMULA_TYPE_ARRAY =2;
public static int FORMULA_TYPE_CONDFOMRAT = 3;
public static int FORMULA_TYPE_NAMEDRANGE = 4;
private String formulaString;
private int pointer=0;
@@ -193,18 +199,16 @@ public class FormulaParser {
/** Get an Identifier */
private String GetName() {
String Token;
Token = "";
StringBuffer Token = new StringBuffer();
if (!IsAlpha(Look)) {
Expected("Name");
}
while (IsAlNum(Look)) {
Token = Token + Character.toUpperCase(Look);
Token = Token.append(Character.toUpperCase(Look));
GetChar();
}
SkipWhite();
return Token;
return Token.toString();
}
@@ -304,7 +308,10 @@ public class FormulaParser {
return;
} else if (IsAlpha(Look)){
Ident();
}else{
} else if(Look == '"') {
StringLiteral();
} else {
String number = GetNum();
if (Look=='.') {
Match('.');
@@ -316,7 +323,13 @@ public class FormulaParser {
}
}
}

private void StringLiteral() {
Match('"');
String name= GetName();
Match('"');
tokens.add(new StringPtg(name));
}
/** Recognize and Translate a Multiply */
private void Multiply(){
@@ -429,13 +442,89 @@ end;
* a result of the parsing
*/
public Ptg[] getRPNPtg() {
synchronized (tokens) {
if (tokens == null) throw new IllegalStateException("Please parse a string before trying to access the parse result");
Ptg[] retval = new Ptg[tokens.size()];
return (Ptg[]) tokens.toArray(retval);
}
return getRPNPtg(FORMULA_TYPE_CELL);
}
public Ptg[] getRPNPtg(int formulaType) {
Node node = createTree();
setRootLevelRVA(node, formulaType);
setParameterRVA(node,formulaType);
return (Ptg[]) tokens.toArray(new Ptg[0]);
}
private void setRootLevelRVA(Node n, int formulaType) {
//Pg 16, excelfileformat.pdf @ openoffice.org
Ptg p = (Ptg) n.getValue();
if (formulaType == this.FORMULA_TYPE_NAMEDRANGE) {
if (p.getDefaultOperandClass() == Ptg.CLASS_REF) {
setClass(n,Ptg.CLASS_REF);
} else {
setClass(n,Ptg.CLASS_ARRAY);
}
} else {
setClass(n,Ptg.CLASS_VALUE);
}
}
private void setParameterRVA(Node n, int formulaType) {
Ptg p = (Ptg) n.getValue();
if (p instanceof FunctionPtg) {
int numOperands = n.getNumChildren();
for (int i =0;i<n.getNumChildren();i++) {
setParameterRVA(n.getChild(i),((FunctionPtg)p).getParameterClass(i),formulaType);
if (n.getChild(i).getValue() instanceof FunctionPtg) {
setParameterRVA(n.getChild(i),formulaType);
}
}
} else {
for (int i =0;i<n.getNumChildren();i++) {
setParameterRVA(n.getChild(i),formulaType);
}
}
}
private void setParameterRVA(Node n, int expectedClass,int formulaType) {
Ptg p = (Ptg) n.getValue();
if (expectedClass == Ptg.CLASS_REF) { //pg 15, table 1
if (p.getDefaultOperandClass() == Ptg.CLASS_REF ) {
setClass(n, Ptg.CLASS_REF);
}
if (p.getDefaultOperandClass() == Ptg.CLASS_VALUE) {
if (formulaType==FORMULA_TYPE_CELL || formulaType == FORMULA_TYPE_SHARED) {
setClass(n,Ptg.CLASS_VALUE);
} else {
setClass(n,Ptg.CLASS_ARRAY);
}
}
if (p.getDefaultOperandClass() == Ptg.CLASS_ARRAY ) {
setClass(n, Ptg.CLASS_ARRAY);
}
} else if (expectedClass == Ptg.CLASS_VALUE) { //pg 15, table 2
if (formulaType == FORMULA_TYPE_NAMEDRANGE) {
setClass(n,Ptg.CLASS_ARRAY) ;
} else {
setClass(n,Ptg.CLASS_VALUE);
}
} else { //Array class, pg 16.
if (p.getDefaultOperandClass() == Ptg.CLASS_VALUE &&
(formulaType==FORMULA_TYPE_CELL || formulaType == FORMULA_TYPE_SHARED)) {
setClass(n,Ptg.CLASS_VALUE);
} else {
setClass(n,Ptg.CLASS_ARRAY);
}
}
}
private void setClass(Node n, byte theClass) {
Ptg p = (Ptg) n.getValue();
if (p instanceof FunctionPtg || !(p instanceof OperationPtg)) {
p.setClass(theClass);
} else {
for (int i =0;i<n.getNumChildren();i++) {
setClass(n.getChild(i),theClass);
}
}
}
/**
* Convience method which takes in a list then passes it to the other toFormulaString
* signature
@@ -459,6 +548,7 @@ end;
String[] operands;
for (int i=0;i<numPtgs;i++) {
if (ptgs[i] instanceof OperationPtg) {

// Excel allows to have AttrPtg at position 0 (such as Blanks) which
// do not have any operands. Skip them.
if(i > 0) {
@@ -478,6 +568,31 @@ end;
}
return (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
}
private Node createTree() {
java.util.Stack stack = new java.util.Stack();
int numPtgs = tokens.size();
OperationPtg o;
int numOperands;
Node[] operands;
for (int i=0;i<numPtgs;i++) {
if (tokens.get(i) instanceof OperationPtg) {
o = (OperationPtg) tokens.get(i);
numOperands = o.getNumberOfOperands();
operands = new Node[numOperands];
for (int j=0;j<numOperands;j++) {
operands[numOperands-j-1] = (Node) stack.pop();
}
Node result = new Node(o);
result.setChildren(operands);
stack.push(result);
} else {
stack.push(new Node((Ptg)tokens.get(i)));
}
}
return (Node) stack.pop();
}
/** toString on the parser instance returns the RPN ordered list of tokens
* Useful for testing
@@ -491,5 +606,17 @@ end;
return buf.toString();
}
}
class Node {
private Ptg value=null;
private Node[] children=new Node[0];
private int numChild=0;
public Node(Ptg val) {
value = val;
}
public void setChildren(Node[] child) {children = child;numChild=child.length;}
public int getNumChildren() {return numChild;}
public Node getChild(int number) {return children[number];}
public Ptg getValue() {return value;}
}
}

+ 59
- 8
src/java/org/apache/poi/hssf/record/formula/FunctionPtg.java View File

@@ -9,15 +9,15 @@ import org.apache.poi.util.BinaryTree;
* This class provides functions with variable arguments.
* @author Avik Sengupta
* @author Andrew C. Oliver (acoliver at apache dot org)
* @version
*/
public class FunctionPtg extends OperationPtg {
public final static short sid = 0x22;
private final static int SIZE = 4;
private static BinaryTree map = produceHash();
static { map=produceHash();}
private static Object[][] functionData = produceFunctionData();
private byte returnClass;
private byte[] paramClass;
private byte field_1_num_args;
private short field_2_fnc_index;
@@ -30,7 +30,6 @@ public class FunctionPtg extends OperationPtg {
offset++;
field_1_num_args = data[ offset + 0 ];
field_2_fnc_index = LittleEndian.getShort(data,offset + 1 );
}
/**
@@ -39,7 +38,13 @@ public class FunctionPtg extends OperationPtg {
protected FunctionPtg(String pName, byte pNumOperands) {
field_1_num_args = pNumOperands;
field_2_fnc_index = lookupIndex(pName);
try{
returnClass = ( (Byte) functionData[field_2_fnc_index][0]).byteValue();
paramClass = (byte[]) functionData[field_2_fnc_index][1];
} catch (NullPointerException npe ) {
returnClass = Ptg.CLASS_VALUE;
paramClass = new byte[] {Ptg.CLASS_VALUE};
}
}
public String toString() {
@@ -89,7 +94,7 @@ public class FunctionPtg extends OperationPtg {
public void writeBytes(byte[] array, int offset) {
array[offset+0]=sid;
array[offset+0]=(byte) (sid + ptgClass);
array[offset+1]=field_1_num_args;
LittleEndian.putShort(array,offset+2,field_2_fnc_index);
}
@@ -99,11 +104,11 @@ public class FunctionPtg extends OperationPtg {
}
private String lookupName(short index) {
return ((String)map.get(new Integer(index))); //for now always return "SUM"
return ((String)map.get(new Integer(index)));
}
private short lookupIndex(String name) {
return (short)((Integer)map.getKeyForValue(name)).intValue(); //for now just return SUM everytime...
return (short)((Integer)map.getKeyForValue(name)).intValue();
}
/**
@@ -465,4 +470,50 @@ public class FunctionPtg extends OperationPtg {

return dmap;
}
private static Object[][] produceFunctionData() {
Object [][] functionData = new Object[368][2];
functionData[0][0]=new Byte(Ptg.CLASS_VALUE);functionData[0][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[2][0]=new Byte(Ptg.CLASS_VALUE);functionData[2][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[3][0]=new Byte(Ptg.CLASS_VALUE);functionData[3][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[4][0]=new Byte(Ptg.CLASS_VALUE);functionData[4][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[5][0]=new Byte(Ptg.CLASS_VALUE);functionData[5][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[6][0]=new Byte(Ptg.CLASS_VALUE);functionData[6][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[7][0]=new Byte(Ptg.CLASS_VALUE);functionData[7][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[8][0]=new Byte(Ptg.CLASS_VALUE);functionData[8][1]=new byte[] {Ptg.CLASS_REF};
functionData[9][0]=new Byte(Ptg.CLASS_VALUE);functionData[9][1]=new byte[] {Ptg.CLASS_REF};
functionData[10][0]=new Byte(Ptg.CLASS_VALUE);functionData[10][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[11][0]=new Byte(Ptg.CLASS_VALUE);functionData[11][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[12][0]=new Byte(Ptg.CLASS_VALUE);functionData[12][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[13][0]=new Byte(Ptg.CLASS_VALUE);functionData[13][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[14][0]=new Byte(Ptg.CLASS_VALUE);functionData[14][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[15][0]=new Byte(Ptg.CLASS_VALUE);functionData[15][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[16][0]=new Byte(Ptg.CLASS_VALUE);functionData[16][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[17][0]=new Byte(Ptg.CLASS_VALUE);functionData[17][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[18][0]=new Byte(Ptg.CLASS_VALUE);functionData[18][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[19][0]=new Byte(Ptg.CLASS_VALUE);functionData[19][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[20][0]=new Byte(Ptg.CLASS_VALUE);functionData[20][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[21][0]=new Byte(Ptg.CLASS_VALUE);functionData[21][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[22][0]=new Byte(Ptg.CLASS_VALUE);functionData[22][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[23][0]=new Byte(Ptg.CLASS_VALUE);functionData[23][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[24][0]=new Byte(Ptg.CLASS_VALUE);functionData[24][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[25][0]=new Byte(Ptg.CLASS_VALUE);functionData[25][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[26][0]=new Byte(Ptg.CLASS_VALUE);functionData[26][1]=new byte[] {Ptg.CLASS_VALUE};
functionData[27][0]=new Byte(Ptg.CLASS_VALUE);functionData[27][1]=new byte[] {Ptg.CLASS_VALUE};
return functionData;
}

public byte getDefaultOperandClass() {
return returnClass;
}
protected byte getParameterClass(int index) {
try {
return paramClass[index];
} catch (ArrayIndexOutOfBoundsException aioobe) {
return paramClass[paramClass.length - 1];
}
}
}

+ 1
- 1
src/java/org/apache/poi/hssf/record/formula/IntPtg.java View File

@@ -114,5 +114,5 @@ public class IntPtg
{
return "" + getValue();
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 1
- 0
src/java/org/apache/poi/hssf/record/formula/MemErrPtg.java View File

@@ -120,4 +120,5 @@ public class MemErrPtg
{
return "ERR#";
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 2
- 0
src/java/org/apache/poi/hssf/record/formula/NamePtg.java View File

@@ -106,4 +106,6 @@ public class NamePtg
{
return "NO IDEA - NAME";
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 1
- 1
src/java/org/apache/poi/hssf/record/formula/NumberPtg.java View File

@@ -113,6 +113,6 @@ public class NumberPtg
{
return "" + getValue();
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}


+ 2
- 0
src/java/org/apache/poi/hssf/record/formula/OperationPtg.java View File

@@ -88,4 +88,6 @@ public abstract class OperationPtg extends Ptg
*/
public abstract int getNumberOfOperands();
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}

+ 3
- 1
src/java/org/apache/poi/hssf/record/formula/ParenthesisPtg.java View File

@@ -112,7 +112,9 @@ public class ParenthesisPtg
public String toFormulaString(String[] operands) {
return "("+operands[0]+")";
}
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}
}


+ 1
- 3
src/java/org/apache/poi/hssf/record/formula/PowerPtg.java View File

@@ -109,9 +109,7 @@ public class PowerPtg
{
return "^";
}
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer();


+ 42
- 53
src/java/org/apache/poi/hssf/record/formula/Ptg.java View File

@@ -66,6 +66,7 @@ import java.util.ArrayList;
/**
*
* @author andy
* @author avik
*/

public abstract class Ptg
@@ -124,54 +125,18 @@ public abstract class Ptg
return retval;
}
*/

/*
private static List ptgsToList(Class [] ptgs)
{
List result = new ArrayList();
Constructor constructor;

for (int i = 0; i < ptgs.length; i++)
{
Class ptg = null;
ptg = ptgs[ i ];
try
{
constructor = ptg.getConstructor(new Class[]
{
byte [].class, int.class
});
}
catch (Exception illegalArgumentException)
{
throw new RuntimeException(
"Now that didn't work nicely at all (couldn't do that there list of ptgs)");
}
result.add(constructor);
}
return result;
}*/

public static Ptg createPtg(byte [] data, int offset)
{
byte id = data[ offset + 0 ];
Ptg retval = null;
final int refRef = ReferencePtg.sid - 0x20;
final int arrayRef = ReferencePtg.sid + 0x20;
final int valueFunc = FunctionPtg.sid + 0x20;
final int arrayFunc = FunctionPtg.sid + 0x40;
final int refArea = AreaPtg.sid-0x20;
final int arrayArea = AreaPtg.sid+0x20;

final byte valueRef = ReferencePtg.sid + 0x20;
final byte arrayRef = ReferencePtg.sid + 0x40;
final byte valueFunc = FunctionPtg.sid + 0x20;
final byte arrayFunc = FunctionPtg.sid + 0x40;
final byte valueArea = AreaPtg.sid + 0x20;
final byte arrayArea = AreaPtg.sid + 0x40;

switch (id)
{
@@ -207,7 +172,12 @@ public abstract class Ptg
case AreaPtg.sid :
retval = new AreaPtg(data, offset);
break;

case valueArea:
retval = new AreaPtg(data, offset);
break;
case arrayArea:
retval = new AreaPtg(data, offset);
break;
case MemErrPtg.sid :
retval = new MemErrPtg(data, offset);
break;
@@ -215,18 +185,16 @@ public abstract class Ptg
case AttrPtg.sid :
retval = new AttrPtg(data, offset);
break;
case ReferencePtg.sid :
retval = new ReferencePtg(data, offset);
break;
case refRef :
break;
case valueRef :
retval = new ReferencePtg(data, offset);
break;

break;
case arrayRef :
retval = new ReferencePtg(data, offset);
break;
break;

case ParenthesisPtg.sid :
retval = new ParenthesisPtg(data, offset);
@@ -239,7 +207,6 @@ public abstract class Ptg
case valueFunc :
retval = new FunctionPtg(data, offset);
break;
case arrayFunc :
retval = new FunctionPtg(data, offset);
break;
@@ -275,7 +242,15 @@ public abstract class Ptg
+ Integer.toHexString(( int ) id)
+ " (" + ( int ) id + ")");
}
return retval;
if (id > 0x60) {
retval.setClass(CLASS_ARRAY);
} else if (id > 0x40) {
retval.setClass(CLASS_VALUE);
} else
retval.setClass(CLASS_REF);
return retval;
}

public abstract int getSize();
@@ -310,5 +285,19 @@ public abstract class Ptg
return retval;
}
public static final byte CLASS_REF = 0x00;
public static final byte CLASS_VALUE = 0x20;
public static final byte CLASS_ARRAY = 0x40;
protected byte ptgClass = CLASS_REF; //base ptg
public void setClass(byte thePtgClass) {
ptgClass = thePtgClass;
}
public abstract byte getDefaultOperandClass();

}

+ 29
- 26
src/java/org/apache/poi/hssf/record/formula/Ref3DPtg.java View File

@@ -1,4 +1,5 @@


/* ====================================================================
* The Apache Software License, Version 1.1
*
@@ -72,22 +73,22 @@ public class Ref3DPtg extends Ptg {
private short field_1_index_extern_sheet;
private short field_2_row;
private short field_3_column;
/** Creates new AreaPtg */
public Ref3DPtg() {
}
public Ref3DPtg(byte[] data, int offset) {
offset++;
field_1_index_extern_sheet = LittleEndian.getShort(data, 0 + offset);
field_2_row = LittleEndian.getShort(data, 2 + offset);
field_3_column = LittleEndian.getShort(data, 4 + offset);
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("Ref3dPrg\n");
buffer.append("Index to Extern Sheet = " + getExternSheetIndex()).append("\n");
buffer.append("Row = " + getRow()).append("\n");
@@ -97,81 +98,83 @@ public class Ref3DPtg extends Ptg {
buffer.append("ColRel = " + isColRelative()).append("\n");
return buffer.toString();
}
public void writeBytes(byte [] array, int offset) {
array[ 0 + offset ] = sid;
LittleEndian.putShort(array, 1 + offset , getExternSheetIndex());
LittleEndian.putShort(array, 3 + offset , getRow());
LittleEndian.putShort(array, 5 + offset , getColumnRaw());
LittleEndian.putShort(array, 5 + offset , getColumnRaw());
}
public int getSize() {
return SIZE;
}
public short getExternSheetIndex(){
return field_1_index_extern_sheet;
}
public void setExternSheetIndex(short index){
field_1_index_extern_sheet = index;
}
public short getRow() {
return field_2_row;
}
public void setRow(short row) {
field_2_row = row;
}
public short getColumn() {
return ( short ) (field_3_column & 0xFF);
}
public short getColumnRaw() {
return field_3_column;
}
public boolean isColRowRelative() {
return (((getColumnRaw()) & 0x8000) == 0x8000);
}
public boolean isColRelative() {
return (((getColumnRaw()) & 0x4000) == 0x4000);
}
public void setColumn(short column) {
field_3_column &= 0xFF00;
field_3_column |= column & 0xFF;
}
public void setColumnRaw(short column) {
field_3_column = column;
}
public String getArea(){
RangeAddress ra = new RangeAddress("");
String result = (ra.numTo26Sys(getColumn()) + (getRow() + 1));
return result;
}

public void setArea(String ref){
RangeAddress ra = new RangeAddress(ref);
String from = ra.getFromCell();
setColumn((short) (ra.getXPosition(from) -1));
setRow((short) (ra.getYPosition(from) -1));
}

public String toFormulaString() {
String result = getArea();
return result;
}

public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}

}

+ 9
- 7
src/java/org/apache/poi/hssf/record/formula/ReferencePtg.java View File

@@ -66,18 +66,15 @@ import org.apache.poi.util.BitField;
import org.apache.poi.hssf.util.CellReference;

/**
* ValueReferencePtg - handles references (such as A1, A2, IA4) - Should also
* be made to handle relative versus absolute references but I don't know enough
* about using them in excel to know if its correct. Seems inverted to me.
* FIXME = correct abs vs relative references
* ReferencePtg - handles references (such as A1, A2, IA4)
* @author Andrew C. Oliver (acoliver@apache.org)
*/

public class ReferencePtg extends Ptg
{
private final static int SIZE = 5;
//public final static byte sid = 0x24;
public final static byte sid = 0x44;
public final static byte sid = 0x24;
//public final static byte sid = 0x44;
private short field_1_row;
private short field_2_col;
private BitField rowRelative = new BitField(0x8000);
@@ -120,7 +117,7 @@ public class ReferencePtg extends Ptg

public void writeBytes(byte [] array, int offset)
{
array[offset] = sid;
array[offset] = (byte) (sid + ptgClass);
LittleEndian.putShort(array,offset+1,field_1_row);
LittleEndian.putShort(array,offset+3,field_2_col);
}
@@ -183,4 +180,9 @@ public class ReferencePtg extends Ptg
//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();
}
public byte getDefaultOperandClass() {
return Ptg.CLASS_REF;
}
}

+ 11
- 8
src/java/org/apache/poi/hssf/record/formula/StringPtg.java View File

@@ -69,29 +69,29 @@ public class StringPtg
public final static byte sid = 0x17;
private String field_1_value;

/** Create a StringPtg from a byte array read from disk */
public StringPtg(byte [] data, int offset)
{
setValue(new String(data, offset+3, data[offset+1] + 256*data[offset+2]));
}
/** Create a StringPtg from a string representation of the number
* Number format is not checked, it is expected to be validated in the parser
* that calls this method.
* that calls this method.
* @param value : String representation of a floating point number
*/
protected StringPtg(String value) {
setValue(value);
}
public void setValue(String value)
{
field_1_value = value;
}
public String getValue()
{
return field_1_value;
@@ -114,6 +114,9 @@ public class StringPtg
{
return getValue();
}
public byte getDefaultOperandClass() {
return Ptg.CLASS_VALUE;
}

}


+ 3
- 0
src/java/org/apache/poi/hssf/record/formula/UnknownPtg.java View File

@@ -95,4 +95,7 @@ public class UnknownPtg
{
return "UNKNOWN";
}
public byte getDefaultOperandClass() {return Ptg.CLASS_VALUE;}

}

+ 2
- 0
src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java View File

@@ -768,6 +768,8 @@ extends TestCase {
c.setCellFormula("AVERAGE(A2:A3)");
c=r.createCell( (short) 4);
c.setCellFormula("POWER(A2,A3)");
c=r.createCell( (short) 5);
c.setCellFormula("SIN(A2)");
r = s.createRow((short) 1);c=r.createCell( (short) 0); c.setCellValue(2.0);
r = s.createRow((short) 2);c=r.createCell( (short) 0); c.setCellValue(3.0);

Loading…
Cancel
Save