PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352571 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew C. Oliver 2002-04-30 23:22:27 +00:00
parent f30f67e65c
commit b065e8de26
21 changed files with 104 additions and 275 deletions

View File

@ -82,6 +82,7 @@ import org.apache.poi.hssf.usermodel.*;
* FormulaViewer - finds formulas in a BIFF8 file and attempts to read them/display * FormulaViewer - finds formulas in a BIFF8 file and attempts to read them/display
* data from them. Only works if Formulas are enabled in "RecordFactory" * data from them. Only works if Formulas are enabled in "RecordFactory"
* @author andy * @author andy
* @author Avik
*/ */
public class FormulaViewer public class FormulaViewer
@ -132,40 +133,34 @@ public class FormulaViewer
public void parseFormulaRecord(FormulaRecord record) public void parseFormulaRecord(FormulaRecord record)
{ {
System.out.println("In ParseFormula Record"); System.out.println("==============================");
System.out.println("row = " + record.getRow()); System.out.print("row = " + record.getRow());
System.out.println("col = " + record.getColumn()); System.out.println(", col = " + record.getColumn());
System.out.println("value = " + record.getValue()); System.out.println("value = " + record.getValue());
System.out.println("xf = " + record.getXFIndex()); System.out.print("xf = " + record.getXFIndex());
System.out.println("number of ptgs = " System.out.print(", number of ptgs = "
+ record.getNumberOfExpressionTokens()); + record.getNumberOfExpressionTokens());
System.out.println("options = " + record.getOptions()); System.out.println(", options = " + record.getOptions());
System.out.println(composeForumla(record)); System.out.println("RPN List = "+formulaString(record));
System.out.println("Formula text = "+ composeForumla(record));
} }
public String composeForumla(FormulaRecord record) private String formulaString(FormulaRecord record) {
{
StringBuffer formula = new StringBuffer("="); StringBuffer formula = new StringBuffer("=");
int numptgs = record.getNumberOfExpressionTokens(); int numptgs = record.getNumberOfExpressionTokens();
List ptgs = record.getParsedExpression(); List tokens = record.getParsedExpression();
StringBuffer buf = new StringBuffer();
for (int ptgnum = numptgs - 1; ptgnum > (-1); ptgnum--) for (int i=0;i<numptgs;i++) {
{ buf.append( ( (Ptg)tokens.get(i)).toFormulaString());
Ptg ptg = ( Ptg ) ptgs.get(ptgnum); buf.append(' ');
OperationPtg optg = ( OperationPtg ) ptg;
int numops = optg.getNumberOfOperands();
Ptg[] ops = new Ptg[ numops ];
int opoffset = 1;
for (int opnum = ops.length - 1; opnum > -1; opnum--)
{
ops[ opnum ] = ( Ptg ) ptgs.get(ptgnum - opoffset);
opoffset++;
}
formula.append(optg.toFormulaString(ops));
ptgnum -= ops.length;
} }
return formula.toString(); return buf.toString();
}
private String composeForumla(FormulaRecord record)
{
return FormulaParser.toFormulaString(record.getParsedExpression());
} }
/** /**

View File

@ -64,7 +64,7 @@ import java.util.Iterator;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.hssf import org.apache.poi.hssf
.record.*; // normally I don't do this, buy we literally mean ALL .record.*; // normally I don't do this, buy we literally mean ALL
import org.apache.poi.hssf.record.formula.FormulaUtil; import org.apache.poi.hssf.record.formula.FormulaParser;
import org.apache.poi.hssf.record.formula.Ptg; import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.IntList; import org.apache.poi.util.IntList;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
@ -706,7 +706,9 @@ public class Sheet
rec.setOptions(( short ) 2); rec.setOptions(( short ) 2);
rec.setValue(0); rec.setValue(0);
rec.setXFIndex(( short ) 0x0f); rec.setXFIndex(( short ) 0x0f);
Ptg[] ptg = FormulaUtil.parseFormula(formula); FormulaParser fp = new FormulaParser(formula);
fp.parse();
Ptg[] ptg = fp.getRPNPtg();
int size = 0; int size = 0;
for (int k = 0; k < ptg.length; k++) for (int k = 0; k < ptg.length; k++)

View File

@ -78,7 +78,7 @@ public class AddPtg
/** Creates new AddPtg */ /** Creates new AddPtg */
public AddPtg() protected AddPtg()
{ {
} }
@ -88,9 +88,6 @@ public class AddPtg
// doesn't need anything // doesn't need anything
} }
protected AddPtg(String formula, int offset) {
}
public void writeBytes(byte [] array, int offset) public void writeBytes(byte [] array, int offset)
{ {
@ -112,31 +109,18 @@ public class AddPtg
return 2; return 2;
} }
/** Implementation of method from Ptg */
public String toFormulaString() public String toFormulaString()
{ {
return "+"; return "+";
} }
public String toFormulaString(Ptg [] operands) /** implementation of method from OperationsPtg*/
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ].toFormulaString());
buffer.append("+");
buffer.append(operands[ 1 ].toFormulaString());
return buffer.toString();
}
public int getStringLength() {
return 1;
}
public String toFormulaString(String[] operands) { public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]); buffer.append(operands[ 0 ]);
buffer.append("+"); buffer.append(toFormulaString());
buffer.append(operands[ 1 ]); buffer.append(operands[ 1 ]);
return buffer.toString(); return buffer.toString();
} }

