]> source.dussan.org Git - poi.git/commitdiff
Start to add XSSF specific handling for NameX (named ranges or functions from another...
authorNick Burch <nick@apache.org>
Sat, 19 Jul 2014 20:30:31 +0000 (20:30 +0000)
committerNick Burch <nick@apache.org>
Sat, 19 Jul 2014 20:30:31 +0000 (20:30 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1611958 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/formula/FormulaParser.java
src/java/org/apache/poi/ss/formula/FormulaParsingWorkbook.java
src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java
src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java [new file with mode: 0644]
src/java/org/apache/poi/ss/formula/ptg/NameXPtg.java
src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java

index 570dd5bcaa6772aaefb73ff495dc19b9672c35fa..51f1a50b1d2dc8f76e8b24ffd43962b89ea9761a 100644 (file)
@@ -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");
index ef2256025e8caa22f274089685cc7c503ec4e1f4..a2be6f8f2e0b9113c780648f0cad0f85c3d3300d 100644 (file)
@@ -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
index 3b25240006c341f1f078c51adb8c02720478953e..4a7ac7a8ef2aee1abecd9c131e6d01f783e0e87f 100644 (file)
@@ -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");
-            }
-            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);
+    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);
+                }
             }
-         }
-         return ErrorEval.REF_INVALID;
-      }catch(WorkbookNotFoundException wnfe){
-         return ErrorEval.REF_INVALID;
-      }
+            return ErrorEval.REF_INVALID;
+        } catch(WorkbookNotFoundException wnfe){
+            return ErrorEval.REF_INVALID;
+        }
    }
 }
index 41a11c95d8591a61e47ae02c2f3b1486ff71b361..ec3f984315500af30a17cec69fc1fd9c84e359da 100644 (file)
@@ -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);
diff --git a/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Area3DPxg.java
new file mode 100644 (file)
index 0000000..84872f5
--- /dev/null
@@ -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");
+    }
+
+}
index e604fbe102ca26158b92181e7c4816a631b7c59a..de88d1b8c21896d3f9794fd455efa368683a2d60 100644 (file)
@@ -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;
diff --git a/src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java b/src/java/org/apache/poi/ss/formula/ptg/NameXPxg.java
new file mode 100644 (file)
index 0000000..62e56c2
--- /dev/null
@@ -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");
+    }
+}
index 9dd475b047c9e721ea9c2ac3747f93400345f1d3..0014693f27a4405f09982a9ff57a169ec2e23a72 100644 (file)
@@ -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) {