mirror of https://github.com/apache/poi.git
More progress towards #55906 - Have the ExternSheet references set up for multi-sheet references
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1613373 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c5dd59014e
commit
1dd9e43898
|
@ -1871,17 +1871,31 @@ public final class InternalWorkbook {
|
||||||
return linkTable.getLastInternalSheetIndexForExtIndex(externSheetNumber);
|
return linkTable.getLastInternalSheetIndexForExtIndex(externSheetNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns the extern sheet number for specific sheet number ,
|
/**
|
||||||
* if this sheet doesn't exist in extern sheet , add it
|
* Returns the extern sheet number for specific sheet number.
|
||||||
* @param sheetNumber sheet number
|
* If this sheet doesn't exist in extern sheet, add it
|
||||||
|
* @param sheetNumber local sheet number
|
||||||
* @return index to extern sheet
|
* @return index to extern sheet
|
||||||
*/
|
*/
|
||||||
public short checkExternSheet(int sheetNumber){
|
public short checkExternSheet(int sheetNumber){
|
||||||
return (short)getOrCreateLinkTable().checkExternSheet(sheetNumber);
|
return (short)getOrCreateLinkTable().checkExternSheet(sheetNumber);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Returns the extern sheet number for specific range of sheets.
|
||||||
|
* If this sheet range doesn't exist in extern sheet, add it
|
||||||
|
* @param firstSheetNumber first local sheet number
|
||||||
|
* @param lastSheetNumber last local sheet number
|
||||||
|
* @return index to extern sheet
|
||||||
|
*/
|
||||||
|
public short checkExternSheet(int firstSheetNumber, int lastSheetNumber){
|
||||||
|
return (short)getOrCreateLinkTable().checkExternSheet(firstSheetNumber, lastSheetNumber);
|
||||||
|
}
|
||||||
|
|
||||||
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
||||||
return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName);
|
return getOrCreateLinkTable().getExternalSheetIndex(workbookName, sheetName, sheetName);
|
||||||
|
}
|
||||||
|
public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) {
|
||||||
|
return getOrCreateLinkTable().getExternalSheetIndex(workbookName, firstSheetName, lastSheetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -383,7 +383,7 @@ final class LinkTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) {
|
||||||
SupBookRecord ebrTarget = null;
|
SupBookRecord ebrTarget = null;
|
||||||
int externalBookIndex = -1;
|
int externalBookIndex = -1;
|
||||||
for (int i=0; i<_externalBookBlocks.length; i++) {
|
for (int i=0; i<_externalBookBlocks.length; i++) {
|
||||||
|
@ -400,12 +400,13 @@ final class LinkTable {
|
||||||
if (ebrTarget == null) {
|
if (ebrTarget == null) {
|
||||||
throw new RuntimeException("No external workbook with name '" + workbookName + "'");
|
throw new RuntimeException("No external workbook with name '" + workbookName + "'");
|
||||||
}
|
}
|
||||||
int sheetIndex = getSheetIndex(ebrTarget.getSheetNames(), sheetName);
|
int firstSheetIndex = getSheetIndex(ebrTarget.getSheetNames(), firstSheetName);
|
||||||
|
int lastSheetIndex = getSheetIndex(ebrTarget.getSheetNames(), lastSheetName);
|
||||||
|
|
||||||
int result = _externSheetRecord.getRefIxForSheet(externalBookIndex, sheetIndex);
|
int result = _externSheetRecord.getRefIxForSheet(externalBookIndex, firstSheetIndex, lastSheetIndex);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
throw new RuntimeException("ExternSheetRecord does not contain combination ("
|
throw new RuntimeException("ExternSheetRecord does not contain combination ("
|
||||||
+ externalBookIndex + ", " + sheetIndex + ")");
|
+ externalBookIndex + ", " + firstSheetIndex + ", " + lastSheetIndex + ")");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -454,6 +455,9 @@ final class LinkTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int checkExternSheet(int sheetIndex) {
|
public int checkExternSheet(int sheetIndex) {
|
||||||
|
return checkExternSheet(sheetIndex, sheetIndex);
|
||||||
|
}
|
||||||
|
public int checkExternSheet(int firstSheetIndex, int lastSheetIndex) {
|
||||||
int thisWbIndex = -1; // this is probably always zero
|
int thisWbIndex = -1; // this is probably always zero
|
||||||
for (int i=0; i<_externalBookBlocks.length; i++) {
|
for (int i=0; i<_externalBookBlocks.length; i++) {
|
||||||
SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord();
|
SupBookRecord ebr = _externalBookBlocks[i].getExternalBookRecord();
|
||||||
|
@ -467,12 +471,12 @@ final class LinkTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Trying to find reference to this sheet
|
//Trying to find reference to this sheet
|
||||||
int i = _externSheetRecord.getRefIxForSheet(thisWbIndex, sheetIndex);
|
int i = _externSheetRecord.getRefIxForSheet(thisWbIndex, firstSheetIndex, lastSheetIndex);
|
||||||
if (i>=0) {
|
if (i>=0) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
//We haven't found reference to this sheet
|
//We haven't found reference to this sheet
|
||||||
return _externSheetRecord.addRef(thisWbIndex, sheetIndex, sheetIndex);
|
return _externSheetRecord.addRef(thisWbIndex, firstSheetIndex, lastSheetIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -612,7 +616,8 @@ final class LinkTable {
|
||||||
int numberOfNames = extBlock.getNumberOfNames();
|
int numberOfNames = extBlock.getNumberOfNames();
|
||||||
// a new name is inserted in the end of the SupBookRecord, after the last name
|
// a new name is inserted in the end of the SupBookRecord, after the last name
|
||||||
_workbookRecordList.add(supLinkIndex + numberOfNames, extNameRecord);
|
_workbookRecordList.add(supLinkIndex + numberOfNames, extNameRecord);
|
||||||
int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, -2 /* the scope is workbook*/);
|
int fakeSheetIdx = -2; /* the scope is workbook*/
|
||||||
|
int ix = _externSheetRecord.getRefIxForSheet(extBlockIndex, fakeSheetIdx, fakeSheetIdx);
|
||||||
return new NameXPtg(ix, nameIndex);
|
return new NameXPtg(ix, nameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,14 +276,15 @@ public class ExternSheetRecord extends StandardRecord {
|
||||||
return _list.size() - 1;
|
return _list.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRefIxForSheet(int externalBookIndex, int sheetIndex) {
|
public int getRefIxForSheet(int externalBookIndex, int firstSheetIndex, int lastSheetIndex) {
|
||||||
int nItems = _list.size();
|
int nItems = _list.size();
|
||||||
for (int i = 0; i < nItems; i++) {
|
for (int i = 0; i < nItems; i++) {
|
||||||
RefSubRecord ref = getRef(i);
|
RefSubRecord ref = getRef(i);
|
||||||
if (ref.getExtBookIndex() != externalBookIndex) {
|
if (ref.getExtBookIndex() != externalBookIndex) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (ref.getFirstSheetIndex() == sheetIndex && ref.getLastSheetIndex() == sheetIndex) {
|
if (ref.getFirstSheetIndex() == firstSheetIndex &&
|
||||||
|
ref.getLastSheetIndex() == lastSheetIndex) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ import org.apache.poi.ss.formula.FormulaParseException;
|
||||||
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
import org.apache.poi.ss.formula.FormulaParsingWorkbook;
|
||||||
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
|
||||||
import org.apache.poi.ss.formula.FormulaType;
|
import org.apache.poi.ss.formula.FormulaType;
|
||||||
|
import org.apache.poi.ss.formula.NameIdentifier;
|
||||||
import org.apache.poi.ss.formula.SheetIdentifier;
|
import org.apache.poi.ss.formula.SheetIdentifier;
|
||||||
|
import org.apache.poi.ss.formula.SheetRangeIdentifier;
|
||||||
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
import org.apache.poi.ss.formula.ptg.Area3DPtg;
|
||||||
import org.apache.poi.ss.formula.ptg.NamePtg;
|
import org.apache.poi.ss.formula.ptg.NamePtg;
|
||||||
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
import org.apache.poi.ss.formula.ptg.NameXPtg;
|
||||||
|
@ -69,7 +71,25 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||||
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
public int getExternalSheetIndex(String workbookName, String sheetName) {
|
||||||
return _iBook.getExternalSheetIndex(workbookName, sheetName);
|
return _iBook.getExternalSheetIndex(workbookName, sheetName);
|
||||||
}
|
}
|
||||||
|
public int getExternalSheetIndex(String workbookName, String firstSheetName, String lastSheetName) {
|
||||||
|
return _iBook.getExternalSheetIndex(workbookName, firstSheetName, lastSheetName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExternalSheetIndex(String workbookName, NameIdentifier sheetName) {
|
||||||
|
return getExternalSheetIndex(workbookName, sheetName.getName());
|
||||||
|
}
|
||||||
|
public int getExternalSheetIndex(String workbookName, NameIdentifier firstSheetName, NameIdentifier lastSheetName) {
|
||||||
|
return getExternalSheetIndex(workbookName, firstSheetName.getName(), lastSheetName.getName());
|
||||||
|
}
|
||||||
|
public int getExternalSheetIndex(NameIdentifier sheetName) {
|
||||||
|
return getExternalSheetIndex(sheetName.getName());
|
||||||
|
}
|
||||||
|
public int getExternalSheetIndex(NameIdentifier firstSheetName, NameIdentifier lastSheetName) {
|
||||||
|
int firstSheetIndex = _uBook.getSheetIndex(firstSheetName.getName());
|
||||||
|
int lastSheetIndex = _uBook.getSheetIndex(lastSheetName.getName());
|
||||||
|
return _iBook.checkExternSheet(firstSheetIndex, lastSheetIndex);
|
||||||
|
}
|
||||||
|
|
||||||
public Ptg get3DReferencePtg(CellReference cr, SheetIdentifier sheet) {
|
public Ptg get3DReferencePtg(CellReference cr, SheetIdentifier sheet) {
|
||||||
int extIx = getSheetExtIx(sheet);
|
int extIx = getSheetExtIx(sheet);
|
||||||
return new Ref3DPtg(cr, extIx);
|
return new Ref3DPtg(cr, extIx);
|
||||||
|
@ -235,11 +255,25 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
|
||||||
if (sheetIden == null) {
|
if (sheetIden == null) {
|
||||||
extIx = -1;
|
extIx = -1;
|
||||||
} else {
|
} else {
|
||||||
String sName = sheetIden.getSheetIdentifier().getName();
|
NameIdentifier sheetName = sheetIden.getSheetIdentifier();
|
||||||
|
NameIdentifier lastSheetName = null;
|
||||||
|
|
||||||
|
if (sheetIden instanceof SheetRangeIdentifier) {
|
||||||
|
lastSheetName = ((SheetRangeIdentifier)sheetIden).getLastSheetIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
if (sheetIden.getBookName() == null) {
|
if (sheetIden.getBookName() == null) {
|
||||||
extIx = getExternalSheetIndex(sName);
|
if (lastSheetName == null) {
|
||||||
|
extIx = getExternalSheetIndex(sheetName);
|
||||||
|
} else {
|
||||||
|
extIx = getExternalSheetIndex(sheetName, lastSheetName);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
extIx = getExternalSheetIndex(sheetIden.getBookName(), sName);
|
if (lastSheetName == null) {
|
||||||
|
extIx = getExternalSheetIndex(sheetIden.getBookName(), sheetName);
|
||||||
|
} else {
|
||||||
|
extIx = getExternalSheetIndex(sheetIden.getBookName(), sheetName, lastSheetName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return extIx;
|
return extIx;
|
||||||
|
|
|
@ -283,16 +283,15 @@ public final class TestXSSFFormulaParser {
|
||||||
|
|
||||||
|
|
||||||
// Check things parse as expected:
|
// Check things parse as expected:
|
||||||
// Note - Ptgs will only show one sheet, the formula
|
// TODO Fix it so that the Pxgs get the second sheet too!
|
||||||
// parser stuff looks up the second later
|
|
||||||
|
|
||||||
|
|
||||||
// SUM to one cell over 3 workbooks, relative reference
|
// SUM to one cell over 3 workbooks, relative reference
|
||||||
ptgs = parse(fpb, "SUM(Sheet1:Sheet3!A1)");
|
ptgs = parse(fpb, "SUM(Sheet1:Sheet3!A1)");
|
||||||
assertEquals(2, ptgs.length);
|
assertEquals(2, ptgs.length);
|
||||||
if (wb instanceof HSSFWorkbook) {
|
if (wb instanceof HSSFWorkbook) {
|
||||||
assertEquals(Ref3DPtg.class, ptgs[0].getClass());
|
assertEquals(Ref3DPtg.class, ptgs[0].getClass());
|
||||||
assertEquals("Sheet1!A1", toFormulaString(ptgs[0], fpb));
|
assertEquals("Sheet1:Sheet3!A1", toFormulaString(ptgs[0], fpb));
|
||||||
} else {
|
} else {
|
||||||
assertEquals(Ref3DPxg.class, ptgs[0].getClass());
|
assertEquals(Ref3DPxg.class, ptgs[0].getClass());
|
||||||
assertEquals("Sheet1!A1", toFormulaString(ptgs[0], fpb));
|
assertEquals("Sheet1!A1", toFormulaString(ptgs[0], fpb));
|
||||||
|
@ -305,8 +304,8 @@ public final class TestXSSFFormulaParser {
|
||||||
ptgs = parse(fpb, "MAX(Sheet1:Sheet3!A$1)");
|
ptgs = parse(fpb, "MAX(Sheet1:Sheet3!A$1)");
|
||||||
assertEquals(2, ptgs.length);
|
assertEquals(2, ptgs.length);
|
||||||
if (wb instanceof HSSFWorkbook) {
|
if (wb instanceof HSSFWorkbook) {
|
||||||
assertEquals(Ref3DPtg.class, ptgs[0].getClass());
|
assertEquals(Ref3DPtg.class, ptgs[0].getClass());
|
||||||
assertEquals("Sheet1!A$1", toFormulaString(ptgs[0], fpb));
|
assertEquals("Sheet1:Sheet3!A$1", toFormulaString(ptgs[0], fpb));
|
||||||
} else {
|
} else {
|
||||||
assertEquals(Ref3DPxg.class, ptgs[0].getClass());
|
assertEquals(Ref3DPxg.class, ptgs[0].getClass());
|
||||||
assertEquals("Sheet1!A$1", toFormulaString(ptgs[0], fpb));
|
assertEquals("Sheet1!A$1", toFormulaString(ptgs[0], fpb));
|
||||||
|
@ -319,14 +318,20 @@ public final class TestXSSFFormulaParser {
|
||||||
ptgs = parse(fpb, "MIN(Sheet1:Sheet3!$A$1)");
|
ptgs = parse(fpb, "MIN(Sheet1:Sheet3!$A$1)");
|
||||||
assertEquals(2, ptgs.length);
|
assertEquals(2, ptgs.length);
|
||||||
if (wb instanceof HSSFWorkbook) {
|
if (wb instanceof HSSFWorkbook) {
|
||||||
assertEquals(Ref3DPtg.class, ptgs[0].getClass());
|
assertEquals(Ref3DPtg.class, ptgs[0].getClass());
|
||||||
assertEquals("Sheet1!$A$1", toFormulaString(ptgs[0], fpb));
|
assertEquals("Sheet1:Sheet3!$A$1", toFormulaString(ptgs[0], fpb));
|
||||||
} else {
|
} else {
|
||||||
assertEquals(Ref3DPxg.class, ptgs[0].getClass());
|
assertEquals(Ref3DPxg.class, ptgs[0].getClass());
|
||||||
assertEquals("Sheet1!$A$1", toFormulaString(ptgs[0], fpb));
|
assertEquals("Sheet1!$A$1", toFormulaString(ptgs[0], fpb));
|
||||||
}
|
}
|
||||||
assertEquals(FuncVarPtg.class, ptgs[1].getClass());
|
assertEquals(FuncVarPtg.class, ptgs[1].getClass());
|
||||||
assertEquals("MIN", toFormulaString(ptgs[1], fpb));
|
assertEquals("MIN", toFormulaString(ptgs[1], fpb));
|
||||||
|
|
||||||
|
|
||||||
|
// Check we can round-trip - try to set a new one to a new cell
|
||||||
|
Cell newF = s1.getRow(0).createCell(10, Cell.CELL_TYPE_FORMULA);
|
||||||
|
newF.setCellFormula("SUM(Sheet2:Sheet3!A1)");
|
||||||
|
assertEquals("SUM(Sheet2:Sheet3!A1)", newF.getCellFormula());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static String toFormulaString(Ptg ptg, FormulaParsingWorkbook wb) {
|
private static String toFormulaString(Ptg ptg, FormulaParsingWorkbook wb) {
|
||||||
|
|
|
@ -476,10 +476,9 @@ public final class TestFormulaParser extends TestCase {
|
||||||
assertEquals("\'Test Sheet\'!A1", formula);
|
assertEquals("\'Test Sheet\'!A1", formula);
|
||||||
|
|
||||||
// Now both
|
// Now both
|
||||||
// TODO Implement remaining logic for #55906
|
|
||||||
cell.setCellFormula("Cash_Flow:\'Test Sheet\'!A1");
|
cell.setCellFormula("Cash_Flow:\'Test Sheet\'!A1");
|
||||||
formula = cell.getCellFormula();
|
formula = cell.getCellFormula();
|
||||||
// assertEquals("Cash_Flow:\'Test Sheet\'!A1", formula);
|
assertEquals("Cash_Flow:\'Test Sheet\'!A1", formula);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue