Start to add XSSF specific handling for NameX (named ranges or functions from another file) #56737
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611958 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
86ca81d22f
commit
58096a6862
@ -399,7 +399,7 @@ public final class FormulaParser {
|
||||
throw new FormulaParseException("Cell reference or Named Range "
|
||||
+ "expected after sheet name at index " + _pointer + ".");
|
||||
}
|
||||
NameXPtg nameXPtg = _book.getNameXPtg(name, sheetIden);
|
||||
Ptg nameXPtg = _book.getNameXPtg(name, sheetIden);
|
||||
if (nameXPtg == null) {
|
||||
throw new FormulaParseException("Specified name '" + name +
|
||||
"' for sheet " + sheetIden.asFormulaString() + " not found");
|
||||
|
@ -18,7 +18,6 @@
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
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;
|
||||
@ -36,7 +35,7 @@ public interface FormulaParsingWorkbook {
|
||||
*/
|
||||
EvaluationName getName(String name, int sheetIndex);
|
||||
|
||||
NameXPtg getNameXPtg(String name, SheetIdentifier sheet);
|
||||
Ptg getNameXPtg(String name, SheetIdentifier sheet);
|
||||
|
||||
/**
|
||||
* Produce the appropriate Ptg for a 3d cell reference
|
||||
|
@ -30,6 +30,7 @@ import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPxg;
|
||||
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
||||
import org.apache.poi.ss.formula.ptg.NameXPxg;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
|
||||
import org.apache.poi.ss.formula.ptg.Ref3DPxg;
|
||||
@ -297,41 +298,58 @@ public final class OperationEvaluationContext {
|
||||
aptg.getLastRow(), aptg.getLastColumn(), sre);
|
||||
}
|
||||
|
||||
public ValueEval getNameXEval(NameXPtg nameXPtg) {
|
||||
// TODO Need HSSF and XSSF versions of these
|
||||
ExternalSheet externSheet = _workbook.getExternalSheet(nameXPtg.getSheetRefIndex());
|
||||
if(externSheet == null)
|
||||
return new NameXEval(nameXPtg);
|
||||
String workbookName = externSheet.getWorkbookName();
|
||||
ExternalName externName = _workbook.getExternalName(
|
||||
nameXPtg.getSheetRefIndex(),
|
||||
nameXPtg.getNameIndex()
|
||||
);
|
||||
try{
|
||||
WorkbookEvaluator refWorkbookEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
|
||||
EvaluationName evaluationName = refWorkbookEvaluator.getName(externName.getName(),externName.getIx()-1);
|
||||
if(evaluationName != null && evaluationName.hasFormula()){
|
||||
if (evaluationName.getNameDefinition().length > 1) {
|
||||
throw new RuntimeException("Complex name formulas not supported yet");
|
||||
public ValueEval getNameXEval(NameXPtg nameXPtg) {
|
||||
ExternalSheet externSheet = _workbook.getExternalSheet(nameXPtg.getSheetRefIndex());
|
||||
if(externSheet == null || externSheet.getWorkbookName() == null) {
|
||||
// External reference to our own workbook's name
|
||||
return new NameXEval(nameXPtg);
|
||||
}
|
||||
|
||||
String workbookName = externSheet.getWorkbookName();
|
||||
ExternalName externName = _workbook.getExternalName(
|
||||
nameXPtg.getSheetRefIndex(),
|
||||
nameXPtg.getNameIndex()
|
||||
);
|
||||
return getNameXEval(externName, workbookName);
|
||||
}
|
||||
public ValueEval getNameXEval(NameXPxg nameXPxg) {
|
||||
ExternalSheet externSheet = _workbook.getExternalSheet(nameXPxg.getSheetName(), nameXPxg.getExternalWorkbookNumber());
|
||||
if(externSheet == null || externSheet.getWorkbookName() == null) {
|
||||
// External reference to our own workbook's name
|
||||
// TODO How to do this?
|
||||
return new NameXEval(null);
|
||||
}
|
||||
|
||||
// TODO
|
||||
return null;
|
||||
// return getNameXEval(nameXPxg.getNameName(), externSheet.getWorkbookName());
|
||||
}
|
||||
private ValueEval getNameXEval(ExternalName externName, String workbookName) {
|
||||
try {
|
||||
WorkbookEvaluator refWorkbookEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
|
||||
EvaluationName evaluationName = refWorkbookEvaluator.getName(externName.getName(),externName.getIx()-1);
|
||||
if (evaluationName != null && evaluationName.hasFormula()){
|
||||
if (evaluationName.getNameDefinition().length > 1) {
|
||||
throw new RuntimeException("Complex name formulas not supported yet");
|
||||
}
|
||||
Ptg ptg = evaluationName.getNameDefinition()[0];
|
||||
if (ptg instanceof Ref3DPtg){
|
||||
Ref3DPtg ref3D = (Ref3DPtg)ptg;
|
||||
int sheetIndex = refWorkbookEvaluator.getSheetIndexByExternIndex(ref3D.getExternSheetIndex());
|
||||
String sheetName = refWorkbookEvaluator.getSheetName(sheetIndex);
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(workbookName, sheetName);
|
||||
return new LazyRefEval(ref3D.getRow(), ref3D.getColumn(), sre);
|
||||
} else if(ptg instanceof Area3DPtg){
|
||||
Area3DPtg area3D = (Area3DPtg)ptg;
|
||||
int sheetIndex = refWorkbookEvaluator.getSheetIndexByExternIndex(area3D.getExternSheetIndex());
|
||||
String sheetName = refWorkbookEvaluator.getSheetName(sheetIndex);
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(workbookName, sheetName);
|
||||
return new LazyAreaEval(area3D.getFirstRow(), area3D.getFirstColumn(), area3D.getLastRow(), area3D.getLastColumn(), sre);
|
||||
}
|
||||
}
|
||||
Ptg ptg = evaluationName.getNameDefinition()[0];
|
||||
if(ptg instanceof Ref3DPtg){
|
||||
Ref3DPtg ref3D = (Ref3DPtg)ptg;
|
||||
int sheetIndex = refWorkbookEvaluator.getSheetIndexByExternIndex(ref3D.getExternSheetIndex());
|
||||
String sheetName = refWorkbookEvaluator.getSheetName(sheetIndex);
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(workbookName, sheetName);
|
||||
return new LazyRefEval(ref3D.getRow(), ref3D.getColumn(), sre);
|
||||
}else if(ptg instanceof Area3DPtg){
|
||||
Area3DPtg area3D = (Area3DPtg)ptg;
|
||||
int sheetIndex = refWorkbookEvaluator.getSheetIndexByExternIndex(area3D.getExternSheetIndex());
|
||||
String sheetName = refWorkbookEvaluator.getSheetName(sheetIndex);
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(workbookName, sheetName);
|
||||
return new LazyAreaEval(area3D.getFirstRow(), area3D.getFirstColumn(), area3D.getLastRow(), area3D.getLastColumn(), sre);
|
||||
}
|
||||
}
|
||||
return ErrorEval.REF_INVALID;
|
||||
}catch(WorkbookNotFoundException wnfe){
|
||||
return ErrorEval.REF_INVALID;
|
||||
}
|
||||
return ErrorEval.REF_INVALID;
|
||||
} catch(WorkbookNotFoundException wnfe){
|
||||
return ErrorEval.REF_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -637,7 +637,7 @@ public final class WorkbookEvaluator {
|
||||
EvaluationName nameRecord = _workbook.getName(namePtg);
|
||||
return getEvalForNameRecord(nameRecord, ec);
|
||||
}
|
||||
if (ptg instanceof NameXPtg) {
|
||||
if (ptg instanceof NameXPtg) { // TODO Generalise for NameXPxg
|
||||
// Externally defined named ranges or macro functions
|
||||
NameXPtg nameXPtg = (NameXPtg)ptg;
|
||||
ValueEval eval = ec.getNameXEval(nameXPtg);
|
||||
|
99
src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
Normal file
99
src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
Normal file
@ -0,0 +1,99 @@
|
||||
/* ====================================================================
|
||||
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.AreaReference;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* <p>Title: XSSF Area 3D Reference (Sheet + Area)<P>
|
||||
* <p>Description: Defined an area 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 Area3DPtg}</p>
|
||||
*/
|
||||
public final class Area3DPxg extends AreaPtgBase {
|
||||
private int externalWorkbookNumber = -1;
|
||||
private String sheetName;
|
||||
|
||||
public Area3DPxg(int externalWorkbookNumber, String sheetName, String arearef) {
|
||||
this(externalWorkbookNumber, sheetName, new AreaReference(arearef));
|
||||
}
|
||||
public Area3DPxg(int externalWorkbookNumber, String sheetName, AreaReference arearef) {
|
||||
super(arearef);
|
||||
this.externalWorkbookNumber = externalWorkbookNumber;
|
||||
this.sheetName = sheetName;
|
||||
}
|
||||
|
||||
public Area3DPxg(String sheetName, String arearef) {
|
||||
this(sheetName, new AreaReference(arearef));
|
||||
}
|
||||
public Area3DPxg(String sheetName, AreaReference arearef) {
|
||||
this(-1, sheetName, arearef);
|
||||
}
|
||||
|
||||
@Override
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
@ -23,8 +23,12 @@ import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author aviks
|
||||
* A Name, be that a Named Range or a Function / User Defined
|
||||
* Function, addressed in the HSSF External Sheet style.
|
||||
*
|
||||
* <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 NameXPxg}
|
||||
*/
|
||||
public final class NameXPtg extends OperandPtg implements WorkbookDependentFormula {
|
||||
public final static short sid = 0x39;
|
||||
|
93
src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java
Normal file
93
src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java
Normal file
@ -0,0 +1,93 @@
|
||||
/* ====================================================================
|
||||
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.util.LittleEndianOutput;
|
||||
|
||||
/**
|
||||
* A Name, be that a Named Range or a Function / User Defined
|
||||
* Function, addressed in the HSSF External Sheet style.
|
||||
*
|
||||
* <p>This is XSSF only, as it stores the sheet / book references
|
||||
* in String form. The HSSF equivalent using indexes is {@link NameXPtg}</p>
|
||||
*/
|
||||
public final class NameXPxg extends OperandPtg {
|
||||
private int externalWorkbookNumber = -1;
|
||||
private String sheetName;
|
||||
private String nameName;
|
||||
|
||||
public NameXPxg(int externalWorkbookNumber, String sheetName, String nameName) {
|
||||
this.externalWorkbookNumber = externalWorkbookNumber;
|
||||
this.sheetName = sheetName;
|
||||
this.nameName = nameName;
|
||||
}
|
||||
public NameXPxg(String sheetName, String nameName) {
|
||||
this(-1, sheetName, nameName);
|
||||
}
|
||||
|
||||
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("name=");
|
||||
sb.append(nameName);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int getExternalWorkbookNumber() {
|
||||
return externalWorkbookNumber;
|
||||
}
|
||||
public String getSheetName() {
|
||||
return sheetName;
|
||||
}
|
||||
public String getNameName() {
|
||||
return nameName;
|
||||
}
|
||||
|
||||
public String toFormulaString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (externalWorkbookNumber >= 0) {
|
||||
sb.append('[');
|
||||
sb.append(externalWorkbookNumber);
|
||||
sb.append(']');
|
||||
}
|
||||
sb.append(sheetName);
|
||||
sb.append('!');
|
||||
sb.append(nameName);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public byte getDefaultOperandClass() {
|
||||
return Ptg.CLASS_VALUE;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return 1;
|
||||
}
|
||||
public void write(LittleEndianOutput out) {
|
||||
throw new IllegalStateException("XSSF-only Ptg, should not be serialised");
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPxg;
|
||||
import org.apache.poi.ss.formula.ptg.NamePtg;
|
||||
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
||||
import org.apache.poi.ss.formula.ptg.NameXPxg;
|
||||
import org.apache.poi.ss.formula.ptg.Ptg;
|
||||
import org.apache.poi.ss.formula.ptg.Ref3DPxg;
|
||||
import org.apache.poi.ss.formula.udf.IndexedUDFFinder;
|
||||
@ -42,11 +43,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
|
||||
|
||||
/**
|
||||
* Internal POI use only
|
||||
*
|
||||
* @author Josh Micich
|
||||
*/
|
||||
public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, EvaluationWorkbook, FormulaParsingWorkbook {
|
||||
|
||||
private final XSSFWorkbook _uBook;
|
||||
|
||||
public static XSSFEvaluationWorkbook create(XSSFWorkbook book) {
|
||||
@ -122,21 +120,22 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
}
|
||||
|
||||
public NameXPtg getNameXPtg(String name, SheetIdentifier sheet) {
|
||||
public NameXPxg getNameXPtg(String name, SheetIdentifier sheet) {
|
||||
// First, try to find it as a User Defined Function
|
||||
IndexedUDFFinder udfFinder = (IndexedUDFFinder)getUDFFinder();
|
||||
FreeRefFunction func = udfFinder.findFunction(name);
|
||||
if (func != null) {
|
||||
return new NameXPtg(0, udfFinder.getFunctionIndex(name));
|
||||
return new NameXPxg(null, name);
|
||||
}
|
||||
|
||||
// Otherwise, try it as a named range
|
||||
XSSFName xname = _uBook.getName(name);
|
||||
if (xname != null) {
|
||||
int nameAt = _uBook.getNameIndex(name);
|
||||
return new NameXPtg(xname.getSheetIndex(), nameAt);
|
||||
String sheetName = sheet._sheetIdentifier.getName();
|
||||
|
||||
if (sheet._bookName != null) {
|
||||
int bookIndex = resolveBookIndex(sheet._bookName);
|
||||
return new NameXPxg(bookIndex, sheetName, name);
|
||||
} else {
|
||||
return null;
|
||||
return new NameXPxg(sheetName, name);
|
||||
}
|
||||
}
|
||||
public Ptg get3DReferencePtg(CellReference cell, SheetIdentifier sheet) {
|
||||
|
Loading…
Reference in New Issue
Block a user