Start to update how the formula parser looks up sheets from formula ptgs, to account for the differences in how HSSF and XSSF store references to external sheets. For #56737
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611948 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0986f32d46
commit
2cd4290460
@ -120,10 +120,29 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
}
|
||||
|
||||
public ExternalSheet getExternalSheet(int externSheetIndex) {
|
||||
return _iBook.getExternalSheet(externSheetIndex);
|
||||
ExternalSheet sheet = _iBook.getExternalSheet(externSheetIndex);
|
||||
if (sheet == null) {
|
||||
// Try to treat it as a local sheet
|
||||
int localSheetIndex = convertFromExternSheetIndex(externSheetIndex);
|
||||
if (localSheetIndex == -1) {
|
||||
// The sheet referenced can't be found, sorry
|
||||
return null;
|
||||
}
|
||||
if (localSheetIndex == -2) {
|
||||
// Not actually sheet based at all - is workbook scoped
|
||||
return null;
|
||||
}
|
||||
// Look up the local sheet
|
||||
String sheetName = getSheetName(localSheetIndex);
|
||||
sheet = new ExternalSheet(null, sheetName);
|
||||
}
|
||||
return sheet;
|
||||
}
|
||||
public ExternalSheet getExternalSheet(String sheetName, int externalWorkbookNumber) {
|
||||
throw new IllegalStateException("XSSF-style external references are not supported for HSSF");
|
||||
}
|
||||
|
||||
public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
|
||||
public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
|
||||
return _iBook.getExternalName(externSheetIndex, externNameIndex);
|
||||
}
|
||||
|
||||
@ -141,7 +160,9 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
int ix = namePtg.getIndex();
|
||||
return new Name(_iBook.getNameRecord(ix), ix);
|
||||
}
|
||||
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Ptg[] getFormulaTokens(EvaluationCell evalCell) {
|
||||
HSSFCell cell = ((HSSFEvaluationCell)evalCell).getHSSFCell();
|
||||
if (false) {
|
||||
// re-parsing the formula text also works, but is a waste of time
|
||||
@ -159,6 +180,7 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
FormulaRecordAggregate fra = (FormulaRecordAggregate) cell.getCellValueRecord();
|
||||
return fra.getFormulaTokens();
|
||||
}
|
||||
|
||||
public UDFFinder getUDFFinder(){
|
||||
return _uBook.getUDFFinder();
|
||||
}
|
||||
|
@ -44,10 +44,21 @@ public interface EvaluationWorkbook {
|
||||
EvaluationSheet getSheet(int sheetIndex);
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if externSheetIndex refers to a sheet inside the current workbook
|
||||
* HSSF Only - fetch the external-style sheet details
|
||||
* <p>Return will have no workbook set if it's actually in our own workbook</p>
|
||||
*/
|
||||
ExternalSheet getExternalSheet(int externSheetIndex);
|
||||
/**
|
||||
* XSSF Only - fetch the external-style sheet details
|
||||
* <p>Return will have no workbook set if it's actually in our own workbook</p>
|
||||
*/
|
||||
ExternalSheet getExternalSheet(String sheetName, int externalWorkbookNumber);
|
||||
/**
|
||||
* HSSF Only - convert an external sheet index to an internal sheet index,
|
||||
* for an external-style reference to one of this workbook's own sheets
|
||||
*/
|
||||
int convertFromExternSheetIndex(int externSheetIndex);
|
||||
|
||||
ExternalName getExternalName(int externSheetIndex, int externNameIndex);
|
||||
EvaluationName getName(NamePtg namePtg);
|
||||
EvaluationName getName(String name, int sheetIndex);
|
||||
|
@ -17,16 +17,21 @@
|
||||
|
||||
package org.apache.poi.ss.formula;
|
||||
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||
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.eval.*;
|
||||
import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
import org.apache.poi.ss.SpreadsheetVersion;
|
||||
import org.apache.poi.ss.formula.CollaboratingWorkbooksEnvironment.WorkbookNotFoundException;
|
||||
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalName;
|
||||
import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;
|
||||
import org.apache.poi.ss.formula.eval.AreaEval;
|
||||
import org.apache.poi.ss.formula.eval.ErrorEval;
|
||||
import org.apache.poi.ss.formula.eval.NameXEval;
|
||||
import org.apache.poi.ss.formula.eval.RefEval;
|
||||
import org.apache.poi.ss.formula.eval.ValueEval;
|
||||
import org.apache.poi.ss.formula.functions.FreeRefFunction;
|
||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||
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.ptg.Ref3DPxg;
|
||||
import org.apache.poi.ss.util.CellReference;
|
||||
import org.apache.poi.ss.util.CellReference.NameType;
|
||||
|
||||
@ -70,13 +75,20 @@ public final class OperationEvaluationContext {
|
||||
SheetRefEvaluator createExternSheetRefEvaluator(ExternSheetReferenceToken ptg) {
|
||||
return createExternSheetRefEvaluator(ptg.getExternSheetIndex());
|
||||
}
|
||||
SheetRefEvaluator createExternSheetRefEvaluator(String sheetName, int externalWorkbookNumber) {
|
||||
ExternalSheet externalSheet = _workbook.getExternalSheet(sheetName, externalWorkbookNumber);
|
||||
return createExternSheetRefEvaluator(externalSheet);
|
||||
}
|
||||
SheetRefEvaluator createExternSheetRefEvaluator(int externSheetIndex) {
|
||||
ExternalSheet externalSheet = _workbook.getExternalSheet(externSheetIndex);
|
||||
return createExternSheetRefEvaluator(externalSheet);
|
||||
}
|
||||
SheetRefEvaluator createExternSheetRefEvaluator(ExternalSheet externalSheet) {
|
||||
WorkbookEvaluator targetEvaluator;
|
||||
int otherSheetIndex;
|
||||
if (externalSheet == null) {
|
||||
if (externalSheet == null || externalSheet.getWorkbookName() == null) {
|
||||
// sheet is in same workbook
|
||||
otherSheetIndex = _workbook.convertFromExternSheetIndex(externSheetIndex);
|
||||
otherSheetIndex = _workbook.getSheetIndex(externalSheet.getSheetName());
|
||||
targetEvaluator = _bookEvaluator;
|
||||
} else {
|
||||
// look up sheet by name from external workbook
|
||||
@ -259,10 +271,14 @@ public final class OperationEvaluationContext {
|
||||
SheetRefEvaluator sre = getRefEvaluatorForCurrentSheet();
|
||||
return new LazyRefEval(rowIndex, columnIndex, sre);
|
||||
}
|
||||
public ValueEval getRef3DEval(int rowIndex, int columnIndex, int extSheetIndex) {
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(extSheetIndex);
|
||||
return new LazyRefEval(rowIndex, columnIndex, sre);
|
||||
public ValueEval getRef3DEval(Ref3DPtg rptg) {
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(rptg.getExternSheetIndex());
|
||||
return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre);
|
||||
}
|
||||
public ValueEval getRef3DEval(Ref3DPxg rptg) {
|
||||
SheetRefEvaluator sre = createExternSheetRefEvaluator(rptg.getSheetName(), rptg.getExternalWorkbookNumber());
|
||||
return new LazyRefEval(rptg.getRow(), rptg.getColumn(), sre);
|
||||
}
|
||||
public ValueEval getAreaEval(int firstRowIndex, int firstColumnIndex,
|
||||
int lastRowIndex, int lastColumnIndex) {
|
||||
SheetRefEvaluator sre = getRefEvaluatorForCurrentSheet();
|
||||
|
@ -28,7 +28,6 @@ import org.apache.poi.ss.usermodel.Cell;
|
||||
* @author Josh Micich
|
||||
*/
|
||||
final class SheetRefEvaluator {
|
||||
|
||||
private final WorkbookEvaluator _bookEvaluator;
|
||||
private final EvaluationTracker _tracker;
|
||||
private final int _sheetIndex;
|
||||
|
@ -673,12 +673,10 @@ public final class WorkbookEvaluator {
|
||||
return ErrorEval.REF_INVALID;
|
||||
}
|
||||
if (ptg instanceof Ref3DPtg) {
|
||||
Ref3DPtg rptg = (Ref3DPtg) ptg;
|
||||
return ec.getRef3DEval(rptg.getRow(), rptg.getColumn(), rptg.getExternSheetIndex());
|
||||
return ec.getRef3DEval((Ref3DPtg)ptg);
|
||||
}
|
||||
if (ptg instanceof Ref3DPxg) {
|
||||
Ref3DPtg rptg = (Ref3DPtg) ptg;
|
||||
// TODO Return the right eval, should be easy as we already know the sheet details
|
||||
return ec.getRef3DEval((Ref3DPxg)ptg);
|
||||
}
|
||||
if (ptg instanceof Area3DPtg) {
|
||||
Area3DPtg aptg = (Area3DPtg) ptg;
|
||||
|
@ -20,13 +20,13 @@ package org.apache.poi.ss.formula.eval.forked;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.EvaluationCell;
|
||||
import org.apache.poi.ss.formula.EvaluationName;
|
||||
import org.apache.poi.ss.formula.EvaluationSheet;
|
||||
import org.apache.poi.ss.formula.EvaluationWorkbook;
|
||||
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.udf.UDFFinder;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
@ -90,8 +90,11 @@ final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
|
||||
public ExternalSheet getExternalSheet(int externSheetIndex) {
|
||||
return _masterBook.getExternalSheet(externSheetIndex);
|
||||
}
|
||||
public ExternalSheet getExternalSheet(String sheetName, int externalWorkbookNumber) {
|
||||
return _masterBook.getExternalSheet(sheetName, externalWorkbookNumber);
|
||||
}
|
||||
|
||||
public Ptg[] getFormulaTokens(EvaluationCell cell) {
|
||||
public Ptg[] getFormulaTokens(EvaluationCell cell) {
|
||||
if (cell instanceof ForkedEvaluationCell) {
|
||||
// doesn't happen yet because formulas cannot be modified from the master workbook
|
||||
throw new RuntimeException("Updated formulas not supported yet");
|
||||
|
@ -37,6 +37,7 @@ 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.apache.poi.xssf.model.ExternalLinksTable;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName;
|
||||
|
||||
/**
|
||||
@ -63,7 +64,8 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
return externSheetIndex;
|
||||
}
|
||||
/**
|
||||
* @return the sheet index of the sheet with the given external index.
|
||||
* XSSF doesn't use external sheet indexes, so when asked treat
|
||||
* it just as a local index
|
||||
*/
|
||||
public int convertFromExternSheetIndex(int externSheetIndex) {
|
||||
return externSheetIndex;
|
||||
@ -175,10 +177,21 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||
}
|
||||
|
||||
public ExternalSheet getExternalSheet(int externSheetIndex) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
throw new IllegalStateException("HSSF-style external references are not supported for XSSF");
|
||||
}
|
||||
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
||||
public ExternalSheet getExternalSheet(String sheetName, int externalWorkbookNumber) {
|
||||
if (externalWorkbookNumber > 0) {
|
||||
// External reference - reference is 1 based, link table is 0 based
|
||||
int linkNumber = externalWorkbookNumber - 1;
|
||||
ExternalLinksTable linkTable = _uBook.getExternalLinksTable().get(linkNumber);
|
||||
return new ExternalSheet(linkTable.getLinkedFileName(), sheetName);
|
||||
} else {
|
||||
// Internal reference
|
||||
return new ExternalSheet(null, sheetName);
|
||||
}
|
||||
}
|
||||
|
||||
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
||||
throw new RuntimeException("not implemented yet");
|
||||
}
|
||||
public int getSheetIndex(String sheetName) {
|
||||
|
Loading…
Reference in New Issue
Block a user