Move towards supporting same workbook named ranges in external style for xssf

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611961 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-07-19 20:51:23 +00:00
parent 13628c0b8c
commit a62dd1bf8f
4 changed files with 61 additions and 37 deletions

View File

@ -373,6 +373,9 @@ public final class FormulaParser {
* 123.456 * 123.456
* "abc" * "abc"
* true * true
* [Foo.xls]!$A$1
* [Foo.xls]'my sheet'!$A$1
* [Foo.xls]!my.named.range
* </pre> * </pre>
* *
*/ */
@ -768,7 +771,6 @@ public final class FormulaParser {
* @return The sheet name as an identifier <code>null</code> if '!' is not found in the right place * @return The sheet name as an identifier <code>null</code> if '!' is not found in the right place
*/ */
private SheetIdentifier parseSheetName() { private SheetIdentifier parseSheetName() {
String bookName; String bookName;
if (look == '[') { if (look == '[') {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -823,6 +825,11 @@ public final class FormulaParser {
} }
return null; return null;
} }
if (look == '!' && bookName != null) {
// Raw book reference, wihtout a sheet
GetChar();
return new SheetIdentifier(bookName, null);
}
return null; return null;
} }

View File

@ -74,7 +74,9 @@ public final class NameXPxg extends OperandPtg {
sb.append(externalWorkbookNumber); sb.append(externalWorkbookNumber);
sb.append(']'); sb.append(']');
} }
if (sheetName != null) {
sb.append(sheetName); sb.append(sheetName);
}
sb.append('!'); sb.append('!');
sb.append(nameName); sb.append(nameName);
return sb.toString(); return sb.toString();

View File

@ -84,16 +84,18 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
} }
private int resolveBookIndex(String bookName) { private int resolveBookIndex(String bookName) {
// Is it already in numeric form? // Strip the [] wrapper, if still present
if (bookName.startsWith("[") && bookName.endsWith("]")) { if (bookName.startsWith("[") && bookName.endsWith("]")) {
bookName = bookName.substring(1, bookName.length()-2); bookName = bookName.substring(1, bookName.length()-2);
}
// Is it already in numeric form?
try { try {
return Integer.parseInt(bookName); return Integer.parseInt(bookName);
} catch (NumberFormatException e) {} } catch (NumberFormatException e) {}
}
// Look up an External Link Table for this name // Look up an External Link Table for this name
throw new RuntimeException("Not implemented yet"); // TODO throw new RuntimeException("Not implemented yet for book " + bookName); // TODO
} }
public EvaluationName getName(String name, int sheetIndex) { public EvaluationName getName(String name, int sheetIndex) {
@ -129,6 +131,13 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
} }
// Otherwise, try it as a named range // Otherwise, try it as a named range
if (sheet._sheetIdentifier == null) {
// Workbook + Named Range only
int bookIndex = resolveBookIndex(sheet._bookName);
return new NameXPxg(bookIndex, null, name);
}
// Use the sheetname and process
String sheetName = sheet._sheetIdentifier.getName(); String sheetName = sheet._sheetIdentifier.getName();
if (sheet._bookName != null) { if (sheet._bookName != null) {

View File

@ -26,6 +26,7 @@ import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType; import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.ptg.FuncPtg; import org.apache.poi.ss.formula.ptg.FuncPtg;
import org.apache.poi.ss.formula.ptg.IntPtg; import org.apache.poi.ss.formula.ptg.IntPtg;
import org.apache.poi.ss.formula.ptg.NameXPxg;
import org.apache.poi.ss.formula.ptg.Ptg; import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.Ref3DPxg; import org.apache.poi.ss.formula.ptg.Ref3DPxg;
import org.apache.poi.ss.formula.ptg.RefPtg; import org.apache.poi.ss.formula.ptg.RefPtg;
@ -95,6 +96,24 @@ public final class TestXSSFFormulaParser {
assertTrue("", ptgs[1] instanceof FuncPtg); assertTrue("", ptgs[1] instanceof FuncPtg);
} }
@Test
public void formaulReferncesSameWorkbook() {
// Use a test file with "other workbook" style references
// to itself
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx");
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
Ptg[] ptgs;
// Reference to a named range in our own workbook, as if it
// were defined in a different workbook
ptgs = parse(fpb, "[0]!NR_Global_B2");
assertEquals(1, ptgs.length);
assertEquals(NameXPxg.class, ptgs[0].getClass());
assertEquals(null, ((NameXPxg)ptgs[0]).getSheetName());
assertEquals("NR_Global_B2",((NameXPxg)ptgs[0]).getNameName());
assertEquals("[0]!NR_Global_B2",((NameXPxg)ptgs[0]).toFormulaString());
}
@Test @Test
@Ignore("Work in progress, see bug #56737") @Ignore("Work in progress, see bug #56737")
public void formulaReferencesOtherSheets() { public void formulaReferencesOtherSheets() {
@ -113,7 +132,10 @@ public final class TestXSSFFormulaParser {
// Reference to a sheet scoped named range from another sheet // Reference to a sheet scoped named range from another sheet
ptgs = parse(fpb, "Defines!NR_To_A1"); ptgs = parse(fpb, "Defines!NR_To_A1");
assertEquals(1, ptgs.length); assertEquals(1, ptgs.length);
// TODO assert assertEquals(NameXPxg.class, ptgs[0].getClass());
assertEquals("Defines", ((NameXPxg)ptgs[0]).getSheetName());
assertEquals("NR_To_A1",((NameXPxg)ptgs[0]).getNameName());
assertEquals("Defines!NR_To_A1",((NameXPxg)ptgs[0]).toFormulaString());
// Reference to a workbook scoped named range // Reference to a workbook scoped named range
ptgs = parse(fpb, "NR_Global_B2"); ptgs = parse(fpb, "NR_Global_B2");
@ -121,22 +143,6 @@ public final class TestXSSFFormulaParser {
// TODO assert // TODO assert
} }
@Test
@Ignore("Work in progress, see bug #56737")
public void fFormaulReferncesSameWorkbook() {
// Use a test file with "other workbook" style references
// to itself
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56737.xlsx");
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
Ptg[] ptgs;
// Reference to a named range in our own workbook, as if it
// were defined in a different workbook
ptgs = parse(fpb, "[0]!NR_Global_B2");
assertEquals(1, ptgs.length);
// TODO assert
}
@Test @Test
@Ignore("Work in progress, see bug #56737") @Ignore("Work in progress, see bug #56737")
public void formulaReferencesOtherWorkbook() { public void formulaReferencesOtherWorkbook() {