*read only* support for optimized ifs. meaning "if(A1=A3,A1,A2)" and stuff.
This optimized if has the conceptual clarity of a featherweight elephant carrier used as a pizza topping. This concludes my therapy session. I love this project :-). Next week I'll try and get write support underway unless someone beats me to it. PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352839 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ce178660f2
commit
32543e4e8c
@ -603,20 +603,42 @@ end;
|
|||||||
int numPtgs = ptgs.length;
|
int numPtgs = ptgs.length;
|
||||||
OperationPtg o;
|
OperationPtg o;
|
||||||
int numOperands;
|
int numOperands;
|
||||||
|
String result=null;
|
||||||
String[] operands;
|
String[] operands;
|
||||||
|
AttrPtg ifptg = null;
|
||||||
for (int i=0;i<numPtgs;i++) {
|
for (int i=0;i<numPtgs;i++) {
|
||||||
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
|
// Excel allows to have AttrPtg at position 0 (such as Blanks) which
|
||||||
// do not have any operands. Skip them.
|
// do not have any operands. Skip them.
|
||||||
if (ptgs[i] instanceof OperationPtg && i>0) {
|
if (ptgs[i] instanceof OperationPtg && i>0) {
|
||||||
o = (OperationPtg) ptgs[i];
|
o = (OperationPtg) ptgs[i];
|
||||||
|
|
||||||
|
if (o instanceof AttrPtg && ((AttrPtg)o).isOptimizedIf()) {
|
||||||
|
ifptg=(AttrPtg)o;
|
||||||
|
} else {
|
||||||
|
|
||||||
numOperands = o.getNumberOfOperands();
|
numOperands = o.getNumberOfOperands();
|
||||||
operands = new String[numOperands];
|
operands = new String[numOperands];
|
||||||
|
|
||||||
for (int j=0;j<numOperands;j++) {
|
for (int j=0;j<numOperands;j++) {
|
||||||
operands[numOperands-j-1] = (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
|
operands[numOperands-j-1] = (String) stack.pop(); //TODO: catch stack underflow and throw parse exception.
|
||||||
|
|
||||||
}
|
}
|
||||||
String result = o.toFormulaString(operands);
|
|
||||||
|
if ( (o instanceof AbstractFunctionPtg) &&
|
||||||
|
((AbstractFunctionPtg)o).getName().equals("specialflag") &&
|
||||||
|
ifptg != null
|
||||||
|
) {
|
||||||
|
// this special case will be way different.
|
||||||
|
result = ifptg.toFormulaString(
|
||||||
|
new String[] {(o.toFormulaString(operands))}
|
||||||
|
);
|
||||||
|
ifptg = null;
|
||||||
|
} else {
|
||||||
|
result = o.toFormulaString(operands);
|
||||||
|
}
|
||||||
stack.push(result);
|
stack.push(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
stack.push(ptgs[i].toFormulaString(refs));
|
stack.push(ptgs[i].toFormulaString(refs));
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package org.apache.poi.hssf.record.formula;
|
|||||||
import org.apache.poi.util.BinaryTree;
|
import org.apache.poi.util.BinaryTree;
|
||||||
import org.apache.poi.hssf.util.SheetReferences;
|
import org.apache.poi.hssf.util.SheetReferences;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides the base functionality for Excel sheet functions
|
* This class provides the base functionality for Excel sheet functions
|
||||||
* There are two kinds of function Ptgs - tFunc and tFuncVar
|
* There are two kinds of function Ptgs - tFunc and tFuncVar
|
||||||
@ -44,11 +46,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
if(field_2_fnc_index != 1) {
|
|
||||||
return lookupName(field_2_fnc_index);
|
return lookupName(field_2_fnc_index);
|
||||||
} else {
|
|
||||||
return "Funky case of formula recombinating";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toFormulaString(SheetReferences refs) {
|
public String toFormulaString(SheetReferences refs) {
|
||||||
@ -57,8 +55,11 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
|||||||
|
|
||||||
public String toFormulaString(String[] operands) {
|
public String toFormulaString(String[] operands) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
|
|
||||||
if (field_2_fnc_index != 1) {
|
if (field_2_fnc_index != 1) {
|
||||||
buf.append(getName()+"(");
|
buf.append(getName());
|
||||||
|
buf.append('(');
|
||||||
|
}
|
||||||
if (operands.length >0) {
|
if (operands.length >0) {
|
||||||
for (int i=0;i<operands.length;i++) {
|
for (int i=0;i<operands.length;i++) {
|
||||||
buf.append(operands[i]);
|
buf.append(operands[i]);
|
||||||
@ -66,11 +67,8 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
|||||||
}
|
}
|
||||||
buf.deleteCharAt(buf.length()-1);
|
buf.deleteCharAt(buf.length()-1);
|
||||||
}
|
}
|
||||||
|
if (field_2_fnc_index != 1) {
|
||||||
buf.append(")");
|
buf.append(")");
|
||||||
} else {
|
|
||||||
throw new RuntimeException("FUNKY CASE OF FORMULA RECOMBINATION NOT "+
|
|
||||||
"YET IMPLEMENTED");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
@ -98,6 +96,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
|||||||
BinaryTree dmap = new BinaryTree();
|
BinaryTree dmap = new BinaryTree();
|
||||||
|
|
||||||
dmap.put(new Integer(0),"COUNT");
|
dmap.put(new Integer(0),"COUNT");
|
||||||
|
dmap.put(new Integer(1),"specialflag");
|
||||||
dmap.put(new Integer(2),"ISNA");
|
dmap.put(new Integer(2),"ISNA");
|
||||||
dmap.put(new Integer(3),"ISERROR");
|
dmap.put(new Integer(3),"ISERROR");
|
||||||
dmap.put(new Integer(4),"SUM");
|
dmap.put(new Integer(4),"SUM");
|
||||||
|
@ -203,6 +203,8 @@ public class AttrPtg
|
|||||||
return operands[ 0 ];
|
return operands[ 0 ];
|
||||||
} else if (optiIf.isSet(field_1_options)) {
|
} else if (optiIf.isSet(field_1_options)) {
|
||||||
return toFormulaString((SheetReferences)null) + "(" + operands[ 0 ] +")";
|
return toFormulaString((SheetReferences)null) + "(" + operands[ 0 ] +")";
|
||||||
|
} else if (optGoto.isSet(field_1_options)) {
|
||||||
|
return toFormulaString((SheetReferences)null) + operands[0]; //goto isn't a real formula element should not show up
|
||||||
} else {
|
} else {
|
||||||
return toFormulaString((SheetReferences)null) + "(" + operands[ 0 ] + ")";
|
return toFormulaString((SheetReferences)null) + "(" + operands[ 0 ] + ")";
|
||||||
}
|
}
|
||||||
@ -230,7 +232,7 @@ public class AttrPtg
|
|||||||
return "CHOOSE";
|
return "CHOOSE";
|
||||||
}
|
}
|
||||||
if(optGoto.isSet(field_1_options)) {
|
if(optGoto.isSet(field_1_options)) {
|
||||||
return "GOTO";
|
return "";
|
||||||
}
|
}
|
||||||
if(sum.isSet(field_1_options)) {
|
if(sum.isSet(field_1_options)) {
|
||||||
return "SUM";
|
return "SUM";
|
||||||
|
@ -880,12 +880,22 @@ extends TestCase {
|
|||||||
|
|
||||||
assertTrue("file exists",file.exists());
|
assertTrue("file exists",file.exists());
|
||||||
|
|
||||||
FileInputStream in = new FileInputStream(readFilename+File.separator+"IfFormulaTest.xls");
|
FileInputStream in = new FileInputStream(file);
|
||||||
|
wb = new HSSFWorkbook(in);
|
||||||
|
s = wb.getSheetAt(0);
|
||||||
|
r = s.getRow(0);
|
||||||
|
c = r.getCell((short)4);
|
||||||
|
|
||||||
|
assertTrue("expected: IF(A1=D1,\"A1\",\"B1\") got "+c.getCellFormula(), ("IF(A1=D1,\"A1\",\"B1\")").equals(c.getCellFormula()));
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
|
||||||
|
in = new FileInputStream(readFilename+File.separator+"IfFormulaTest.xls");
|
||||||
wb = new HSSFWorkbook(in);
|
wb = new HSSFWorkbook(in);
|
||||||
s = wb.getSheetAt(0);
|
s = wb.getSheetAt(0);
|
||||||
r = s.getRow(3);
|
r = s.getRow(3);
|
||||||
c = r.getCell((short)0);
|
c = r.getCell((short)0);
|
||||||
assertTrue("expected: IF(A3=A1,\"A1\",\"B1\") got "+c.getCellFormula(), ("IF(A3=A1,\"A1\",\"B1\")").equals(c.getCellFormula()));
|
assertTrue("expected: IF(A3=A1,\"A1\",\"A2\") got "+c.getCellFormula(), ("IF(A3=A1,\"A1\",\"A2\")").equals(c.getCellFormula()));
|
||||||
//c = r.getCell((short)1);
|
//c = r.getCell((short)1);
|
||||||
//assertTrue("expected: A!A1+A!B1 got: "+c.getCellFormula(), ("A!A1+A!B1").equals(c.getCellFormula()));
|
//assertTrue("expected: A!A1+A!B1 got: "+c.getCellFormula(), ("A!A1+A!B1").equals(c.getCellFormula()));
|
||||||
in.close();
|
in.close();
|
||||||
|
Loading…
Reference in New Issue
Block a user