View File

@ -85,13 +85,8 @@ public class AreaPtg
private BitField column = new BitField(0x3FFF); private BitField column = new BitField(0x3FFF);
/** Creates new AreaPtg */
public AreaPtg() protected AreaPtg(String arearef) {
{
}
public AreaPtg(String arearef) {
int[] xyxy = ReferenceUtil.getXYXYFromAreaRef(arearef); int[] xyxy = ReferenceUtil.getXYXYFromAreaRef(arearef);
setFirstRow((short)xyxy[0]); setFirstRow((short)xyxy[0]);
setFirstColumn((short)xyxy[1]); setFirstColumn((short)xyxy[1]);

View File

@ -87,10 +87,7 @@ public class AttrPtg
private BitField baxcel = new BitField(0x20); private BitField baxcel = new BitField(0x20);
private BitField space = new BitField(0x40); private BitField space = new BitField(0x40);
/** Creates new AttrPtg */ public AttrPtg() {
public AttrPtg()
{
} }
public AttrPtg(byte [] data, int offset) public AttrPtg(byte [] data, int offset)
@ -199,11 +196,6 @@ public class AttrPtg
return "SUM()"; return "SUM()";
} }
public String toFormulaString(Ptg [] operands)
{
return "SUM(" + operands[ 0 ].toFormulaString() + ")";
}
public int getNumberOfOperands() public int getNumberOfOperands()
{ {
return 1; return 1;
@ -218,8 +210,6 @@ public class AttrPtg
return "SUM(" + operands[ 0 ] + ")"; return "SUM(" + operands[ 0 ] + ")";
} }
public int getPrecedence() {
return 1;
}
} }

View File

@ -75,19 +75,13 @@ public class ConcatPtg
private final static String CONCAT = "&"; private final static String CONCAT = "&";
/** Creates new ConcatPtg */
public ConcatPtg()
{
}
public ConcatPtg(byte [] data, int offset) public ConcatPtg(byte [] data, int offset)
{ {
// doesn't need anything // doesn't need anything
} }
protected ConcatPtg(String formula, int offset) { protected ConcatPtg() {
} }
@ -116,20 +110,6 @@ public class ConcatPtg
return CONCAT; return CONCAT;
} }
public String toFormulaString(Ptg [] operands)
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ].toFormulaString());
buffer.append(CONCAT);
buffer.append(operands[ 1 ].toFormulaString());
return buffer.toString();
}
public int getStringLength() {
return 1;
}
public String toFormulaString(String[] operands) { public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();

View File

@ -75,7 +75,7 @@ public class DividePtg
/** Creates new AddPtg */ /** Creates new AddPtg */
public DividePtg() protected DividePtg()
{ {
} }
@ -110,25 +110,11 @@ public class DividePtg
return "/"; return "/";
} }
public String toFormulaString(Ptg [] operands) public String toFormulaString(String[] operands) {
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ].toFormulaString());
buffer.append("/");
buffer.append(operands[ 1 ].toFormulaString());
return buffer.toString();
}
public int getStringLength() {
return 1;
}
public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]); buffer.append(operands[ 0 ]);
buffer.append("/"); buffer.append(toFormulaString());
buffer.append(operands[ 1 ]); buffer.append(operands[ 1 ]);
return buffer.toString(); return buffer.toString();
} }

View File

@ -73,7 +73,7 @@ public class ExpPtg
/** Creates new ExpPtg */ /** Creates new ExpPtg */
public ExpPtg() protected ExpPtg()
{ {
} }

View File

