Browse Source

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
tags/REL_3_11_BETA1
Nick Burch 10 years ago
parent
commit
83d9405d43

+ 27
- 5
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java View File

@@ -120,10 +120,29 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
}

public ExternalSheet getExternalSheet(int externSheetIndex) {
return _iBook.getExternalSheet(externSheetIndex);
}
public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
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) {
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();
}

+ 12
- 1
src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java View File

@@ -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);

+ 27
- 11
src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java View File

@@ -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();

+ 0
- 1
src/java/org/apache/poi/ss/formula/SheetRefEvaluator.java View File

@@ -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;

+ 2
- 4
src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java View File

@@ -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;

+ 7
- 4
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java View File

@@ -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");

+ 17
- 4
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java View File

@@ -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…
Cancel
Save