]> source.dussan.org Git - poi.git/commitdiff
Update the formula evaluator to support XSSF style external named ranges too
authorNick Burch <nick@apache.org>
Sun, 20 Jul 2014 17:51:51 +0000 (17:51 +0000)
committerNick Burch <nick@apache.org>
Sun, 20 Jul 2014 17:51:51 +0000 (17:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1612133 13f79535-47bb-0310-9956-ffa450edef68

14 files changed:
src/java/org/apache/poi/hssf/usermodel/HSSFEvaluationWorkbook.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
src/java/org/apache/poi/ss/formula/EvaluationWorkbook.java
src/java/org/apache/poi/ss/formula/FormulaShifter.java
src/java/org/apache/poi/ss/formula/OperationEvaluationContext.java
src/java/org/apache/poi/ss/formula/UserDefinedFunction.java
src/java/org/apache/poi/ss/formula/WorkbookEvaluator.java
src/java/org/apache/poi/ss/formula/eval/forked/ForkedEvaluationWorkbook.java
src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java
src/testcases/org/apache/poi/hssf/model/TestSheet.java
src/testcases/org/apache/poi/ss/formula/TestFormulaShifter.java

index 199f7ca3c30f510209f4557b0d7ab898aa0e5fef..748b42a43d1d0ac5f011eeb3cae818643634c971 100644 (file)
@@ -146,6 +146,10 @@ public final class HSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
         return _iBook.getExternalName(externSheetIndex, externNameIndex);
     }
 
+    public ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber) {
+        throw new IllegalStateException("XSSF-style external names are not supported for HSSF");
+    }
+
     public String resolveNameXText(NameXPtg n) {
         return _iBook.resolveNameXText(n.getSheetRefIndex(), n.getNameIndex());
     }
index 170c015ac532788324f993b41090278209901b8c..ff33868c57f7b2ba06a52bac3cbe139a1cb8012a 100644 (file)
@@ -1504,8 +1504,10 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
         // Update any formulas on this sheet that point to
         //  rows which have been moved
         int sheetIndex = _workbook.getSheetIndex(this);
+        String sheetName = _workbook.getSheetName(sheetIndex);
         short externSheetIndex = _book.checkExternSheet(sheetIndex);
-        FormulaShifter shifter = FormulaShifter.createForRowShift(externSheetIndex, startRow, endRow, n);
+        FormulaShifter shifter = FormulaShifter.createForRowShift(
+                         externSheetIndex, sheetName, startRow, endRow, n);
         _sheet.updateFormulasAfterCellShift(shifter, externSheetIndex);
 
         int nSheets = _workbook.getNumberOfSheets();
index f91dacf0de853fdd1a1eebe56b2e96cb54132486..855ae5929c60483ea6d2d869e3bfdfee3ff1ceea 100644 (file)
@@ -59,7 +59,15 @@ public interface EvaluationWorkbook {
      */
     int convertFromExternSheetIndex(int externSheetIndex);
 
+    /**
+     * HSSF Only - fetch the external-style name details
+     */
     ExternalName getExternalName(int externSheetIndex, int externNameIndex);
+    /**
+     * XSSF Only - fetch the external-style name details
+     */
+    ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber);
+    
     EvaluationName getName(NamePtg namePtg);
     EvaluationName getName(String name, int sheetIndex);
     String resolveNameXText(NameXPtg ptg);
index 74804a8845bbe4d4316170e64d72298f8c7531d1..9439000d235212d91c4e3680bd1dd57fef98dba6 100644 (file)
 
 package org.apache.poi.ss.formula;
 