@ -310,8 +310,6 @@ public class FormulaParser {
if (IsDigit(Look)) number = number +"."+ GetNum(); //this also takes care of someone entering "1234." if (IsDigit(Look)) number = number +"."+ GetNum(); //this also takes care of someone entering "1234."
tokens.add(new NumberPtg(number)); tokens.add(new NumberPtg(number));
} else { } else {
//IntPtg p = new IntPtg(GetNum()); // removing since a ptg should be able to create itself from parser results.
//p.setValue(Short.parseShort(GetNum()));
tokens.add(new IntPtg(number)); //TODO:what if the number is too big to be a short? ..add factory to return Int or Number! tokens.add(new IntPtg(number)); //TODO:what if the number is too big to be a short? ..add factory to return Int or Number!
} }
} }
@ -450,7 +448,6 @@ end;
/** Static method to convert an array of Ptgs in RPN order /** Static method to convert an array of Ptgs in RPN order
* to a human readable string format in infix mode * to a human readable string format in infix mode
* TODO - extra brackets might appear, but string will be semantically correct.
*/ */
public static String toFormulaString(Ptg[] ptgs) { public static String toFormulaString(Ptg[] ptgs) {
java.util.Stack stack = new java.util.Stack(); java.util.Stack stack = new java.util.Stack();
@ -468,7 +465,6 @@ end;
} }
String result = o.toFormulaString(operands); String result = o.toFormulaString(operands);
//if (! (o instanceof DummyFunctionPtg) ) result = "("+result+")" ;
stack.push(result); stack.push(result);
} else { } else {
stack.push(ptgs[i].toFormulaString()); stack.push(ptgs[i].toFormulaString());
@ -477,6 +473,9 @@ end;
return (String) stack.pop(); //TODO: catch stack underflow and throw parse exception. return (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
} }
/** toString on the parser instance returns the RPN ordered list of tokens
* Useful for testing
*/
public String toString() { public String toString() {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (int i=0;i<tokens.size();i++) { for (int i=0;i<tokens.size();i++) {

View File

@ -16,12 +16,10 @@ public class FunctionPtg extends OperationPtg {
private byte field_1_num_args; private byte field_1_num_args;
private short field_2_fnc_index; private short field_2_fnc_index;
//private String name;
//private int numOperands;
/** Creates new DummyFunctionPtg */
public FunctionPtg() {
}
/**Creates new function pointer from a byte array
* usually called while reading an excel file.
*/
public FunctionPtg(byte[] data, int offset) { public FunctionPtg(byte[] data, int offset) {
offset++; offset++;
field_1_num_args = data[ offset + 0 ]; field_1_num_args = data[ offset + 0 ];
@ -29,8 +27,10 @@ public class FunctionPtg extends OperationPtg {
} }
/**
public FunctionPtg(String pName, byte pNumOperands) { * Create a function ptg from a string tokenised by the parser
*/
protected FunctionPtg(String pName, byte pNumOperands) {
field_1_num_args = pNumOperands; field_1_num_args = pNumOperands;
field_2_fnc_index = lookupIndex(pName); field_2_fnc_index = lookupIndex(pName);
@ -64,20 +64,10 @@ public class FunctionPtg extends OperationPtg {
} }
public String toFormulaString() { public String toFormulaString() {
return getName()+getNumberOfOperands(); return getName();
} }
public String toFormulaString(Ptg[] operands) { public String toFormulaString(String[] operands) {
StringBuffer buf = new StringBuffer();
buf.append(getName()+"(");
for (int i=0;i<operands.length;i++) {
buf.append(operands[i].toFormulaString()).append(',');
}
buf.append(")");
return buf.toString();
}
public String toFormulaString(String[] operands) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
buf.append(getName()+"("); buf.append(getName()+"(");
if (operands.length >0) { if (operands.length >0) {

View File

@ -77,23 +77,12 @@ public class IntPtg
private String val; private String val;
private int strlen = 0; private int strlen = 0;
/** Creates new IntPtg */
public IntPtg()
{
}
public IntPtg(byte [] data, int offset) public IntPtg(byte [] data, int offset)
{ {
setValue(LittleEndian.getShort(data, offset + 1)); setValue(LittleEndian.getShort(data, offset + 1));
} }
protected IntPtg(String formula, int offset) {
val = parseString(formula, offset);
if (val == null) throw new RuntimeException("WHOOAA there...thats got no int!");
strlen=val.length();
field_1_value = Short.parseShort(val);
}
// IntPtg should be able to create itself, shouldnt have to call setValue // IntPtg should be able to create itself, shouldnt have to call setValue
protected IntPtg(String formulaToken) { protected IntPtg(String formulaToken) {
@ -126,37 +115,4 @@ public class IntPtg
return "" + getValue(); return "" + getValue();
} }
private static String parseString(String formula, int pos) {
String retval = null;
while (pos < formula.length() && Character.isWhitespace(formula.charAt(pos))) {
pos++;
}
if (pos < formula.length()) {
if (Character.isDigit(formula.charAt(pos)) ) {
int numpos = pos;
while (numpos < formula.length() && Character.isDigit(formula.charAt(numpos))){
numpos++;
}
if (numpos == formula.length() || formula.charAt(numpos) != '.') {
String numberstr = formula.substring(pos,numpos);
try {
int number = Short.parseShort(numberstr);
retval = numberstr;
} catch (NumberFormatException e) {
retval = null;
}
}
}
}
return retval;
}
public int getStringLength() {
return strlen;
}
} }

View File

@ -77,7 +77,7 @@ public class MultiplyPtg
/** Creates new AddPtg */ /** Creates new AddPtg */
public MultiplyPtg() protected MultiplyPtg()
{ {
} }
@ -87,11 +87,6 @@ public class MultiplyPtg
// doesn't need anything // doesn't need anything
} }
protected MultiplyPtg(String formula, int offset) {
}
public void writeBytes(byte [] array, int offset) public void writeBytes(byte [] array, int offset)
{ {
array[ offset + 0 ] = sid; array[ offset + 0 ] = sid;
@ -136,7 +131,7 @@ public class MultiplyPtg
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ]); buffer.append(operands[ 0 ]);
buffer.append("*"); buffer.append(toFormulaString());
buffer.append(operands[ 1 ]); buffer.append(operands[ 1 ]);
return buffer.toString(); return buffer.toString();
} }

View File

@ -78,8 +78,9 @@ public class NamePtg
/** Creates new NamePtg */ /** Creates new NamePtg */
public NamePtg() protected NamePtg(String name)
{ {
//TODO
} }
/** Creates new NamePtg */ /** Creates new NamePtg */

View File

@ -57,8 +57,9 @@ package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndian;
/** /**
* Integer (short intger) * Number
* Stores a (java) short value in a formula * Stores a floating point value in a formula
* value stored in a 8 byte field using IEEE notation
* @author Avik Sengupta * @author Avik Sengupta
*/ */
@ -69,25 +70,29 @@ public class NumberPtg
public final static byte sid = 0x1f; public final static byte sid = 0x1f;
private double field_1_value; private double field_1_value;
/** Creates new NumberPtg */
public NumberPtg()
{
}
/** Create a NumberPtg from a byte array read from disk */
public NumberPtg(byte [] data, int offset) public NumberPtg(byte [] data, int offset)
{ {
setValue(LittleEndian.getDouble(data, offset + 1)); setValue(LittleEndian.getDouble(data, offset + 1));
} }
/** Create a NumberPtg 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.
* @param value : String representation of a floating point number
*/
protected NumberPtg(String value) { protected NumberPtg(String value) {
setValue(Double.parseDouble(value)); setValue(Double.parseDouble(value));
} }
public void setValue(double value) public void setValue(double value)
{ {
field_1_value = value; field_1_value = value;
} }
public double getValue() public double getValue()
{ {
return field_1_value; return field_1_value;
@ -109,10 +114,5 @@ public class NumberPtg
return "" + getValue(); return "" + getValue();
} }
//TODO: do we really need this method??
public int getStringLength() {
return 1;
}
} }

View File

@ -75,11 +75,17 @@ public abstract class OperationPtg extends Ptg
public abstract int getType(); public abstract int getType();
/**
* returns a string representation of the operations
* the length of the input array should equal the number returned by
* @see getNumberOfOperands
*
*/
public abstract String toFormulaString(String[] operands); public abstract String toFormulaString(String[] operands);
/**
* The number of operands expected by the operations
*/
public abstract int getNumberOfOperands(); public abstract int getNumberOfOperands();
public abstract String toFormulaString(Ptg [] operands);
} }

