import org.apache.poi.ss.formula.FormulaParsingWorkbook;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.FormulaType;
+import org.apache.poi.ss.formula.SheetIdentifier;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.formula.ptg.NamePtg;
import org.apache.poi.ss.formula.ptg.NameXPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.Ref3DPtg;
import org.apache.poi.ss.formula.udf.UDFFinder;
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
public int getExternalSheetIndex(String workbookName, String sheetName) {
return _iBook.getExternalSheetIndex(workbookName, sheetName);
}
-
- public NameXPtg getNameXPtg(String name, int sheetRefIndex) {
+
+ public Ptg get3DReferencePtg(CellReference cr, SheetIdentifier sheet) {
+ int extIx = getSheetExtIx(sheet);
+ return new Ref3DPtg(cr, extIx);
+ }
+ public Ptg get3DReferencePtg(AreaReference areaRef, SheetIdentifier sheet) {
+ int extIx = getSheetExtIx(sheet);
+ return new Area3DPtg(areaRef, extIx);
+ }
+ public NameXPtg getNameXPtg(String name, SheetIdentifier sheet) {
+ int sheetRefIndex = getSheetExtIx(sheet);
return _iBook.getNameXPtg(name, sheetRefIndex, _uBook.getUDFFinder());
}
}
}
+ private int getSheetExtIx(SheetIdentifier sheetIden) {
+ int extIx;
+ if (sheetIden == null) {
+ extIx = -1;
+ } else {
+ String sName = sheetIden.getSheetIdentifier().getName();
+ if (sheetIden.getBookName() == null) {
+ extIx = getExternalSheetIndex(sName);
+ } else {
+ extIx = getExternalSheetIndex(sheetIden.getBookName(), sName);
+ }
+ }
+ return extIx;
+ }
+
public SpreadsheetVersion getSpreadsheetVersion(){
return SpreadsheetVersion.EXCEL97;
}
import org.apache.poi.ss.formula.function.FunctionMetadataRegistry;
import org.apache.poi.ss.formula.ptg.AbstractFunctionPtg;
import org.apache.poi.ss.formula.ptg.AddPtg;
-import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.formula.ptg.AreaPtg;
import org.apache.poi.ss.formula.ptg.ArrayPtg;
import org.apache.poi.ss.formula.ptg.AttrPtg;
import org.apache.poi.ss.formula.ptg.PowerPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.RangePtg;
-import org.apache.poi.ss.formula.ptg.Ref3DPtg;
import org.apache.poi.ss.formula.ptg.RefPtg;
import org.apache.poi.ss.formula.ptg.StringPtg;
import org.apache.poi.ss.formula.ptg.SubtractPtg;
* <p/>
* For POI internal use only
* <p/>
- *
- *
- * @author Avik Sengupta <avik at apache dot org>
- * @author Andrew C. oliver (acoliver at apache dot org)
- * @author Eric Ladner (eladner at goldinc dot com)
- * @author Cameron Riley (criley at ekmail.com)
- * @author Peter M. Murray (pete at quantrix dot com)
- * @author Pavel Krupets (pkrupets at palmtreebusiness dot com)
- * @author Josh Micich
- * @author David Lewis (DLewis400 at gmail dot com)
*/
public final class FormulaParser {
- private static final class Identifier {
- private final String _name;
- private final boolean _isQuoted;
-
- public Identifier(String name, boolean isQuoted) {
- _name = name;
- _isQuoted = isQuoted;
- }
- public String getName() {
- return _name;
- }
- public boolean isQuoted() {
- return _isQuoted;
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName());
- sb.append(" [");
- if (_isQuoted) {
- sb.append("'").append(_name).append("'");
- } else {
- sb.append(_name);
- }
- sb.append("]");
- return sb.toString();
- }
- }
- private static final class SheetIdentifier {
-
-
- private final String _bookName;
- private final Identifier _sheetIdentifier;
- public SheetIdentifier(String bookName, Identifier sheetIdentifier) {
- _bookName = bookName;
- _sheetIdentifier = sheetIdentifier;
- }
- public String getBookName() {
- return _bookName;
- }
- public Identifier getSheetIdentifier() {
- return _sheetIdentifier;
- }
- private void asFormulaString(StringBuffer sb) {
- if (_bookName != null) {
- sb.append(" [").append(_sheetIdentifier.getName()).append("]");
- }
- if (_sheetIdentifier.isQuoted()) {
- sb.append("'").append(_sheetIdentifier.getName()).append("'");
- } else {
- sb.append(_sheetIdentifier.getName());
- }
- }
- public String asFormulaString() {
- StringBuffer sb = new StringBuffer(32);
- asFormulaString(sb);
- return sb.toString();
- }
- public String toString() {
- StringBuffer sb = new StringBuffer(64);
- sb.append(getClass().getName());
- sb.append(" [");
- asFormulaString(sb);
- sb.append("]");
- return sb.toString();
- }
- }
-
private final String _formulaString;
private final int _formulaLength;
/** points at the next character to be read (after the {@link #look} char) */
throw new FormulaParseException("Cell reference or Named Range "
+ "expected after sheet name at index " + _pointer + ".");
}
- int extIx = getSheetExtIx(sheetIden);
- NameXPtg nameXPtg = _book.getNameXPtg(name, extIx);
+ NameXPtg nameXPtg = _book.getNameXPtg(name, sheetIden);
if (nameXPtg == null) {
throw new FormulaParseException("Specified name '" + name +
"' for sheet " + sheetIden.asFormulaString() + " not found");
return false;
}
- private int getSheetExtIx(SheetIdentifier sheetIden) {
- int extIx;
- if (sheetIden == null) {
- extIx = Integer.MIN_VALUE;
- } else {
- String sName = sheetIden.getSheetIdentifier().getName();
- if (sheetIden.getBookName() == null) {
- extIx = _book.getExternalSheetIndex(sName);
- } else {
- extIx = _book.getExternalSheetIndex(sheetIden.getBookName(), sName);
- }
- }
- return extIx;
- }
-
/**
*
* @param sheetIden may be <code>null</code>
*/
private ParseNode createAreaRefParseNode(SheetIdentifier sheetIden, SimpleRangePart part1,
SimpleRangePart part2) throws FormulaParseException {
- int extIx = getSheetExtIx(sheetIden);
-
Ptg ptg;
if (part2 == null) {
CellReference cr = part1.getCellReference();
if (sheetIden == null) {
ptg = new RefPtg(cr);
} else {
- ptg = new Ref3DPtg(cr, extIx);
+ ptg = _book.get3DReferencePtg(cr, sheetIden);
}
} else {
AreaReference areaRef = createAreaRef(part1, part2);
if (sheetIden == null) {
ptg = new AreaPtg(areaRef);
} else {
- ptg = new Area3DPtg(areaRef, extIx);
+ ptg = _book.get3DReferencePtg(areaRef, sheetIden);
}
}
return new ParseNode(ptg);
}
}
- Identifier iden = new Identifier(sb.toString(), true);
+ NameIdentifier iden = new NameIdentifier(sb.toString(), true);
// quoted identifier - can't concatenate anything more
SkipWhite();
if (look == '!') {
SkipWhite();
if (look == '!') {
GetChar();
- return new SheetIdentifier(bookName, new Identifier(sb.toString(), false));
+ return new SheetIdentifier(bookName, new NameIdentifier(sb.toString(), false));
}
return null;
}
}
EvaluationName hName = _book.getName(name, _sheetIndex);
if (hName == null) {
- nameToken = _book.getNameXPtg(name, -1);
+ nameToken = _book.getNameXPtg(name, null);
if (nameToken == null) {
throw new FormulaParseException("Name '" + name
+ "' is completely unknown in the current workbook");
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.ptg.NameXPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
/**
* Abstracts a workbook for the purpose of formula parsing.<br/>
*/
EvaluationName getName(String name, int sheetIndex);
- NameXPtg getNameXPtg(String name, int sheetRefIndex);
+ NameXPtg getNameXPtg(String name, SheetIdentifier sheet);
+
+ /**
+ * Produce the appropriate Ptg for a 3d cell reference
+ */
+ Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet);
+
+ /**
+ * Produce the appropriate Ptg for a 3d area reference
+ */
+ Ptg get3DReferencePtg(AreaReference area, SheetIdentifier sheet);
/**
* gets the externSheet index for a sheet from this workbook
--- /dev/null
+/* ====================================================================
+ 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.
+==================================================================== */
+
+package org.apache.poi.ss.formula;
+
+public class NameIdentifier {
+ private final String _name;
+ private final boolean _isQuoted;
+
+ public NameIdentifier(String name, boolean isQuoted) {
+ _name = name;
+ _isQuoted = isQuoted;
+ }
+ public String getName() {
+ return _name;
+ }
+ public boolean isQuoted() {
+ return _isQuoted;
+ }
+ public String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName());
+ sb.append(" [");
+ if (_isQuoted) {
+ sb.append("'").append(_name).append("'");
+ } else {
+ sb.append(_name);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
\ No newline at end of file
--- /dev/null
+/* ====================================================================
+ 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.
+==================================================================== */
+
+package org.apache.poi.ss.formula;
+
+public class SheetIdentifier {
+ public String _bookName;
+ public NameIdentifier _sheetIdentifier;
+
+ public SheetIdentifier(String bookName, NameIdentifier sheetIdentifier) {
+ _bookName = bookName;
+ _sheetIdentifier = sheetIdentifier;
+ }
+ public String getBookName() {
+ return _bookName;
+ }
+ public NameIdentifier getSheetIdentifier() {
+ return _sheetIdentifier;
+ }
+ private void asFormulaString(StringBuffer sb) {
+ if (_bookName != null) {
+ sb.append(" [").append(_sheetIdentifier.getName()).append("]");
+ }
+ if (_sheetIdentifier.isQuoted()) {
+ sb.append("'").append(_sheetIdentifier.getName()).append("'");
+ } else {
+ sb.append(_sheetIdentifier.getName());
+ }
+ }
+ public String asFormulaString() {
+ StringBuffer sb = new StringBuffer(32);
+ asFormulaString(sb);
+ return sb.toString();
+ }
+ public String toString() {
+ StringBuffer sb = new StringBuffer(64);
+ sb.append(getClass().getName());
+ sb.append(" [");
+ asFormulaString(sb);
+ sb.append("]");
+ return sb.toString();
+ }
+}
\ No newline at end of file
import org.apache.poi.ss.formula.ptg.OperationPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
+import org.apache.poi.ss.formula.ptg.Ref3DPxg;
import org.apache.poi.ss.formula.ptg.RefErrorPtg;
import org.apache.poi.ss.formula.ptg.RefPtg;
import org.apache.poi.ss.formula.ptg.StringPtg;
Ref3DPtg rptg = (Ref3DPtg) ptg;
return ec.getRef3DEval(rptg.getRow(), rptg.getColumn(), rptg.getExternSheetIndex());
}
+ if (ptg instanceof Ref3DPxg) {
+ Ref3DPtg rptg = (Ref3DPtg) ptg;
+ // TODO Return the right eval, should be easy as we already know the sheet details
+ }
if (ptg instanceof Area3DPtg) {
Area3DPtg aptg = (Area3DPtg) ptg;
return ec.getArea3DEval(aptg.getFirstRow(), aptg.getFirstColumn(), aptg.getLastRow(), aptg.getLastColumn(), aptg.getExternSheetIndex());
package org.apache.poi.ss.formula.ptg;
-import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.formula.ExternSheetReferenceToken;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.WorkbookDependentFormula;
+import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
/**
- * Title: Reference 3D Ptg <P>
- * Description: Defined a cell in extern sheet. <P>
- * REFERENCE: <P>
- * @author Libin Roman (Vista Portal LDT. Developer)
- * @author Jason Height (jheight at chariot dot net dot au)
+ * <p>Title: Reference 3D Ptg</p>
+ * <p>Description: Defined a cell in extern sheet.</p>
+ * <p>REFERENCE: </p>
+ *
+ * <p>This is HSSF only, as it matches the HSSF file format way of
+ * referring to the sheet by an extern index. The XSSF equivalent
+ * is {@link Ref3DPxg}
*/
public final class Ref3DPtg extends RefPtgBase implements WorkbookDependentFormula, ExternSheetReferenceToken {
public final static byte sid = 0x3a;
--- /dev/null
+/* ====================================================================
+ 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.
+==================================================================== */
+
+package org.apache.poi.ss.formula.ptg;
+
+import org.apache.poi.ss.util.CellReference;
+import org.apache.poi.util.LittleEndianOutput;
+
+/**
+ * <p>Title: XSSF 3D Reference</p>
+ * <p>Description: Defines a cell in an external or different sheet.</p>
+ * <p>REFERENCE: </p>
+ *
+ * <p>This is XSSF only, as it stores the sheet / book references
+ * in String form. The HSSF equivalent using indexes is {@link Ref3DPtg}</p>
+ */
+public final class Ref3DPxg extends RefPtgBase {
+ private int externalWorkbookNumber = -1;
+ private String sheetName;
+
+ public Ref3DPxg(int externalWorkbookNumber, String sheetName, String cellref) {
+ this(externalWorkbookNumber, sheetName, new CellReference(cellref));
+ }
+ public Ref3DPxg(int externalWorkbookNumber, String sheetName, CellReference c) {
+ super(c);
+ this.externalWorkbookNumber = externalWorkbookNumber;
+ this.sheetName = sheetName;
+ }
+
+ public Ref3DPxg(String sheetName, String cellref) {
+ this(sheetName, new CellReference(cellref));
+ }
+ public Ref3DPxg(String sheetName, CellReference c) {
+ this(-1, sheetName, c);
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ if (externalWorkbookNumber >= 0) {
+ sb.append(" [");
+ sb.append("workbook=").append(getExternalWorkbookNumber());
+ sb.append("] ");
+ }
+ sb.append("sheet=").append(getSheetName());
+ sb.append(" ! ");
+ sb.append(formatReferenceAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public int getExternalWorkbookNumber() {
+ return externalWorkbookNumber;
+ }
+ public String getSheetName() {
+ return sheetName;
+ }
+
+ public String format2DRefAsString() {
+ return formatReferenceAsString();
+ }
+
+ public String toFormulaString() {
+ StringBuffer sb = new StringBuffer();
+ if (externalWorkbookNumber >= 0) {
+ sb.append('[');
+ sb.append(externalWorkbookNumber);
+ sb.append(']');
+ }
+ sb.append(sheetName);
+ sb.append('!');
+ sb.append(formatReferenceAsString());
+ return sb.toString();
+ }
+
+ public int getSize() {
+ return 1;
+ }
+ public void write(LittleEndianOutput out) {
+ throw new IllegalStateException("XSSF-only Ptg, should not be serialised");
+ }
+}
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.FormulaType;
+import org.apache.poi.ss.formula.SheetIdentifier;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.formula.ptg.NamePtg;
import org.apache.poi.ss.formula.ptg.NameXPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.formula.ptg.Ref3DPxg;
import org.apache.poi.ss.formula.udf.IndexedUDFFinder;
import org.apache.poi.ss.formula.udf.UDFFinder;
+import org.apache.poi.ss.util.AreaReference;
+import org.apache.poi.ss.util.CellReference;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
/**
int sheetIndex = _uBook.getSheetIndex(sheetName);
return convertToExternalSheetIndex(sheetIndex);
}
+
+ private int resolveBookIndex(String bookName) {
+ // Is it already in numeric form?
+ if (bookName.startsWith("[") && bookName.endsWith("]")) {
+ bookName = bookName.substring(1, bookName.length()-2);
+ try {
+ return Integer.parseInt(bookName);
+ } catch (NumberFormatException e) {}
+ }
+
+ // Look up an External Link Table for this name
+ throw new RuntimeException("Not implemented yet"); // TODO
+ }
public EvaluationName getName(String name, int sheetIndex) {
for (int i = 0; i < _uBook.getNumberOfNames(); i++) {
throw new RuntimeException("Not implemented yet");
}
- public NameXPtg getNameXPtg(String name, int sheetRefIndex) {
+ public NameXPtg getNameXPtg(String name, SheetIdentifier sheet) {
// First, try to find it as a User Defined Function
IndexedUDFFinder udfFinder = (IndexedUDFFinder)getUDFFinder();
FreeRefFunction func = udfFinder.findFunction(name);
return null;
}
}
+ public Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet) {
+ String sheetName = sheet._sheetIdentifier.getName();
+
+ if (sheet._bookName != null) {
+ int bookIndex = resolveBookIndex(sheet._bookName);
+ return new Ref3DPxg(bookIndex, sheetName, cell);
+ } else {
+ return new Ref3DPxg(sheetName, cell);
+ }
+ }
+ public Ptg get3DReferencePtg(AreaReference area, SheetIdentifier sheet) {
+ // TODO Implement properly
+ return new Area3DPtg(area, getExternalSheetIndex(sheet._sheetIdentifier.getName()));
+ }
public String resolveNameXText(NameXPtg n) {
int idx = n.getNameIndex();
import org.apache.poi.ss.formula.ptg.FuncPtg;
import org.apache.poi.ss.formula.ptg.IntPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
-import org.apache.poi.ss.formula.ptg.Ref3DPtg;
+import org.apache.poi.ss.formula.ptg.Ref3DPxg;
import org.apache.poi.ss.formula.ptg.RefPtg;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.Ignore;
// Reference to a single cell in a different sheet
ptgs = parse(fpb, "Uses!A1");
assertEquals(1, ptgs.length);
- assertEquals(Ref3DPtg.class, ptgs[0].getClass());
- assertEquals("A1", ((Ref3DPtg)ptgs[0]).format2DRefAsString());
- assertEquals("Uses!A1", ((Ref3DPtg)ptgs[0]).toFormulaString(fpb));
+ assertEquals(Ref3DPxg.class, ptgs[0].getClass());
+ assertEquals("A1", ((Ref3DPxg)ptgs[0]).format2DRefAsString());
+ assertEquals("Uses!A1", ((Ref3DPxg)ptgs[0]).toFormulaString());
// Reference to a sheet scoped named range from another sheet
ptgs = parse(fpb, "Defines!NR_To_A1");