summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDanny Mui <dmui@apache.org>2003-03-15 01:57:41 +0000
committerDanny Mui <dmui@apache.org>2003-03-15 01:57:41 +0000
commit4d2a757cdc1f0cd6c0c461e804c5642f26c9fa18 (patch)
tree42246bea1d15682358b1fb06a1728359dddb7c64 /src
parentf48736e73d768c1d2f49e21a10c0a3bda3b7e9ca (diff)
downloadpoi-4d2a757cdc1f0cd6c0c461e804c5642f26c9fa18.tar.gz
poi-4d2a757cdc1f0cd6c0c461e804c5642f26c9fa18.zip
FormulaParser changes to support IF function(s)
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353027 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/hssf/model/FormulaParser.java172
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java57
-rw-r--r--src/java/org/apache/poi/hssf/record/formula/AttrPtg.java10
-rw-r--r--src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java136
-rw-r--r--src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java55
5 files changed, 407 insertions, 23 deletions
diff --git a/src/java/org/apache/poi/hssf/model/FormulaParser.java b/src/java/org/apache/poi/hssf/model/FormulaParser.java
index 06c28c9f5d..99314bb86b 100644
--- a/src/java/org/apache/poi/hssf/model/FormulaParser.java
+++ b/src/java/org/apache/poi/hssf/model/FormulaParser.java
@@ -2,7 +2,7 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,12 +56,34 @@
package org.apache.poi.hssf.model;
-import org.apache.poi.hssf.record.formula.*;
-import org.apache.poi.hssf.util.SheetReferences;
-
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
+import org.apache.poi.hssf.record.formula.AbstractFunctionPtg;
+import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.hssf.record.formula.Area3DPtg;
+import org.apache.poi.hssf.record.formula.AreaPtg;
+import org.apache.poi.hssf.record.formula.AttrPtg;
+import org.apache.poi.hssf.record.formula.BoolPtg;
+import org.apache.poi.hssf.record.formula.ConcatPtg;
+import org.apache.poi.hssf.record.formula.DividePtg;
+import org.apache.poi.hssf.record.formula.EqualPtg;
+import org.apache.poi.hssf.record.formula.FuncVarPtg;
+import org.apache.poi.hssf.record.formula.IntPtg;
+import org.apache.poi.hssf.record.formula.MultiplyPtg;
+import org.apache.poi.hssf.record.formula.NumberPtg;
+import org.apache.poi.hssf.record.formula.OperationPtg;
+import org.apache.poi.hssf.record.formula.ParenthesisPtg;
+import org.apache.poi.hssf.record.formula.PowerPtg;
+import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.Ref3DPtg;
+import org.apache.poi.hssf.record.formula.ReferencePtg;
+import org.apache.poi.hssf.record.formula.StringPtg;
+import org.apache.poi.hssf.record.formula.SubtractPtg;
+import org.apache.poi.hssf.util.SheetReferences;
+
/**
* This class parses a formula string into a List of tokens in RPN order.
@@ -90,6 +112,12 @@ public class FormulaParser {
private int formulaLength;
private List tokens = new java.util.Stack();
+
+ /**
+ * Using an unsynchronized linkedlist to implement a stack since we're not multi-threaded.
+ */
+ private List functionTokens = new LinkedList();
+
//private Stack tokens = new java.util.Stack();
private List result = new ArrayList();
private int numParen;
@@ -98,6 +126,7 @@ public class FormulaParser {
private static char CR = '\n';
private char look; // Lookahead Character
+ private boolean inFunction = false;
private Workbook book;
@@ -297,25 +326,140 @@ public class FormulaParser {
}
}
+ /**
+ * Adds a pointer to the last token to the latest function argument list.
+ * @param obj
+ */
+ private void addArgumentPointer() {
+ if (this.functionTokens.size() > 0) {
+ //no bounds check because this method should not be called unless a token array is setup by function()
+ List arguments = (List)this.functionTokens.get(0);
+ arguments.add(tokens.get(tokens.size()-1));
+ }
+ }
+
private void function(String name) {
+ //average 2 args per function
+ this.functionTokens.add(0, new ArrayList(2));
+
Match('(');
int numArgs = Arguments();
Match(')');
- tokens.add(getFunction(name,(byte)numArgs));
+
+ Ptg functionPtg = getFunction(name,(byte)numArgs);
+
+ tokens.add(functionPtg);
+
+ //remove what we just put in
+ this.functionTokens.remove(0);
}
+ /**
+ * Adds the size of all the ptgs after the provided index (inclusive).
+ * <p>
+ * Initially used to count a goto
+ * @param index
+ * @return int
+ */
+ private int getPtgSize(int index) {
+ int count = 0;
+
+ Iterator ptgIterator = tokens.listIterator(index);
+ while (ptgIterator.hasNext()) {
+ Ptg ptg = (Ptg)ptgIterator.next();
+ count+=ptg.getSize();
+ }
+
+ return count;
+ }
+
+ private int getPtgSize(int start, int end) {
+ int count = 0;
+ int index = start;
+ Iterator ptgIterator = tokens.listIterator(index);
+ while (ptgIterator.hasNext() && index <= end) {
+ Ptg ptg = (Ptg)ptgIterator.next();
+ count+=ptg.getSize();
+ index++;
+ }
+
+ return count;
+ }
+
+ /**
+ * Generates the variable function ptg for the formula.
+ * <p>
+ * For IF Formulas, additional PTGs are added to the tokens
+ * @param name
+ * @param numArgs
+ * @return Ptg a null is returned if we're in an IF formula, it needs extreme manipulation and is handled in this function
+ */
private Ptg getFunction(String name,byte numArgs) {
Ptg retval = null;
- //retval = new FuncVarPtg(name,numArgs);
- if (name.equals("IF")) {
- AttrPtg ptg = new AttrPtg();
- ptg.setData((short)6); //sums don't care but this is what excel does.
- ptg.setOptimizedIf(true);
- retval = ptg;
+
+ if (name.equals("IF")) {
+ retval = new FuncVarPtg(AbstractFunctionPtg.ATTR_NAME, numArgs);
+
+ //simulated pop, no bounds checking because this list better be populated by function()
+ List argumentPointers = (List)this.functionTokens.get(0);
+
+
+ AttrPtg ifPtg = new AttrPtg();
+ ifPtg.setData((short)7); //mirroring excel output
+ ifPtg.setOptimizedIf(true);
+
+ if (argumentPointers.size() != 2 && argumentPointers.size() != 3) {
+ throw new IllegalArgumentException("["+argumentPointers.size()+"] Arguments Found - An IF formula requires 2 or 3 arguments. IF(CONDITION, TRUE_VALUE, FALSE_VALUE [OPTIONAL]");
+ }
+
+ //Biffview of an IF formula record indicates the attr ptg goes after the condition ptgs and are
+ //tracked in the argument pointers
+ //The beginning first argument pointer is the last ptg of the condition
+ int ifIndex = tokens.indexOf(argumentPointers.get(0))+1;
+ tokens.add(ifIndex, ifPtg);
+
+ //we now need a goto ptgAttr to skip to the end of the formula after a true condition
+ //the true condition is should be inserted after the last ptg in the first argument
+
+ int gotoIndex = tokens.indexOf(argumentPointers.get(1))+1;
+
+ AttrPtg goto1Ptg = new AttrPtg();
+ goto1Ptg.setGoto(true);
+
+
+ tokens.add(gotoIndex, goto1Ptg);
+
+
+ if (numArgs > 2) { //only add false jump if there is a false condition
+
+ //second goto to skip past the function ptg
+ AttrPtg goto2Ptg = new AttrPtg();
+ goto2Ptg.setGoto(true);
+ goto2Ptg.setData((short)(retval.getSize()-1));
+ //Page 472 of the Microsoft Excel Developer's kit states that:
+ //The b(or w) field specifies the number byes (or words to skip, minus 1
+
+ tokens.add(goto2Ptg); //this goes after all the arguments are defined
+ }
+
+ //data portion of the if ptg points to the false subexpression (Page 472 of MS Excel Developer's kit)
+ //count the number of bytes after the ifPtg to the False Subexpression
+ //doesn't specify -1 in the documentation
+ ifPtg.setData((short)(getPtgSize(ifIndex+1, gotoIndex)));
+
+ //count all the additional (goto) ptgs but dont count itself
+ int ptgCount = this.getPtgSize(gotoIndex)-goto1Ptg.getSize()+retval.getSize();
+ if (ptgCount > (int)Short.MAX_VALUE) {
+ throw new RuntimeException("Ptg Size exceeds short when being specified for a goto ptg in an if");
+ }
+
+ goto1Ptg.setData((short)(ptgCount-1));
+
} else {
- retval = new FuncVarPtg(name,numArgs);
+
+ retval = new FuncVarPtg(name,numArgs);
}
-
+
return retval;
}
@@ -451,6 +595,8 @@ public class FormulaParser {
if (look == '*') Multiply();
if (look == '/') Divide();
}
+ addArgumentPointer();
+
}
diff --git a/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java b/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
index 17004fbe77..6dcb7ef0f1 100644
--- a/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/AbstractFunctionPtg.java
@@ -1,3 +1,56 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
package org.apache.poi.hssf.record.formula;
import org.apache.poi.util.BinaryTree;
@@ -13,7 +66,9 @@ import java.util.Stack;
* @author Andrew C. Oliver (acoliver at apache dot org)
*/
public abstract class AbstractFunctionPtg extends OperationPtg {
-
+ //constant used allow a ptgAttr to be mapped properly for its functionPtg
+ public static final String ATTR_NAME = "specialflag";
+
private final static int SIZE = 4;
private static BinaryTree map = produceHash();
diff --git a/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java b/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
index b87e250696..bd7ede88f3 100644
--- a/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
+++ b/src/java/org/apache/poi/hssf/record/formula/AttrPtg.java
@@ -2,7 +2,7 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -144,6 +144,14 @@ public class AttrPtg
field_1_options=optiIf.setByteBoolean(field_1_options,bif);
}
+ /**
+ * Flags this ptg as a goto/jump
+ * @param isGoto
+ */
+ public void setGoto(boolean isGoto) {
+ field_1_options=optGoto.setByteBoolean(field_1_options, isGoto);
+ }
+
// lets hope no one uses this anymore
public boolean isBaxcel()
{
diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
index 833eabd8bc..6c82ec76f0 100644
--- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
+++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
@@ -1,3 +1,56 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ * "Apache POI" must not be used to endorse or promote products
+ * derived from this software without prior written permission. For
+ * written permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ * "Apache POI", nor may "Apache" appear in their name, without
+ * prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
package org.apache.poi.hssf.model;
import junit.framework.TestCase;
@@ -80,20 +133,95 @@ public class TestFormulaParser extends TestCase {
FormulaParser fp = new FormulaParser(yn, null);
fp.parse();
Ptg[] asts = fp.getRPNPtg();
- assertEquals(4, asts.length);
+ assertEquals(7, asts.length);
BoolPtg flag = (BoolPtg) asts[0];
- StringPtg y = (StringPtg) asts[1];
- StringPtg n = (StringPtg) asts[2];
- AttrPtg funif = (AttrPtg) asts[3];
+ AttrPtg funif = (AttrPtg) asts[1];
+ StringPtg y = (StringPtg) asts[2];
+ AttrPtg goto1 = (AttrPtg) asts[3];
+ StringPtg n = (StringPtg) asts[4];
+
assertEquals(true, flag.getValue());
assertEquals("Y", y.getValue());
assertEquals("N", n.getValue());
assertEquals("IF", funif.toFormulaString(new SheetReferences()));
+ assertTrue("Goto ptg exists", goto1.isGoto());
}
+ public void testSimpleIf() throws Exception {
+ final String simpleif = "IF(1=1,0,1)";
+ FormulaParser fp = new FormulaParser(simpleif, null);
+ fp.parse();
+ Ptg[] asts = fp.getRPNPtg();
+ assertEquals(9, asts.length);
+
+ IntPtg op1 = (IntPtg) asts[0];
+ IntPtg op2 = (IntPtg) asts[1];
+ EqualPtg eq = (EqualPtg) asts[2];
+ AttrPtg ifPtg = (AttrPtg) asts[3];
+ IntPtg res1 = (IntPtg) asts[4];
+
+ AttrPtg ptgGoto= (AttrPtg) asts[5];
+ assertEquals("Goto 1 Length", (short)10, ptgGoto.getData());
+
+ IntPtg res2 = (IntPtg) asts[6];
+ AttrPtg ptgGoto2 = (AttrPtg) asts[7];
+ assertEquals("Goto 2 Length", (short)3, ptgGoto2.getData());
+
+ assertEquals("If FALSE offset", (short)7, ifPtg.getData());
+
+ FuncVarPtg funcPtg = (FuncVarPtg)asts[8];
+
+
+ }
+ /**
+ * Make sure the ptgs are generated properly with two functions embedded
+ *
+ */
+ public void testNestedFunctionIf() {
+ String function = "IF(A1=B1,AVERAGE(A1:B1),AVERAGE(A2:B2))";
+
+ FormulaParser fp = new FormulaParser(function, null);
+ fp.parse();
+ Ptg[] asts = fp.getRPNPtg();
+ assertEquals("11 Ptgs expected", 11, asts.length);
+
+ assertTrue("IF Attr set correctly", (asts[3] instanceof AttrPtg));
+ AttrPtg ifFunc = (AttrPtg)asts[3];
+ assertTrue("It is not an if", ifFunc.isOptimizedIf());
+
+ assertTrue("Average Function set correctly", (asts[5] instanceof FuncVarPtg));
+
+
+ }
+
+ public void testIfSingleCondition(){
+ String function = "IF(1=1,10)";
+
+ FormulaParser fp = new FormulaParser(function, null);
+ fp.parse();
+ Ptg[] asts = fp.getRPNPtg();
+ assertEquals("7 Ptgs expected", 7, asts.length);
+
+ assertTrue("IF Attr set correctly", (asts[3] instanceof AttrPtg));
+ AttrPtg ifFunc = (AttrPtg)asts[3];
+ assertTrue("It is not an if", ifFunc.isOptimizedIf());
+
+ assertTrue("Single Value is not an IntPtg", (asts[4] instanceof IntPtg));
+ IntPtg intPtg = (IntPtg)asts[4];
+ assertEquals("Result", (short)10, intPtg.getValue());
+
+ assertTrue("Ptg is not a Variable Function", (asts[6] instanceof FuncVarPtg));
+ FuncVarPtg funcPtg = (FuncVarPtg)asts[6];
+ assertEquals("Arguments", 2, funcPtg.getNumberOfOperands());
+
+
+
+
+ }
+
public static void main(String [] args) {
System.out.println("Testing org.apache.poi.hssf.record.formula.FormulaParser");
junit.textui.TestRunner.run(TestFormulaParser.class);
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java
index 0df72a7349..bab97e1d22 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestFormulas.java
@@ -2,7 +2,7 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002 The Apache Software Foundation. All rights
+ * Copyright (c) 2002, 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -894,7 +894,7 @@ extends TestCase {
}
-/*
+
public void testIfFormulas()
throws java.io.IOException
{
@@ -935,9 +935,56 @@ extends TestCase {
assertTrue("expected: IF(A3=A1,\"A1\",\"A2\") got "+c.getCellFormula(), ("IF(A3=A1,\"A1\",\"A2\")").equals(c.getCellFormula()));
//c = r.getCell((short)1);
//assertTrue("expected: A!A1+A!B1 got: "+c.getCellFormula(), ("A!A1+A!B1").equals(c.getCellFormula()));
- in.close();
+ in.close();
+
+ File simpleIf = File.createTempFile("testSimpleIfFormulaWrite",".xls");
+ out = new FileOutputStream(simpleIf);
+ wb = new HSSFWorkbook();
+ s = wb.createSheet("Sheet1");
+ r = null;
+ c = null;
+ r = s.createRow((short)0);
+ c=r.createCell((short)0); c.setCellFormula("IF(1=1,0,1)");
+
+ wb.write(out);
+ out.close();
+ assertTrue("file exists", simpleIf.exists());
+
+ assertTrue("length of simpleIf file is zero", (simpleIf.length()>0));
+
+ File nestedIf = File.createTempFile("testNestedIfFormula",".xls");
+ out = new FileOutputStream(nestedIf);
+ wb = new HSSFWorkbook();
+ s = wb.createSheet("Sheet1");
+ r = null;
+ c = null;
+ r = s.createRow((short)0);
+ c=r.createCell((short)0);
+ c.setCellValue(1);
+
+ c=r.createCell((short)1);
+ c.setCellValue(3);
+
+
+ HSSFCell formulaCell=r.createCell((short)3);
+
+ r = s.createRow((short)1);
+ c=r.createCell((short)0);
+ c.setCellValue(3);
+
+ c=r.createCell((short)1);
+ c.setCellValue(7);
+
+ formulaCell.setCellFormula("IF(A1=B1,AVERAGE(A1:B1),AVERAGE(A2:B2))");
+
+
+ wb.write(out);
+ out.close();
+ assertTrue("file exists", nestedIf.exists());
+
+ assertTrue("length of nestedIf file is zero", (nestedIf.length()>0));
}
-*/
+
public static void main(String [] args) {
System.out