View File

@ -72,7 +72,7 @@ public class ParenthesisPtg
private final static int SIZE = 1; private final static int SIZE = 1;
public final static byte sid = 0x15; public final static byte sid = 0x15;
public ParenthesisPtg() protected ParenthesisPtg()
{ {
} }
@ -82,9 +82,6 @@ public class ParenthesisPtg
// doesn't need anything // doesn't need anything
} }
protected ParenthesisPtg(String formula, int offset) {
}
public void writeBytes(byte [] array, int offset) public void writeBytes(byte [] array, int offset)
@ -112,10 +109,6 @@ public class ParenthesisPtg
return "()"; return "()";
} }
public String toFormulaString(Ptg [] operands)
{
return "";
}
public String toFormulaString(String[] operands) { public String toFormulaString(String[] operands) {
return "("+operands[0]+")"; return "("+operands[0]+")";

View File

@ -75,7 +75,7 @@ public class PowerPtg
/** Creates new AddPtg */ /** Creates new AddPtg */
public PowerPtg() protected PowerPtg()
{ {
} }
@ -110,16 +110,6 @@ public class PowerPtg
return "^"; return "^";
} }
public String toFormulaString(Ptg [] operands)
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ].toFormulaString());
buffer.append("^");
buffer.append(operands[ 1 ].toFormulaString());
return buffer.toString();
}
public String toFormulaString(String[] operands) { public String toFormulaString(String[] operands) {
@ -127,7 +117,7 @@ public class PowerPtg
buffer.append(operands[ 0 ]); buffer.append(operands[ 0 ]);
buffer.append("^"); buffer.append(toFormulaString());
buffer.append(operands[ 1 ]); buffer.append(operands[ 1 ]);
return buffer.toString(); return buffer.toString();
} }

