Partitioning common formula logic. Introduced FormulaRenderingWorkbook interface to make merge with ooxml branch easier
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@696813 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5f8442cba4
commit
c5a00d78c9
@ -97,7 +97,7 @@ public class FormulaViewer
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
if (token instanceof ExpPtg) return;
|
||||
buf.append(((OperationPtg) token).toFormulaString((HSSFWorkbook)null));
|
||||
buf.append(((OperationPtg) token).toFormulaString());
|
||||
buf.append(sep);
|
||||
switch (token.getPtgClass()) {
|
||||
case Ptg.CLASS_REF :
|
||||
@ -161,7 +161,7 @@ public class FormulaViewer
|
||||
Ptg[] tokens = record.getParsedExpression();
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
Ptg token = tokens[i];
|
||||
buf.append( token.toFormulaString((HSSFWorkbook)null));
|
||||
buf.append( token.toFormulaString());
|
||||
switch (token.getPtgClass()) {
|
||||
case Ptg.CLASS_REF :
|
||||
buf.append("(R)");
|
||||
|
@ -19,21 +19,53 @@ package org.apache.poi.hssf.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
//import PTGs .. since we need everything, import *
|
||||
import org.apache.poi.hssf.record.UnicodeString;
|
||||
import org.apache.poi.hssf.record.constant.ErrorConstant;
|
||||
import org.apache.poi.hssf.record.formula.*;
|
||||
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.ArrayPtg;
|
||||
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.ErrPtg;
|
||||
import org.apache.poi.hssf.record.formula.FuncPtg;
|
||||
import org.apache.poi.hssf.record.formula.FuncVarPtg;
|
||||
import org.apache.poi.hssf.record.formula.GreaterEqualPtg;
|
||||
import org.apache.poi.hssf.record.formula.GreaterThanPtg;
|
||||
import org.apache.poi.hssf.record.formula.IntPtg;
|
||||
import org.apache.poi.hssf.record.formula.LessEqualPtg;
|
||||
import org.apache.poi.hssf.record.formula.LessThanPtg;
|
||||
import org.apache.poi.hssf.record.formula.MissingArgPtg;
|
||||
import org.apache.poi.hssf.record.formula.MultiplyPtg;
|
||||
import org.apache.poi.hssf.record.formula.NamePtg;
|
||||
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||
import org.apache.poi.hssf.record.formula.NotEqualPtg;
|
||||
import org.apache.poi.hssf.record.formula.NumberPtg;
|
||||
import org.apache.poi.hssf.record.formula.ParenthesisPtg;
|
||||
import org.apache.poi.hssf.record.formula.PercentPtg;
|
||||
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.RefPtg;
|
||||
import org.apache.poi.hssf.record.formula.StringPtg;
|
||||
import org.apache.poi.hssf.record.formula.SubtractPtg;
|
||||
import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
|
||||
import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.AreaReference;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.util.CellReference.NameType;
|
||||
import org.apache.poi.ss.formula.FormulaRenderer;
|
||||
|
||||
/**
|
||||
* This class parses a formula string into a List of tokens in RPN order.
|
||||
@ -1001,94 +1033,6 @@ end;
|
||||
* @return a human readable String
|
||||
*/
|
||||
public static String toFormulaString(HSSFWorkbook book, Ptg[] ptgs) {
|
||||
if (ptgs == null || ptgs.length == 0) {
|
||||
// TODO - what is the justification for returning "#NAME" (which is not "#NAME?", btw)
|
||||
return "#NAME";
|
||||
}
|
||||
Stack stack = new Stack();
|
||||
|
||||
for (int i=0 ; i < ptgs.length; i++) {
|
||||
Ptg ptg = ptgs[i];
|
||||
// TODO - what about MemNoMemPtg?
|
||||
if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {
|
||||
// marks the start of a list of area expressions which will be naturally combined
|
||||
// by their trailing operators (e.g. UnionPtg)
|
||||
// TODO - put comment and throw exception in toFormulaString() of these classes
|
||||
continue;
|
||||
}
|
||||
if (ptg instanceof ParenthesisPtg) {
|
||||
String contents = (String)stack.pop();
|
||||
stack.push ("(" + contents + ")");
|
||||
continue;
|
||||
}
|
||||
if (ptg instanceof AttrPtg) {
|
||||
AttrPtg attrPtg = ((AttrPtg) ptg);
|
||||
if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {
|
||||
continue;
|
||||
}
|
||||
if (attrPtg.isSpace()) {
|
||||
// POI currently doesn't render spaces in formulas
|
||||
continue;
|
||||
// but if it ever did, care must be taken:
|
||||
// tAttrSpace comes *before* the operand it applies to, which may be consistent
|
||||
// with how the formula text appears but is against the RPN ordering assumed here
|
||||
}
|
||||
if (attrPtg.isSemiVolatile()) {
|
||||
// similar to tAttrSpace - RPN is violated
|
||||
continue;
|
||||
}
|
||||
if (attrPtg.isSum()) {
|
||||
String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());
|
||||
stack.push(attrPtg.toFormulaString(operands));
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());
|
||||
}
|
||||
|
||||
if (! (ptg instanceof OperationPtg)) {
|
||||
stack.push(ptg.toFormulaString(book));
|
||||
continue;
|
||||
}
|
||||
|
||||
OperationPtg o = (OperationPtg) ptg;
|
||||
String[] operands = getOperands(stack, o.getNumberOfOperands());
|
||||
stack.push(o.toFormulaString(operands));
|
||||
}
|
||||
if(stack.isEmpty()) {
|
||||
// inspection of the code above reveals that every stack.pop() is followed by a
|
||||
// stack.push(). So this is either an internal error or impossible.
|
||||
throw new IllegalStateException("Stack underflow");
|
||||
}
|
||||
String result = (String) stack.pop();
|
||||
if(!stack.isEmpty()) {
|
||||
// Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't
|
||||
// put anything on the stack
|
||||
throw new IllegalStateException("too much stuff left on the stack");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String[] getOperands(Stack stack, int nOperands) {
|
||||
String[] operands = new String[nOperands];
|
||||
|
||||
for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order
|
||||
if(stack.isEmpty()) {
|
||||
String msg = "Too few arguments supplied to operation. Expected (" + nOperands
|
||||
+ ") operands but got (" + (nOperands - j - 1) + ")";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
operands[j] = (String) stack.pop();
|
||||
}
|
||||
return operands;
|
||||
}
|
||||
/**
|
||||
* Static method to convert an array of Ptgs in RPN order
|
||||
* to a human readable string format in infix mode. Works
|
||||
* on the current workbook for named and 3D references.
|
||||
* @param ptgs array of Ptg, can be null or empty
|
||||
* @return a human readable String
|
||||
*/
|
||||
public String toFormulaString(Ptg[] ptgs) {
|
||||
return toFormulaString(book, ptgs);
|
||||
return FormulaRenderer.toFormulaString(HSSFEvaluationWorkbook.create(book), ptgs);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadata;
|
||||
import org.apache.poi.hssf.record.formula.function.FunctionMetadataRegistry;
|
||||
|
||||
@ -71,7 +70,7 @@ public abstract class AbstractFunctionPtg extends OperationPtg {
|
||||
return field_2_fnc_index == FUNCTION_INDEX_EXTERNAL;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -45,7 +44,7 @@ public abstract class Area2DPtgBase extends AreaPtgBase {
|
||||
public final int getSize() {
|
||||
return SIZE;
|
||||
}
|
||||
public final String toFormulaString(HSSFWorkbook book) {
|
||||
public final String toFormulaString() {
|
||||
return formatReferenceAsString();
|
||||
}
|
||||
public final String toString() {
|
||||
|
@ -19,6 +19,8 @@ package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.WorkbookDependentFormula;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -30,7 +32,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
public final class Area3DPtg extends AreaPtgBase {
|
||||
public final class Area3DPtg extends AreaPtgBase implements WorkbookDependentFormula {
|
||||
public final static byte sid = 0x3b;
|
||||
private final static int SIZE = 11; // 10 + 1 for Ptg
|
||||
|
||||
@ -87,7 +89,10 @@ public final class Area3DPtg extends AreaPtgBase {
|
||||
* @return text representation of this area reference that can be used in text
|
||||
* formulas. The sheet name will get properly delimited if required.
|
||||
*/
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString(FormulaRenderingWorkbook book) {
|
||||
return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
|
||||
}
|
||||
public String toFormulaString() {
|
||||
throw new RuntimeException("3D references need a workbook to determine formula text");
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -49,7 +48,7 @@ public final class AreaErrPtg extends OperandPtg {
|
||||
LittleEndian.putInt(array, offset + 5, unused2);
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString() {
|
||||
return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
|
||||
}
|
||||
|
||||
|
@ -17,14 +17,12 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.util.AreaReference;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* Specifies a rectangular area of cells A1:A4 for instance.
|
||||
@ -269,7 +267,7 @@ public abstract class AreaPtgBase extends OperandPtg implements AreaI {
|
||||
return topLeft.formatAsString() + ":" + botRight.formatAsString();
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString() {
|
||||
return formatReferenceAsString();
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ public final class ArrayPtg extends Ptg {
|
||||
+ ConstantValueParser.getEncodedSize(token_3_arrayValues);
|
||||
}
|
||||
|
||||
public String formatAsString() {
|
||||
public String formatAsString() { // TODO - fold into toFormulaString
|
||||
StringBuffer b = new StringBuffer();
|
||||
b.append("{");
|
||||
for (int y=0;y<getRowCount();y++) {
|
||||
@ -202,7 +202,7 @@ public final class ArrayPtg extends Ptg {
|
||||
b.append("}");
|
||||
return b.toString();
|
||||
}
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString() {
|
||||
return formatAsString();
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,10 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* "Special Attributes"
|
||||
@ -244,11 +242,11 @@ public final class AttrPtg extends ControlPtg {
|
||||
if(space.isSet(field_1_options)) {
|
||||
return operands[ 0 ];
|
||||
} else if (optiIf.isSet(field_1_options)) {
|
||||
return toFormulaString((HSSFWorkbook)null) + "(" + operands[ 0 ] +")";
|
||||
return toFormulaString() + "(" + operands[ 0 ] +")";
|
||||
} else if (optGoto.isSet(field_1_options)) {
|
||||
return toFormulaString((HSSFWorkbook)null) + operands[0]; //goto isn't a real formula element should not show up
|
||||
return toFormulaString() + operands[0]; //goto isn't a real formula element should not show up
|
||||
} else {
|
||||
return toFormulaString((HSSFWorkbook)null) + "(" + operands[ 0 ] + ")";
|
||||
return toFormulaString() + "(" + operands[ 0 ] + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +261,7 @@ public final class AttrPtg extends ControlPtg {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString() {
|
||||
if(semiVolatile.isSet(field_1_options)) {
|
||||
return "ATTR(semiVolatile)";
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public final class BoolPtg extends ScalarConstantPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
protected String toFormulaString() {
|
||||
public String toFormulaString() {
|
||||
return _value ? "TRUE" : "FALSE";
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.WorkbookDependentFormula;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -29,7 +30,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
* @author Patrick Luby
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
public final class DeletedArea3DPtg extends OperandPtg {
|
||||
public final class DeletedArea3DPtg extends OperandPtg implements WorkbookDependentFormula {
|
||||
public final static byte sid = 0x3d;
|
||||
private final int field_1_index_extern_sheet;
|
||||
private final int unused1;
|
||||
@ -46,10 +47,13 @@ public final class DeletedArea3DPtg extends OperandPtg {
|
||||
unused1 = in.readInt();
|
||||
unused2 = in.readInt();
|
||||
}
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString(FormulaRenderingWorkbook book) {
|
||||
return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet,
|
||||
HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF));
|
||||
}
|
||||
public String toFormulaString() {
|
||||
throw new RuntimeException("3D references need a workbook to determine formula text");
|
||||
}
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_REF;
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.WorkbookDependentFormula;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -30,7 +31,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
* @author Patrick Luby
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
public final class DeletedRef3DPtg extends OperandPtg {
|
||||
public final class DeletedRef3DPtg extends OperandPtg implements WorkbookDependentFormula {
|
||||
public final static byte sid = 0x3c;
|
||||
private final int field_1_index_extern_sheet;
|
||||
private final int unused1;
|
||||
@ -46,10 +47,13 @@ public final class DeletedRef3DPtg extends OperandPtg {
|
||||
unused1 = 0;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString(FormulaRenderingWorkbook book) {
|
||||
return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet,
|
||||
HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF));
|
||||
}
|
||||
public String toFormulaString() {
|
||||
throw new RuntimeException("3D references need a workbook to determine formula text");
|
||||
}
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_REF;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public final class ErrPtg extends ScalarConstantPtg {
|
||||
array[offset + 1] = (byte)field_1_error_code;
|
||||
}
|
||||
|
||||
protected String toFormulaString() {
|
||||
public String toFormulaString() {
|
||||
return HSSFErrorConstants.getText(field_1_error_code);
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordFormatException;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -61,7 +59,7 @@ public final class ExpPtg extends ControlPtg {
|
||||
return field_2_first_col;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
throw new RecordFormatException("Coding Error: Expected ExpPtg to be converted from Shared to Non-Shared Formula by ValueRecordsAggregate, but it wasn't");
|
||||
}
|
||||
|
@ -17,8 +17,7 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
|
||||
/**
|
||||
* @author Josh Micich
|
||||
@ -29,8 +28,8 @@ final class ExternSheetNameResolver {
|
||||
// no instances of this class
|
||||
}
|
||||
|
||||
public static String prependSheetName(HSSFWorkbook book, int field_1_index_extern_sheet, String cellRefText) {
|
||||
String sheetName = book.findSheetNameFromExternSheet(field_1_index_extern_sheet);
|
||||
public static String prependSheetName(FormulaRenderingWorkbook book, int field_1_index_extern_sheet, String cellRefText) {
|
||||
String sheetName = book.getSheetNameByExternSheet(field_1_index_extern_sheet);
|
||||
StringBuffer sb = new StringBuffer(sheetName.length() + cellRefText.length() + 4);
|
||||
if (sheetName.length() < 1) {
|
||||
// What excel does if sheet has been deleted
|
||||
|
@ -68,7 +68,7 @@ public final class IntPtg extends ScalarConstantPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
protected String toFormulaString() {
|
||||
public String toFormulaString() {
|
||||
return String.valueOf(getValue());
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* @author Daniel Noll (daniel at nuix dot com dot au)
|
||||
@ -46,7 +45,7 @@ public final class IntersectionPtg extends OperationPtg {
|
||||
}
|
||||
|
||||
/** Implementation of method from Ptg */
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return " ";
|
||||
}
|
||||
|
@ -17,9 +17,8 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* @author Daniel Noll (daniel at nuix dot com dot au)
|
||||
@ -74,7 +73,7 @@ public class MemAreaPtg extends OperandPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return ""; // TODO: Not sure how to format this. -- DN
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public final class MemErrPtg extends MemAreaPtg {
|
||||
array[offset] = (byte) (sid + getPtgClass());
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return "ERR#";
|
||||
}
|
||||
|
@ -17,9 +17,8 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
@ -51,7 +50,7 @@ public final class MemFuncPtg extends OperandPtg {
|
||||
LittleEndian.putUShort( array, offset + 1, field_1_len_ref_subexpression );
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public final class MissingArgPtg extends ScalarConstantPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
protected String toFormulaString() {
|
||||
public String toFormulaString() {
|
||||
return " ";
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,8 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.formula.WorkbookDependentFormula;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -27,7 +27,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
* @author andy
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
*/
|
||||
public final class NamePtg extends OperandPtg {
|
||||
public final class NamePtg extends OperandPtg implements WorkbookDependentFormula {
|
||||
public final static short sid = 0x23;
|
||||
private final static int SIZE = 5;
|
||||
/** one-based index to defined name record */
|
||||
@ -65,10 +65,13 @@ public final class NamePtg extends OperandPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString(FormulaRenderingWorkbook book)
|
||||
{
|
||||
return book.getNameName(field_1_label_index - 1);
|
||||
return book.getNameText(this);
|
||||
}
|
||||
public String toFormulaString() {
|
||||
throw new RuntimeException("3D references need a workbook to determine formula text");
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_REF;
|
||||
|
@ -17,15 +17,16 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.ss.formula.WorkbookDependentFormula;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aviks
|
||||
*/
|
||||
public final class NameXPtg extends OperandPtg {
|
||||
public final class NameXPtg extends OperandPtg implements WorkbookDependentFormula {
|
||||
public final static short sid = 0x39;
|
||||
private final static int SIZE = 7;
|
||||
|
||||
@ -65,9 +66,12 @@ public final class NameXPtg extends OperandPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString(FormulaRenderingWorkbook book) {
|
||||
// -1 to convert definedNameIndex from 1-based to zero-based
|
||||
return book.resolveNameXText(_sheetRefIndex, _nameNumber - 1);
|
||||
return book.resolveNameXText(this);
|
||||
}
|
||||
public String toFormulaString() {
|
||||
throw new RuntimeException("3D references need a workbook to determine formula text");
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
|
@ -63,7 +63,7 @@ public final class NumberPtg extends ScalarConstantPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
protected String toFormulaString() {
|
||||
public String toFormulaString() {
|
||||
// TODO - java's rendering of double values is not quite same as excel's
|
||||
return String.valueOf(field_1_value);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
|
||||
/**
|
||||
* @author Josh Micich
|
||||
*/
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
|
||||
/**
|
||||
* defines a Ptg that is an operation instead of an operand
|
||||
* @author andy
|
||||
@ -46,5 +48,10 @@ public abstract class OperationPtg extends Ptg {
|
||||
// TODO remove "int getType();" from Eval hierarchy
|
||||
throw new RuntimeException("remove this method");
|
||||
}
|
||||
|
||||
public String toFormulaString(FormulaRenderingWorkbook book) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,10 +18,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
/**
|
||||
* While formula tokens are stored in RPN order and thus do not need parenthesis for
|
||||
@ -52,7 +48,7 @@ public final class ParenthesisPtg extends ControlPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return "()";
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ public abstract class Ptg implements Cloneable {
|
||||
/**
|
||||
* return a string representation of this token alone
|
||||
*/
|
||||
public abstract String toFormulaString(HSSFWorkbook book);
|
||||
public abstract String toFormulaString();
|
||||
/**
|
||||
* dump a debug representation (hexdump) to a string
|
||||
*/
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* @author Daniel Noll (daniel at nuix dot com dot au)
|
||||
@ -46,7 +45,7 @@ public final class RangePtg extends OperationPtg {
|
||||
array[ offset + 0 ] = sid;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return ":";
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -49,7 +48,7 @@ abstract class Ref2DPtgBase extends RefPtgBase {
|
||||
LittleEndian.putByte(array, offset+0, getSid() + getPtgClass());
|
||||
writeCoordinates(array, offset+1);
|
||||
}
|
||||
public final String toFormulaString(HSSFWorkbook book) {
|
||||
public final String toFormulaString() {
|
||||
return formatReferenceAsString();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ package org.apache.poi.hssf.record.formula;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.CellReference;
|
||||
import org.apache.poi.ss.formula.WorkbookDependentFormula;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -30,7 +32,7 @@ import org.apache.poi.util.LittleEndian;
|
||||
* @author Jason Height (jheight at chariot dot net dot au)
|
||||
* @version 1.0-pre
|
||||
*/
|
||||
public final class Ref3DPtg extends RefPtgBase {
|
||||
public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula {
|
||||
public final static byte sid = 0x3a;
|
||||
|
||||
private final static int SIZE = 7; // 6 + 1 for Ptg
|
||||
@ -86,7 +88,10 @@ public final class Ref3DPtg extends RefPtgBase {
|
||||
* @return text representation of this cell reference that can be used in text
|
||||
* formulas. The sheet name will get properly delimited if required.
|
||||
*/
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString(FormulaRenderingWorkbook book) {
|
||||
return ExternSheetNameResolver.prependSheetName(book, field_1_index_extern_sheet, formatReferenceAsString());
|
||||
}
|
||||
public String toFormulaString() {
|
||||
throw new RuntimeException("3D references need a workbook to determine formula text");
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public final class RefErrorPtg extends OperandPtg {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book) {
|
||||
public String toFormulaString() {
|
||||
return HSSFErrorConstants.getText(HSSFErrorConstants.ERROR_REF);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* @author Josh Micich
|
||||
@ -31,12 +30,6 @@ abstract class ScalarConstantPtg extends Ptg {
|
||||
return Ptg.CLASS_VALUE;
|
||||
}
|
||||
|
||||
public final String toFormulaString(HSSFWorkbook book) {
|
||||
return toFormulaString();
|
||||
}
|
||||
|
||||
protected abstract String toFormulaString();
|
||||
|
||||
public final String toString() {
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
sb.append(getClass().getName()).append(" [");
|
||||
|
@ -97,7 +97,7 @@ public final class StringPtg extends ScalarConstantPtg {
|
||||
}
|
||||
}
|
||||
|
||||
protected String toFormulaString() {
|
||||
public String toFormulaString() {
|
||||
String value = field_3_string;
|
||||
int len = value.length();
|
||||
StringBuffer sb = new StringBuffer(len + 4);
|
||||
|
@ -17,10 +17,8 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordFormatException;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
import org.apache.poi.util.LittleEndian;
|
||||
|
||||
/**
|
||||
@ -68,7 +66,7 @@ public final class TblPtg extends ControlPtg {
|
||||
return field_2_first_col;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
// table(....)[][]
|
||||
throw new RecordFormatException("Table and Arrays are not yet supported");
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* @author Glen Stampoultzis (glens at apache.org)
|
||||
@ -45,7 +44,7 @@ public final class UnionPtg extends OperationPtg {
|
||||
array[ offset + 0 ] = sid;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return ",";
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
==================================================================== */
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.record.RecordInputStream;
|
||||
|
||||
/**
|
||||
@ -49,7 +48,7 @@ public class UnknownPtg extends Ptg {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String toFormulaString(HSSFWorkbook book)
|
||||
public String toFormulaString()
|
||||
{
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public abstract class ValueOperatorPtg extends OperationPtg {
|
||||
public final int getSize() {
|
||||
return 1;
|
||||
}
|
||||
public final String toFormulaString(HSSFWorkbook book) {
|
||||
public final String toFormulaString() {
|
||||
// TODO - prune this method out of the hierarchy
|
||||
throw new RuntimeException("toFormulaString(String[] operands) should be used for subclasses of OperationPtgs");
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
package org.apache.poi.hssf.usermodel;
|
||||
|
||||
import org.apache.poi.hssf.model.Workbook;
|
||||
import org.apache.poi.hssf.record.formula.NamePtg;
|
||||
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||
|
||||
/**
|
||||
* Internal POI use only
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook {
|
||||
|
||||
private final Workbook _iBook;
|
||||
|
||||
public static HSSFEvaluationWorkbook create(HSSFWorkbook book) {
|
||||
if (book == null) {
|
||||
return null;
|
||||
}
|
||||
return new HSSFEvaluationWorkbook(book);
|
||||
}
|
||||
|
||||
private HSSFEvaluationWorkbook(HSSFWorkbook book) {
|
||||
_iBook = book.getWorkbook();
|
||||
}
|
||||
|
||||
public String resolveNameXText(NameXPtg n) {
|
||||
return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
|
||||
}
|
||||
|
||||
public String getSheetNameByExternSheet(int externSheetIndex) {
|
||||
return _iBook.findSheetNameFromExternSheet(externSheetIndex);
|
||||
}
|
||||
public String getNameText(NamePtg namePtg) {
|
||||
return _iBook.getNameRecord(namePtg.getIndex()).getNameText();
|
||||
}
|
||||
}
|
124
src/java/org/apache/poi/ss/formula/FormulaRenderer.java
Normal file
124
src/java/org/apache/poi/ss/formula/FormulaRenderer.java
Normal file
@ -0,0 +1,124 @@
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.AttrPtg;
|
||||
import org.apache.poi.hssf.record.formula.MemAreaPtg;
|
||||
import org.apache.poi.hssf.record.formula.MemErrPtg;
|
||||
import org.apache.poi.hssf.record.formula.MemFuncPtg;
|
||||
import org.apache.poi.hssf.record.formula.OperationPtg;
|
||||
import org.apache.poi.hssf.record.formula.ParenthesisPtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
|
||||
public class FormulaRenderer {
|
||||
/**
|
||||
* Convenience method which takes in a list then passes it to the
|
||||
* other toFormulaString signature.
|
||||
* @param book workbook for 3D and named references
|
||||
* @param lptgs list of Ptg, can be null or empty
|
||||
* @return a human readable String
|
||||
*/
|
||||
public static String toFormulaString(FormulaRenderingWorkbook book, List lptgs) {
|
||||
String retval = null;
|
||||
if (lptgs == null || lptgs.size() == 0) return "#NAME";
|
||||
Ptg[] ptgs = new Ptg[lptgs.size()];
|
||||
ptgs = (Ptg[])lptgs.toArray(ptgs);
|
||||
retval = toFormulaString(book, ptgs);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method to convert an array of Ptgs in RPN order
|
||||
* to a human readable string format in infix mode.
|
||||
* @param book workbook for named and 3D references
|
||||
* @param ptgs array of Ptg, can be null or empty
|
||||
* @return a human readable String
|
||||
*/
|
||||
public static String toFormulaString(FormulaRenderingWorkbook book, Ptg[] ptgs) {
|
||||
if (ptgs == null || ptgs.length == 0) {
|
||||
// TODO - what is the justification for returning "#NAME" (which is not "#NAME?", btw)
|
||||
return "#NAME";
|
||||
}
|
||||
Stack stack = new Stack();
|
||||
|
||||
for (int i=0 ; i < ptgs.length; i++) {
|
||||
Ptg ptg = ptgs[i];
|
||||
// TODO - what about MemNoMemPtg?
|
||||
if(ptg instanceof MemAreaPtg || ptg instanceof MemFuncPtg || ptg instanceof MemErrPtg) {
|
||||
// marks the start of a list of area expressions which will be naturally combined
|
||||
// by their trailing operators (e.g. UnionPtg)
|
||||
// TODO - put comment and throw exception in toFormulaString() of these classes
|
||||
continue;
|
||||
}
|
||||
if (ptg instanceof ParenthesisPtg) {
|
||||
String contents = (String)stack.pop();
|
||||
stack.push ("(" + contents + ")");
|
||||
continue;
|
||||
}
|
||||
if (ptg instanceof AttrPtg) {
|
||||
AttrPtg attrPtg = ((AttrPtg) ptg);
|
||||
if (attrPtg.isOptimizedIf() || attrPtg.isOptimizedChoose() || attrPtg.isGoto()) {
|
||||
continue;
|
||||
}
|
||||
if (attrPtg.isSpace()) {
|
||||
// POI currently doesn't render spaces in formulas
|
||||
continue;
|
||||
// but if it ever did, care must be taken:
|
||||
// tAttrSpace comes *before* the operand it applies to, which may be consistent
|
||||
// with how the formula text appears but is against the RPN ordering assumed here
|
||||
}
|
||||
if (attrPtg.isSemiVolatile()) {
|
||||
// similar to tAttrSpace - RPN is violated
|
||||
continue;
|
||||
}
|
||||
if (attrPtg.isSum()) {
|
||||
String[] operands = getOperands(stack, attrPtg.getNumberOfOperands());
|
||||
stack.push(attrPtg.toFormulaString(operands));
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException("Unexpected tAttr: " + attrPtg.toString());
|
||||
}
|
||||
|
||||
if (ptg instanceof WorkbookDependentFormula) {
|
||||
WorkbookDependentFormula optg = (WorkbookDependentFormula) ptg;
|
||||
stack.push(optg.toFormulaString(book));
|
||||
continue;
|
||||
}
|
||||
if (! (ptg instanceof OperationPtg)) {
|
||||
stack.push(ptg.toFormulaString());
|
||||
continue;
|
||||
}
|
||||
|
||||
OperationPtg o = (OperationPtg) ptg;
|
||||
String[] operands = getOperands(stack, o.getNumberOfOperands());
|
||||
stack.push(o.toFormulaString(operands));
|
||||
}
|
||||
if(stack.isEmpty()) {
|
||||
// inspection of the code above reveals that every stack.pop() is followed by a
|
||||
// stack.push(). So this is either an internal error or impossible.
|
||||
throw new IllegalStateException("Stack underflow");
|
||||
}
|
||||
String result = (String) stack.pop();
|
||||
if(!stack.isEmpty()) {
|
||||
// Might be caused by some tokens like AttrPtg and Mem*Ptg, which really shouldn't
|
||||
// put anything on the stack
|
||||
throw new IllegalStateException("too much stuff left on the stack");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String[] getOperands(Stack stack, int nOperands) {
|
||||
String[] operands = new String[nOperands];
|
||||
|
||||
for (int j = nOperands-1; j >= 0; j--) { // reverse iteration because args were pushed in-order
|
||||
if(stack.isEmpty()) {
|
||||
String msg = "Too few arguments supplied to operation. Expected (" + nOperands
|
||||
+ ") operands but got (" + (nOperands - j - 1) + ")";
|
||||
throw new IllegalStateException(msg);
|
||||
}
|
||||
operands[j] = (String) stack.pop();
|
||||
}
|
||||
return operands;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
import org.apache.poi.hssf.record.formula.NamePtg;
|
||||
import org.apache.poi.hssf.record.formula.NameXPtg;
|
||||
|
||||
public interface FormulaRenderingWorkbook {
|
||||
|
||||
String getSheetNameByExternSheet(int externSheetIndex);
|
||||
String resolveNameXText(NameXPtg nameXPtg);
|
||||
String getNameText(NamePtg namePtg);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
public interface WorkbookDependentFormula {
|
||||
String toFormulaString(FormulaRenderingWorkbook book);
|
||||
}
|
29
src/java/org/apache/poi/ss/formula/package.html
Normal file
29
src/java/org/apache/poi/ss/formula/package.html
Normal file
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!--
|
||||
====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
====================================================================
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
|
||||
This package contains common internal POI code for manipulating formulas.
|
||||
Client applications should not refer to these classes directly.
|
||||
|
||||
</body>
|
||||
</html>
|
@ -32,6 +32,7 @@ import org.apache.poi.hssf.record.FormulaRecord;
|
||||
import org.apache.poi.hssf.record.Record;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.Ref3DPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
/**
|
||||
@ -110,7 +111,8 @@ public final class TestEventWorkbookBuilder extends TestCase {
|
||||
assertTrue(ptgs[0] instanceof Ref3DPtg);
|
||||
|
||||
Ref3DPtg ptg = (Ref3DPtg)ptgs[0];
|
||||
assertEquals("Sheet1!A1", ptg.toFormulaString(stubHSSF));
|
||||
HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(stubHSSF);
|
||||
assertEquals("Sheet1!A1", ptg.toFormulaString(book));
|
||||
|
||||
|
||||
// Now check we get the right formula back for
|
||||
|
@ -51,6 +51,7 @@ import org.apache.poi.hssf.record.formula.UnaryMinusPtg;
|
||||
import org.apache.poi.hssf.record.formula.UnaryPlusPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
@ -130,13 +131,14 @@ public final class TestFormulaParser extends TestCase {
|
||||
public void testMacroFunction() {
|
||||
// testNames.xls contains a VB function called 'myFunc'
|
||||
HSSFWorkbook w = HSSFTestDataSamples.openSampleWorkbook("testNames.xls");
|
||||
HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(w);
|
||||
|
||||
Ptg[] ptg = FormulaParser.parse("myFunc()", w);
|
||||
// myFunc() actually takes 1 parameter. Don't know if POI will ever be able to detect this problem
|
||||
|
||||
// the name gets encoded as the first arg
|
||||
NamePtg tname = (NamePtg) ptg[0];
|
||||
assertEquals("myFunc", tname.toFormulaString(w));
|
||||
assertEquals("myFunc", tname.toFormulaString(book));
|
||||
|
||||
AbstractFunctionPtg tfunc = (AbstractFunctionPtg) ptg[1];
|
||||
assertTrue(tfunc.isExternalFunction());
|
||||
@ -871,7 +873,7 @@ public final class TestFormulaParser extends TestCase {
|
||||
assertEquals(2, ptgs.length);
|
||||
Ptg ptg0 = ptgs[0];
|
||||
assertEquals(ArrayPtg.class, ptg0.getClass());
|
||||
assertEquals("{1.0,2.0,2.0,#REF!;FALSE,3.0,3.0,2.0}", ptg0.toFormulaString(null));
|
||||
assertEquals("{1.0,2.0,2.0,#REF!;FALSE,3.0,3.0,2.0}", ptg0.toFormulaString());
|
||||
|
||||
ArrayPtg aptg = (ArrayPtg) ptg0;
|
||||
Object[][] values = aptg.getTokenArrayValues();
|
||||
|
@ -33,7 +33,6 @@ import org.apache.poi.hssf.record.formula.NotEqualPtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.RefPtg;
|
||||
import org.apache.poi.hssf.record.formula.StringPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* Tests <tt>FormulaParser</tt> specifically with respect to IF() functions
|
||||
@ -202,7 +201,7 @@ public final class TestFormulaParserIf extends TestCase {
|
||||
assertEquals(true, flag.getValue());
|
||||
assertEquals("Y", y.getValue());
|
||||
assertEquals("N", n.getValue());
|
||||
assertEquals("IF", funif.toFormulaString((HSSFWorkbook) null));
|
||||
assertEquals("IF", funif.toFormulaString());
|
||||
assertTrue("Goto ptg exists", goto1.isGoto());
|
||||
}
|
||||
/**
|
||||
|
@ -66,7 +66,7 @@ public final class TestSharedFormulaRecord extends TestCase {
|
||||
Ptg[] convertedFormula = SharedFormulaRecord.convertSharedFormulas(sharedFormula, 100, 200);
|
||||
|
||||
RefPtg refPtg = (RefPtg) convertedFormula[1];
|
||||
assertEquals("$C101", refPtg.toFormulaString(null));
|
||||
assertEquals("$C101", refPtg.toFormulaString());
|
||||
if (refPtg.getPtgClass() == Ptg.CLASS_REF) {
|
||||
throw new AssertionFailedError("Identified bug 45123");
|
||||
}
|
||||
|
@ -14,10 +14,10 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
@ -27,21 +27,22 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
*/
|
||||
public final class TestArea3DPtg extends AbstractPtgTestCase {
|
||||
|
||||
/**
|
||||
* confirms that sheet names get properly escaped
|
||||
*/
|
||||
/**
|
||||
* confirms that sheet names get properly escaped
|
||||
*/
|
||||
public void testToFormulaString() {
|
||||
|
||||
|
||||
Area3DPtg target = new Area3DPtg("A1:B1", (short)0);
|
||||
|
||||
|
||||
String sheetName = "my sheet";
|
||||
HSSFWorkbook book = createWorkbookWithSheet(sheetName);
|
||||
HSSFWorkbook wb = createWorkbookWithSheet(sheetName);
|
||||
HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(wb);
|
||||
assertEquals("'my sheet'!A1:B1", target.toFormulaString(book));
|
||||
|
||||
book.setSheetName(0, "Sheet1");
|
||||
assertEquals("Sheet1!A1:B1", target.toFormulaString(book));
|
||||
|
||||
book.setSheetName(0, "C64");
|
||||
assertEquals("'C64'!A1:B1", target.toFormulaString(book));
|
||||
|
||||
wb.setSheetName(0, "Sheet1");
|
||||
assertEquals("Sheet1!A1:B1", target.toFormulaString(book));
|
||||
|
||||
wb.setSheetName(0, "C64");
|
||||
assertEquals("'C64'!A1:B1", target.toFormulaString(book));
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.apache.poi.hssf.record.formula;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.poi.hssf.model.FormulaParser;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
* Tests for {@link AreaPtg}.
|
||||
@ -83,14 +84,10 @@ public final class TestAreaPtg extends TestCase {
|
||||
assertEquals("Relative references changed", expectedFormula2, newFormula2);
|
||||
}
|
||||
|
||||
private String shiftAllColumnsBy1(String formula)
|
||||
{
|
||||
private static String shiftAllColumnsBy1(String formula) {
|
||||
int letUsShiftColumn1By1Column=1;
|
||||
|
||||
FormulaParser parser = new FormulaParser(formula,null);
|
||||
parser.parse();
|
||||
|
||||
final Ptg[] ptgs = parser.getRPNPtg();
|
||||
HSSFWorkbook wb = null;
|
||||
Ptg[] ptgs = FormulaParser.parse(formula, wb);
|
||||
for(int i=0; i<ptgs.length; i++)
|
||||
{
|
||||
Ptg ptg = ptgs[i];
|
||||
@ -101,10 +98,7 @@ public final class TestAreaPtg extends TestCase {
|
||||
aptg.setLastColumn((short)(aptg.getLastColumn()+letUsShiftColumn1By1Column));
|
||||
}
|
||||
}
|
||||
String newFormula = parser.toFormulaString(ptgs);
|
||||
String newFormula = FormulaParser.toFormulaString(wb, ptgs);
|
||||
return newFormula;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ public final class TestArrayPtg extends TestCase {
|
||||
|
||||
String actualFormula;
|
||||
try {
|
||||
actualFormula = ptg.toFormulaString(null);
|
||||
actualFormula = ptg.toFormulaString();
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (e.getMessage().equals("Unexpected constant class (java.lang.Boolean)")) {
|
||||
throw new AssertionFailedError("Identified bug 45380");
|
||||
|
@ -14,10 +14,10 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
|
||||
package org.apache.poi.hssf.record.formula;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
/**
|
||||
@ -28,17 +28,17 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
public final class TestRef3DPtg extends AbstractPtgTestCase {
|
||||
|
||||
public void testToFormulaString() {
|
||||
|
||||
|
||||
Ref3DPtg target = new Ref3DPtg("A1", (short)0);
|
||||
|
||||
HSSFWorkbook book = createWorkbookWithSheet("my sheet");
|
||||
|
||||
|
||||
HSSFWorkbook wb = createWorkbookWithSheet("my sheet");
|
||||
HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(wb);
|
||||
assertEquals("'my sheet'!A1", target.toFormulaString(book));
|
||||
|
||||
book.setSheetName(0, "ProfitAndLoss");
|
||||
assertEquals("ProfitAndLoss!A1", target.toFormulaString(book));
|
||||
|
||||
book.setSheetName(0, "profit+loss");
|
||||
assertEquals("'profit+loss'!A1", target.toFormulaString(book));
|
||||
wb.setSheetName(0, "ProfitAndLoss");
|
||||
assertEquals("ProfitAndLoss!A1", target.toFormulaString(book));
|
||||
|
||||
wb.setSheetName(0, "profit+loss");
|
||||
assertEquals("'profit+loss'!A1", target.toFormulaString(book));
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
||||
assertEquals(2, ptg.getLastColumn());
|
||||
assertEquals(0, ptg.getFirstRow());
|
||||
assertEquals(65535, ptg.getLastRow());
|
||||
assertEquals("C:C", ptg.toFormulaString(wb));
|
||||
assertEquals("C:C", ptg.toFormulaString());
|
||||
|
||||
// Will show as C:C, but won't know how many
|
||||
// rows it covers as we don't have the sheet
|
||||
@ -316,6 +316,7 @@ public final class TestFormulaEvaluatorBugs extends TestCase {
|
||||
evaluator.evaluate(cell);
|
||||
int evalCount = evaluator.getEvaluationCount();
|
||||
// With caching, the evaluationCount is 8 which is a big improvement
|
||||
assertTrue(evalCount > 0); // make sure the counter is actually working
|
||||
if (evalCount > 10) {
|
||||
// Without caching, evaluating cell 'A9' takes 21845 evaluations which consumes
|
||||
// much time (~3 sec on Core 2 Duo 2.2GHz)
|
||||
|
@ -30,6 +30,7 @@ import org.apache.poi.hssf.record.formula.MemFuncPtg;
|
||||
import org.apache.poi.hssf.record.formula.Ptg;
|
||||
import org.apache.poi.hssf.record.formula.UnionPtg;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFName;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
@ -190,6 +191,7 @@ public final class TestAreaReference extends TestCase {
|
||||
InputStream is = HSSFTestDataSamples.openSampleFileStream("44167.xls");
|
||||
HSSFWB wb = new HSSFWB(is);
|
||||
Workbook workbook = wb.getWorkbook();
|
||||
HSSFEvaluationWorkbook eb = HSSFEvaluationWorkbook.create(wb);
|
||||
|
||||
assertEquals(1, wb.getNumberOfNames());
|
||||
String sheetName = "Tabelle1";
|
||||
@ -211,10 +213,10 @@ public final class TestAreaReference extends TestCase {
|
||||
Area3DPtg ptgB = (Area3DPtg)def[1];
|
||||
Area3DPtg ptgC = (Area3DPtg)def[2];
|
||||
UnionPtg ptgD = (UnionPtg)def[3];
|
||||
assertEquals("", ptgA.toFormulaString(wb));
|
||||
assertEquals(refA, ptgB.toFormulaString(wb));
|
||||
assertEquals(refB, ptgC.toFormulaString(wb));
|
||||
assertEquals(",", ptgD.toFormulaString(wb));
|
||||
assertEquals("", ptgA.toFormulaString());
|
||||
assertEquals(refA, ptgB.toFormulaString(eb));
|
||||
assertEquals(refB, ptgC.toFormulaString(eb));
|
||||
assertEquals(",", ptgD.toFormulaString());
|
||||
|
||||
assertEquals(ref, nr.getAreaReference(wb));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user