-import org.apache.poi.ss.formula.ptg.*;
+import org.apache.poi.ss.formula.ptg.Area2DPtgBase;
+import org.apache.poi.ss.formula.ptg.Area3DPtg;
+import org.apache.poi.ss.formula.ptg.Area3DPxg;
+import org.apache.poi.ss.formula.ptg.AreaErrPtg;
+import org.apache.poi.ss.formula.ptg.AreaPtg;
+import org.apache.poi.ss.formula.ptg.AreaPtgBase;
+import org.apache.poi.ss.formula.ptg.Deleted3DPxg;
+import org.apache.poi.ss.formula.ptg.DeletedArea3DPtg;
+import org.apache.poi.ss.formula.ptg.DeletedRef3DPtg;
+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.formula.ptg.RefErrorPtg;
+import org.apache.poi.ss.formula.ptg.RefPtg;
+import org.apache.poi.ss.formula.ptg.RefPtgBase;
 
 
 /**
- * @author Josh Micich
+ * Updates Formulas as rows or sheets are shifted
  */
 public final class FormulaShifter {
 
@@ -31,9 +45,16 @@ public final class FormulaShifter {
     }
 
        /**
-        * Extern sheet index of sheet where moving is occurring
+        * Extern sheet index of sheet where moving is occurring,
+        *  used for updating HSSF style 3D references
         */
        private final int _externSheetIndex;
+       /**
+        * Sheet name of the sheet where moving is occurring, 
+        *  used for updating XSSF style 3D references on row shifts.
+        */
+       private final String _sheetName;
+       
        private final int _firstMovedIndex;
        private final int _lastMovedIndex;
        private final int _amountToMove;
@@ -48,7 +69,7 @@ public final class FormulaShifter {
      *
      * For example, this will be called on {@link org.apache.poi.hssf.usermodel.HSSFSheet#shiftRows(int, int, int)} }
      */
-       private FormulaShifter(int externSheetIndex, int firstMovedIndex, int lastMovedIndex, int amountToMove) {
+       private FormulaShifter(int externSheetIndex, String sheetName, int firstMovedIndex, int lastMovedIndex, int amountToMove) {
                if (amountToMove == 0) {
                        throw new IllegalArgumentException("amountToMove must not be zero");
                }
@@ -56,6 +77,7 @@ public final class FormulaShifter {
                        throw new IllegalArgumentException("firstMovedIndex, lastMovedIndex out of order");
                }
                _externSheetIndex = externSheetIndex;
+               _sheetName = sheetName;
                _firstMovedIndex = firstMovedIndex;
                _lastMovedIndex = lastMovedIndex;
                _amountToMove = amountToMove;
@@ -71,14 +93,15 @@ public final class FormulaShifter {
      */
     private FormulaShifter(int srcSheetIndex, int dstSheetIndex) {
         _externSheetIndex = _firstMovedIndex = _lastMovedIndex = _amountToMove = -1;
+        _sheetName = null;
 
         _srcSheetIndex = srcSheetIndex;
         _dstSheetIndex = dstSheetIndex;
         _mode = ShiftMode.Sheet;
     }
 
-       public static FormulaShifter createForRowShift(int externSheetIndex, int firstMovedRowIndex, int lastMovedRowIndex, int numberOfRowsToMove) {
-               return new FormulaShifter(externSheetIndex, firstMovedRowIndex, lastMovedRowIndex, numberOfRowsToMove);
+       public static FormulaShifter createForRowShift(int externSheetIndex, String sheetName, int firstMovedRowIndex, int lastMovedRowIndex, int numberOfRowsToMove) {
+               return new FormulaShifter(externSheetIndex, sheetName, firstMovedRowIndex, lastMovedRowIndex, numberOfRowsToMove);
        }
 
     public static FormulaShifter createForSheetShift(int srcSheetIndex, int dstSheetIndex) {
@@ -145,6 +168,14 @@ public final class FormulaShifter {
                        }
                        return rowMoveRefPtg(rptg);
                }
+               if(ptg instanceof Ref3DPxg) {
+                   Ref3DPxg rpxg = (Ref3DPxg)ptg;
+                   if (rpxg.getExternalWorkbookNumber() > 0 ||
+                          ! _sheetName.equals(rpxg.getSheetName())) {
+                // only move 3D refs that refer to the sheet with cells being moved
+                   }
+            return rowMoveRefPtg(rpxg);
+               }
                if(ptg instanceof Area2DPtgBase) {
                        if (currentExternSheetIx != _externSheetIndex) {
                                // local refs on other sheets are unaffected
@@ -161,6 +192,15 @@ public final class FormulaShifter {
                        }
                        return rowMoveAreaPtg(aptg);
                }
+        if(ptg instanceof Area3DPxg) {
+            Area3DPxg apxg = (Area3DPxg)ptg;
+            if (apxg.getExternalWorkbookNumber() > 0 ||
+                    ! _sheetName.equals(apxg.getSheetName())) {
+                // only move 3D refs that refer to the sheet with cells being moved
+                return null;
+            }
+            return rowMoveAreaPtg(apxg);
+        }
                return null;
        }
 
@@ -348,6 +388,14 @@ public final class FormulaShifter {
                        Area3DPtg area3DPtg = (Area3DPtg) ptg;
                        return new DeletedArea3DPtg(area3DPtg.getExternSheetIndex());
                }
+        if (ptg instanceof Ref3DPxg) {
+            Ref3DPxg pxg = (Ref3DPxg)ptg;
+            return new Deleted3DPxg(pxg.getExternalWorkbookNumber(), pxg.getSheetName());
+        }
+        if (ptg instanceof Area3DPxg) {
+            Area3DPxg pxg = (Area3DPxg)ptg;
+            return new Deleted3DPxg(pxg.getExternalWorkbookNumber(), pxg.getSheetName());
+        }
 
                throw new IllegalArgumentException("Unexpected ref ptg class (" + ptg.getClass().getName() + ")");
        }
index 4a7ac7a8ef2aee1abecd9c131e6d01f783e0e87f..ab8720822753818cb9b2d4d6ebf610ac610bb5e7 100644 (file)
@@ -23,7 +23,8 @@ 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.ExternalNameEval;
+import org.apache.poi.ss.formula.eval.FunctionNameEval;
 import org.apache.poi.ss.formula.eval.RefEval;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.FreeRefFunction;
@@ -299,32 +300,82 @@ public final class OperationEvaluationContext {
     }
     
     public ValueEval getNameXEval(NameXPtg nameXPtg) {
+        // Is the name actually on our workbook?
         ExternalSheet externSheet = _workbook.getExternalSheet(nameXPtg.getSheetRefIndex());
         if(externSheet == null || externSheet.getWorkbookName() == null) {
             // External reference to our own workbook's name
-            return new NameXEval(nameXPtg);
+            return getLocalNameXEval(nameXPtg);
         }
         
+        // Look it up for the external workbook
         String workbookName = externSheet.getWorkbookName();
         ExternalName externName = _workbook.getExternalName(
               nameXPtg.getSheetRefIndex(), 
               nameXPtg.getNameIndex()
         );
-        return getNameXEval(externName, workbookName);
+        return getExternalNameXEval(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);
+            return getLocalNameXEval(nameXPxg);
         }
   
-        // TODO
-        return null;
-//        return getNameXEval(nameXPxg.getNameName(), externSheet.getWorkbookName());
+        // Look it up for the external workbook
+        String workbookName = externSheet.getWorkbookName();
+        ExternalName externName = _workbook.getExternalName(
+              nameXPxg.getNameName(),
+              nameXPxg.getSheetName(),
+              nameXPxg.getExternalWorkbookNumber()
+        );
+        return getExternalNameXEval(externName, workbookName);
+       }
+       
+    private ValueEval getLocalNameXEval(NameXPxg nameXPxg) {
+        // Look up the sheet, if present
+        int sIdx = -1;
+        if (nameXPxg.getSheetName() != null) {
+            sIdx = _workbook.getSheetIndex(nameXPxg.getSheetName());
+        }
+        
+        // Is it a name or a function?
+        String name = nameXPxg.getNameName();
+        EvaluationName evalName = _workbook.getName(name, sIdx);
+        if (evalName != null) {
+            // Process it as a name
+            return new ExternalNameEval(evalName);
+        } else {
+            // Must be an external function
+            return new FunctionNameEval(name);
+        }
+    }
+       private ValueEval getLocalNameXEval(NameXPtg nameXPtg) {
+        String name = _workbook.resolveNameXText(nameXPtg);
+        
+        // Try to parse it as a name
+        int sheetNameAt = name.indexOf('!'); 
+        EvaluationName evalName = null;
+        if (sheetNameAt > -1) {
+            // Sheet based name
+            String sheetName = name.substring(0, sheetNameAt);
+            String nameName = name.substring(sheetNameAt+1);
+            evalName = _workbook.getName(nameName, _workbook.getSheetIndex(sheetName));
+        } else {
+            // Workbook based name
+            evalName = _workbook.getName(name, -1);
+        }
+        
+        if (evalName != null) {
+            // Process it as a name
+            return new ExternalNameEval(evalName);
+        } else {
+            // Must be an external function
+            return new FunctionNameEval(name);
+        }
        }
-    private ValueEval getNameXEval(ExternalName externName, String workbookName) {
+       
+    private ValueEval getExternalNameXEval(ExternalName externName, String workbookName) {
         try {
             WorkbookEvaluator refWorkbookEvaluator = _bookEvaluator.getOtherWorkbookEvaluator(workbookName);
             EvaluationName evaluationName = refWorkbookEvaluator.getName(externName.getName(),externName.getIx()-1);
index 47df90a00dc2f4029db287bf4d98d87dc39685fc..c52613755452550291929105b6ef613907dcd9ca 100644 (file)
@@ -17,7 +17,7 @@
 
 package org.apache.poi.ss.formula;
 
-import org.apache.poi.ss.formula.eval.NameEval;
+import org.apache.poi.ss.formula.eval.FunctionNameEval;
 import org.apache.poi.ss.formula.eval.NotImplementedFunctionException;
 import org.apache.poi.ss.formula.eval.ValueEval;
 import org.apache.poi.ss.formula.functions.FreeRefFunction;
@@ -45,8 +45,8 @@ final class UserDefinedFunction implements FreeRefFunction {
 
                ValueEval nameArg = args[0];
                String functionName;
-               if (nameArg instanceof NameEval) {
-                       functionName = ((NameEval) nameArg).getFunctionName();
+               if (nameArg instanceof FunctionNameEval) {
+                       functionName = ((FunctionNameEval) nameArg).getFunctionName();
                } else {
                        throw new RuntimeException("First argument should be a NameEval, but got ("
                                        + nameArg.getClass().getName() + ")");
index 6dd5dd20687d8923ec011213ee321061bdb1090e..4cbcee40cff03c61263a02afc9bc749691d7640d 100644 (file)
@@ -30,10 +30,10 @@ import org.apache.poi.ss.formula.eval.BlankEval;
 import org.apache.poi.ss.formula.eval.BoolEval;
 import org.apache.poi.ss.formula.eval.ErrorEval;
 import org.apache.poi.ss.formula.eval.EvaluationException;
+import org.apache.poi.ss.formula.eval.ExternalNameEval;
 import org.apache.poi.ss.formula.eval.FunctionEval;
+import org.apache.poi.ss.formula.eval.FunctionNameEval;
 import org.apache.poi.ss.formula.eval.MissingArgEval;
-import org.apache.poi.ss.formula.eval.NameEval;
-import org.apache.poi.ss.formula.eval.NameXEval;
 import org.apache.poi.ss.formula.eval.NotImplementedException;
 import org.apache.poi.ss.formula.eval.NumberEval;
 import org.apache.poi.ss.formula.eval.OperandResolver;
@@ -638,37 +638,13 @@ public final class WorkbookEvaluator {
            EvaluationName nameRecord = _workbook.getName(namePtg);
            return getEvalForNameRecord(nameRecord, ec);
        }
-       if (ptg instanceof NameXPtg) { // TODO Generalise for NameXPxg
+       if (ptg instanceof NameXPtg) {
            // Externally defined named ranges or macro functions
-           NameXPtg nameXPtg = (NameXPtg)ptg;
-           ValueEval eval = ec.getNameXEval(nameXPtg);
-
-           if (eval instanceof NameXEval) {
-               // Could not be directly evaluated, so process as a name
-               return getEvalForNameX(nameXPtg, ec);
-           } else {
-               // Use the evaluated version
-               return eval;
-           }
+           return processNameEval(ec.getNameXEval((NameXPtg)ptg), ec);
        }
        if (ptg instanceof NameXPxg) {
-           // TODO This is a temporary hack....
-           NameXPxg pxg = (NameXPxg)ptg;
-           int sIdx = -1;
-           if (pxg.getSheetName() != null) {
-               sIdx = _workbook.getSheetIndex(pxg.getSheetName());
-           }
-           EvaluationName evalName = _workbook.getName(pxg.getNameName(), sIdx);
-           if (evalName == null) {
-               // We don't know about that name, sorry
-               // TODO What about UDFs?
-               logInfo("Unknown Name referenced: " + pxg.getNameName());
-               return ErrorEval.NAME_INVALID;
-           }
-           
-           int nIdx = evalName.createPtg().getIndex();
-           NameXPtg nptg = new NameXPtg(sIdx, nIdx);
-           return getEvalForPtg(nptg, ec);
+           // Externally defined named ranges or macro functions
+           return processNameEval(ec.getNameXEval((NameXPxg)ptg), ec);
        }
 
        if (ptg instanceof IntPtg) {
@@ -728,10 +704,18 @@ public final class WorkbookEvaluator {
 
        throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
     }
+   
+   private ValueEval processNameEval(ValueEval eval, OperationEvaluationContext ec) {
+       if (eval instanceof ExternalNameEval) {
+           EvaluationName name = ((ExternalNameEval)eval).getName();
+           return getEvalForNameRecord(name, ec);
+       }
+       return eval;
+   }
        
     private ValueEval getEvalForNameRecord(EvaluationName nameRecord, OperationEvaluationContext ec) {
         if (nameRecord.isFunctionName()) {
-            return new NameEval(nameRecord.getNameText());
+            return new FunctionNameEval(nameRecord.getNameText());
         }
         if (nameRecord.hasFormula()) {
             return evaluateNameFormula(nameRecord.getNameDefinition(), ec);
@@ -739,30 +723,6 @@ public final class WorkbookEvaluator {
 
         throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'");
     }
-    private ValueEval getEvalForNameX(NameXPtg nameXPtg, OperationEvaluationContext ec) {
-        String name = _workbook.resolveNameXText(nameXPtg);
-        
-        // Try to parse it as a name
-        int sheetNameAt = name.indexOf('!'); 
-        EvaluationName nameRecord = null;
-        if (sheetNameAt > -1) {
-            // Sheet based name
-            String sheetName = name.substring(0, sheetNameAt);
-            String nameName = name.substring(sheetNameAt+1);
-            nameRecord = _workbook.getName(nameName, _workbook.getSheetIndex(sheetName));
-        } else {
-            // Workbook based name
-            nameRecord = _workbook.getName(name, -1);
-        }
-        
-        if (nameRecord != null) {
-            // Process it as a name
-            return getEvalForNameRecord(nameRecord, ec);
-        } else {
-            // Must be an external function
-            return new NameEval(name);
-        }
-    }
     
     /**
      * YK: Used by OperationEvaluationContext to resolve indirect names.
index 442b74859375cb0f3572150e6fecfe2ff9992128..93d3ec556555428471317341fa9d5fda5c590d4f 100644 (file)
@@ -117,8 +117,11 @@ final class ForkedEvaluationWorkbook implements EvaluationWorkbook {
        public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
           return _masterBook.getExternalName(externSheetIndex, externNameIndex);
        }
+       public ExternalName getExternalName(String nameName, String sheetName, int externalWorkbookNumber) {
+              return _masterBook.getExternalName(nameName, sheetName, externalWorkbookNumber);
+    }
 
-       public int getSheetIndex(EvaluationSheet sheet) {
+    public int getSheetIndex(EvaluationSheet sheet) {
                if (sheet instanceof ForkedEvaluationSheet) {
                        ForkedEvaluationSheet mes = (ForkedEvaluationSheet) sheet;
                        return mes.getSheetIndex(_masterBook);
diff --git a/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java b/src/java/org/apache/poi/ss/formula/ptg/Deleted3DPxg.java
new file mode 100644 (file)
index 0000000..772e10b
--- /dev/null
@@ -0,0 +1,87 @@
+/* ====================================================================
+   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.usermodel.ErrorConstants;
+import org.apache.poi.util.LittleEndianOutput;
+
+
+/**
+ * An XSSF only representation of a reference to a deleted area
+ */
+public final class Deleted3DPxg extends OperandPtg {
+    private int externalWorkbookNumber = -1;
+    private String sheetName;
+
+    public Deleted3DPxg(int externalWorkbookNumber, String sheetName) {
+        this.externalWorkbookNumber = externalWorkbookNumber;
+        this.sheetName = sheetName;
+    }
+    public Deleted3DPxg(String sheetName) {
+        this(-1, sheetName);
+    }
+
+    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(ErrorConstants.getText(ErrorConstants.ERROR_REF));
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public int getExternalWorkbookNumber() {
+        return externalWorkbookNumber;
+    }
+    public String getSheetName() {
+        return sheetName;
+    }
+
+    public String toFormulaString() {
+        StringBuffer sb = new StringBuffer();
+        if (externalWorkbookNumber >= 0) {
+            sb.append('[');
+            sb.append(externalWorkbookNumber);
+            sb.append(']');
+        }
+        if (sheetName != null) {
+            sb.append(sheetName);
+        }
+        sb.append('!');
+        sb.append(ErrorConstants.getText(ErrorConstants.ERROR_REF));
+        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 17d92f902c60a664713e7272c71994c274a6a2dd..9728e73ab4d98d92cb2122aa3585ce50c3f2d3a0 100644 (file)
@@ -119,10 +119,24 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
        }
        
        public ExternalName getExternalName(int externSheetIndex, int externNameIndex) {
-          throw new RuntimeException("Not implemented yet");
+        throw new IllegalStateException("HSSF-style external references are not supported for XSSF");
        }
 
-       public NameXPxg getNameXPtg(String name, SheetIdentifier sheet) {
+       public ExternalName getExternalName(String nameName, 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 ExternalName(nameName, -1, -1); // TODO Finish this
+        } else {
+            // Internal reference
+            int nameIdx = _uBook.getNameIndex(nameName);
+            return new ExternalName(nameName, nameIdx, -1);  // TODO Is this right?
+        }
+           
+    }
+
+    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);
@@ -131,6 +145,12 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
         }
         
         // Otherwise, try it as a named range
+        if (sheet == null) {
+            if (_uBook.getNameIndex(name) > -1) {
+                return new NameXPxg(null, name);
+            }
+            return null;
+        }
         if (sheet._sheetIdentifier == null) {
             // Workbook + Named Range only
             int bookIndex = resolveBookIndex(sheet._bookName);
@@ -229,7 +249,7 @@ public final class XSSFEvaluationWorkbook implements FormulaRenderingWorkbook, E
                XSSFEvaluationWorkbook frBook = XSSFEvaluationWorkbook.create(_uBook);
                return FormulaParser.parse(cell.getCellFormula(), frBook, FormulaType.CELL, _uBook.getSheetIndex(cell.getSheet()));
        }
-
+       
     public UDFFinder getUDFFinder(){
         return _uBook.getUDFFinder();
     }
index a7d4b5ddedcbf46b8da7ea2ab3c201f9cd1199ff..b6b9ee6f2f744078c5bf34866889986a45b865a3 100644 (file)
@@ -42,7 +42,16 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.ss.SpreadsheetVersion;
 import org.apache.poi.ss.formula.FormulaShifter;
 import org.apache.poi.ss.formula.SheetNameFormatter;
-import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellRange;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataValidation;
+import org.apache.poi.ss.usermodel.DataValidationHelper;
+import org.apache.poi.ss.usermodel.Footer;
+import org.apache.poi.ss.usermodel.Header;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
 import org.apache.poi.ss.util.CellReference;
@@ -58,7 +67,48 @@ import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter;
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlOptions;
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAutoFilter;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTLegacyDrawing;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetCalcPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTablePart;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableParts;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnsignedShortHex;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
 
 /**
  * High level representation of a SpreadsheetML worksheet.
@@ -2498,7 +2548,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         XSSFRowShifter rowShifter = new XSSFRowShifter(this);
 
         int sheetIndex = getWorkbook().getSheetIndex(this);
-        FormulaShifter shifter = FormulaShifter.createForRowShift(sheetIndex, startRow, endRow, n);
+        String sheetName = getWorkbook().getSheetName(sheetIndex);
+        FormulaShifter shifter = FormulaShifter.createForRowShift(
+                                   sheetIndex, sheetName, startRow, endRow, n);
 
         rowShifter.updateNamedRanges(shifter);
         rowShifter.updateFormulas(shifter);
index 245d7c1c19181d1e6386425df1e56fb4a1c8192d..da65972edb0962c9f5c4329c92059d81b47f3566 100644 (file)
 
 package org.apache.poi.xssf.usermodel.helpers;
 
-import org.apache.poi.xssf.usermodel.*;
-import org.apache.poi.ss.util.CellRangeAddress;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.poi.ss.formula.FormulaParser;
-import org.apache.poi.ss.formula.FormulaType;
 import org.apache.poi.ss.formula.FormulaRenderer;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.formula.FormulaShifter;
-import org.apache.poi.ss.formula.ptg.Ptg;
-import org.apache.poi.ss.formula.ptg.AreaPtg;
+import org.apache.poi.ss.formula.FormulaType;
 import org.apache.poi.ss.formula.ptg.AreaErrPtg;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
-
-import java.util.List;
-import java.util.ArrayList;
+import org.apache.poi.ss.formula.ptg.AreaPtg;
+import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFName;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
 
 /**
  * @author Yegor Kozlov
@@ -115,7 +124,6 @@ public final class XSSFRowShifter {
                 String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
                 name.setRefersToFormula(shiftedFmla);
             }
-
         }
     }
 
index 57ccf1f6babc4de09e2387d983d01d248f6155b1..176bb04464f0400c7d9c366fa32901710636de60 100644 (file)
 
 package org.apache.poi.hssf.model;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
+
 import org.apache.poi.ddf.EscherDggRecord;
 import org.apache.poi.hssf.HSSFTestDataSamples;
-import org.apache.poi.hssf.record.*;
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.BlankRecord;
+import org.apache.poi.hssf.record.CellValueRecordInterface;
+import org.apache.poi.hssf.record.ColumnInfoRecord;
+import org.apache.poi.hssf.record.DimensionsRecord;
+import org.apache.poi.hssf.record.DrawingRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.EscherAggregate;
+import org.apache.poi.hssf.record.FormulaRecord;
+import org.apache.poi.hssf.record.GutsRecord;
+import org.apache.poi.hssf.record.IndexRecord;
+import org.apache.poi.hssf.record.MergeCellsRecord;
+import org.apache.poi.hssf.record.MulBlankRecord;
+import org.apache.poi.hssf.record.NoteRecord;
+import org.apache.poi.hssf.record.NumberRecord;
+import org.apache.poi.hssf.record.ObjRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.hssf.record.RecordBase;
+import org.apache.poi.hssf.record.RowRecord;
+import org.apache.poi.hssf.record.StringRecord;
+import org.apache.poi.hssf.record.TextObjectRecord;
+import org.apache.poi.hssf.record.UncalcedRecord;
+import org.apache.poi.hssf.record.WindowTwoRecord;
 import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;
 import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;
 import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
@@ -35,11 +63,6 @@ import org.apache.poi.ss.formula.FormulaShifter;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.HexRead;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * Unit test for the {@link InternalSheet} class.
  *
@@ -632,7 +655,7 @@ public final class TestSheet extends TestCase {
                List<RecordBase> sheetRecs = sheet.getRecords();
                assertEquals(23, sheetRecs.size());
 
-               FormulaShifter shifter = FormulaShifter.createForRowShift(0, 0, 0, 1);
+               FormulaShifter shifter = FormulaShifter.createForRowShift(0, "", 0, 0, 1);
                sheet.updateFormulasAfterCellShift(shifter, 0);
                if (sheetRecs.size() == 24 && sheetRecs.get(22) instanceof ConditionalFormattingTable) {
                        throw new AssertionFailedError("Identified bug 46547a");
index e3e955850ad5aab609c3c6914358a7373a363ae4..d1848a1009ee5f27a1bca36761f5d667685f1fe7 100644 (file)
@@ -97,7 +97,7 @@ public final class TestFormulaShifter extends TestCase {
                        int firstRowMoved, int lastRowMoved, int numberRowsMoved,
                        int expectedAreaFirstRow, int expectedAreaLastRow) {
 
-               FormulaShifter fs = FormulaShifter.createForRowShift(0, firstRowMoved, lastRowMoved, numberRowsMoved);
+               FormulaShifter fs = FormulaShifter.createForRowShift(0, "", firstRowMoved, lastRowMoved, numberRowsMoved);
                boolean expectedChanged = aptg.getFirstRow() != expectedAreaFirstRow || aptg.getLastRow() != expectedAreaLastRow;
 
                AreaPtg copyPtg = (AreaPtg) aptg.copy(); // clone so we can re-use aptg in calling method