View File

@ -77,7 +77,7 @@ public abstract class Ptg
* @param infixPtgs List of ptgs in infix order * @param infixPtgs List of ptgs in infix order
*/ */
/* DO NOI REMOVE /* DO NOT REMOVE
*we keep this method in case we wish to change the way we parse *we keep this method in case we wish to change the way we parse
*It needs a getPrecedence in OperationsPtg *It needs a getPrecedence in OperationsPtg
@ -287,15 +287,13 @@ public abstract class Ptg
writeBytes(bytes, 0); writeBytes(bytes, 0);
return bytes; return bytes;
} }
/** write this Ptg to a byte array*/
public abstract void writeBytes(byte [] array, int offset); public abstract void writeBytes(byte [] array, int offset);
/**
* return a string representation of this token alone
*/
public abstract String toFormulaString(); public abstract String toFormulaString();
public int getStringLength() {
return 0;
}
/** /**
* dump a debug representation (hexdump) to a strnig * dump a debug representation (hexdump) to a strnig
*/ */

View File

@ -82,17 +82,13 @@ public class ReferencePtg extends Ptg
private BitField rowRelative = new BitField(0x8000); private BitField rowRelative = new BitField(0x8000);
private BitField colRelative = new BitField(0x4000); private BitField colRelative = new BitField(0x4000);
/** Creates new ValueReferencePtg */
public ReferencePtg()
{
}
/** /**
* Takes in a String represnetation of a cell reference and fills out the * Takes in a String represnetation of a cell reference and fills out the
* numeric fields. * numeric fields.
*/ */
public ReferencePtg(String cellref) { protected ReferencePtg(String cellref) {
int[] xy = ReferenceUtil.getXYFromReference(cellref); int[] xy = ReferenceUtil.getXYFromReference(cellref);
setRow((short)xy[0]); setRow((short)xy[0]);
setColumn((short)xy[1]); setColumn((short)xy[1]);

View File

@ -73,9 +73,7 @@ public class SubtractPtg
public final static int SIZE = 1; public final static int SIZE = 1;
public final static byte sid = 0x04; public final static byte sid = 0x04;
/** Creates new AddPtg */ protected SubtractPtg()
public SubtractPtg()
{ {
} }
@ -110,20 +108,6 @@ public class SubtractPtg
return "-"; return "-";
} }
public String toFormulaString(Ptg [] operands)
{
StringBuffer buffer = new StringBuffer();
buffer.append(operands[ 0 ].toFormulaString());
buffer.append("-");
buffer.append(operands[ 1 ].toFormulaString());
return buffer.toString();
}
public int getStringLength() {
return 1;
}
public String toFormulaString(String[] operands) { public String toFormulaString(String[] operands) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();

View File

@ -124,23 +124,12 @@ public class ValueVariableFunctionPtg
return "NO IDEA YET VALUE VARIABLE"; return "NO IDEA YET VALUE VARIABLE";
} }
public String toFormulaString(Ptg [] operands)
{
return toFormulaString();
}
public String toFormulaString(String[] operands) { public String toFormulaString(String[] operands) {
return toFormulaString(); return toFormulaString();
} }
public void manipulate(List source, List results, int pos) {
}
public int getPrecedence() {
return 1;
}