]> source.dussan.org Git - poi.git/commitdiff
refactored XSSFSheet.shiftRows to use FormulaShifter, use a common test superclass...
authorYegor Kozlov <yegor@apache.org>
Sun, 15 Feb 2009 20:47:36 +0000 (20:47 +0000)
committerYegor Kozlov <yegor@apache.org>
Sun, 15 Feb 2009 20:47:36 +0000 (20:47 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@744750 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetShiftRows.java [new file with mode: 0755]
src/testcases/org/apache/poi/hssf/data/ForShifting.xlsx [new file with mode: 0755]
src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx [new file with mode: 0755]
src/testcases/org/apache/poi/hssf/data/comments.xlsx [new file with mode: 0755]
src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java [deleted file]
src/testcases/org/apache/poi/hssf/usermodel/TestSheetShiftRows.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java [new file with mode: 0755]

index f01cae8ce41b0828093de8a631f80b62a80e0715..aa7f72df195cae81cc3ec8cc4bb7ebc8d0569804 100755 (executable)
@@ -127,6 +127,15 @@ public class POIXMLDocumentPart {
         relations.add(part);\r
     }\r
 \r
+    /**\r
+     * Remove the specified part in this package.\r
+     */\r
+    public final void removeRelation(POIXMLDocumentPart part){\r
+        getPackagePart().removeRelationship(part.getPackageRelationship().getId());\r
+        getPackagePart().getPackage().removePart(part.getPackagePart());\r
+        relations.remove(part);\r
+    }\r
+\r
     /**\r
      * Returns the parent POIXMLDocumentPart. All parts except root have not-null parent.\r
      *\r
index 88563ec268b887b243865ffefe014e8eaf55bfa1..7c8ff976a1ab437f48deba435a2ca0afb9ccedc0 100644 (file)
@@ -27,7 +27,10 @@ import org.apache.poi.ss.formula.FormulaType;
 import org.apache.poi.ss.formula.FormulaRenderer;
 import org.apache.poi.xssf.model.CalculationChain;
 import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.FormulaShifter;
 import org.apache.poi.hssf.record.SharedFormulaRecord;
+import org.apache.poi.util.POILogger;
+import org.apache.poi.util.POILogFactory;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
@@ -36,6 +39,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
  * High level representation of a row of a spreadsheet.
  */
 public class XSSFRow implements Row, Comparable<XSSFRow> {
+    private static final POILogger logger = POILogFactory.getLogger(XSSFRow.class);
 
     private static final String FILE_FORMAT_NAME  = "BIFF12";
     /**
@@ -406,34 +410,45 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
      * @param n the number of rows to move
      */
     protected void shift(int n) {
-        XSSFSheet sheet = getSheet();
-        CalculationChain calcChain = sheet.getWorkbook().getCalculationChain();
         int rownum = getRowNum() + n;
+        CalculationChain calcChain = sheet.getWorkbook().getCalculationChain();
+        int sheetId = (int)sheet.sheet.getSheetId();
         for(Cell c : this){
             XSSFCell cell = (XSSFCell)c;
 
             //remove the reference in the calculation chain
-            if(calcChain != null) calcChain.removeItem((int)sheet.sheet.getSheetId(), cell.getReference());
+            if(calcChain != null) calcChain.removeItem(sheetId, cell.getReference());
 
             CTCell ctCell = cell.getCTCell();
             String r = new CellReference(rownum, cell.getColumnIndex()).formatAsString();
             ctCell.setR(r);
+        }
+        setRowNum(rownum);
+    }
+
+    protected void updateFormulasAfterCellShift(FormulaShifter shifter) {
+        for(Cell c : this){
+            XSSFCell cell = (XSSFCell)c;
 
+            CTCell ctCell = cell.getCTCell();
             if(ctCell.isSetF()){
                 CTCellFormula f = ctCell.getF();
-                String fmla = f.getStringValue();
-                if(fmla.length() > 0) {
-                    String shiftedFmla = shiftFormula(fmla, n);
-                    f.setStringValue(shiftedFmla);
+                String formula = f.getStringValue();
+                if(formula.length() > 0) {
+                    String shiftedFormula = shiftFormula(formula, shifter);
+                    if (shiftedFormula != null) {
+                        f.setStringValue(shiftedFormula);
+                    }
                 }
+
                 if(f.isSetRef()){ //Range of cells which the formula applies to.
                     String ref = f.getRef();
-                    String shiftedRef = shiftFormula(ref, n);
-                    f.setRef(shiftedRef);
+                    String shiftedRef = shiftFormula(ref, shifter);
+                    if(shiftedRef != null) f.setRef(shiftedRef);
                 }
             }
+
         }
-        setRowNum(rownum);
     }
 
     /**
@@ -443,17 +458,21 @@ public class XSSFRow implements Row, Comparable<XSSFRow> {
      * </p>
      *
      * @param formula the formula to shift
-     * @param n the number of rows to shift
-     * @return the shifted formula
+     * @param shifter the FormulaShifter object that operates on the parsed formula tokens
+     * @return the shifted formula if the formula was changed,
+     *   <code>null</code> if the formula wasn't modified
      */
-    private String shiftFormula(String formula, int n){
+    private String shiftFormula(String formula, FormulaShifter shifter){
         XSSFSheet sheet = getSheet();
         XSSFWorkbook wb = sheet.getWorkbook();
         int sheetIndex = wb.getSheetIndex(sheet);
         XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
         Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex);
-        Ptg[] fmla = SharedFormulaRecord.convertSharedFormulas(ptgs, n, 0);
-        return FormulaRenderer.toFormulaString(fpb, fmla);
+        String shiftedFmla = null;
+        if (shifter.adjustFormula(ptgs, sheetIndex)) {
+            shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
+        }
+        return shiftedFmla;
     }
 
 }
index 90f920c3e7ad093eaf53ac8d822cc0468deb2c9d..e44208b75e5461df2d47f607fd2dac24d706e7fe 100644 (file)
@@ -25,6 +25,7 @@ import javax.xml.namespace.QName;
 
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.hssf.record.formula.Ptg;
+import org.apache.poi.hssf.record.formula.FormulaShifter;
 import org.apache.poi.hssf.record.SharedFormulaRecord;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
@@ -60,7 +61,7 @@ import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelations
  * </p>
  */
 public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
-    private static POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
+    private static final POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
 
     /**
      * Column width measured as the number of characters of the maximum digit width of the
@@ -1442,6 +1443,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
         for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
             XSSFRow row = (XSSFRow)it.next();
+            int rownum = row.getRowNum();
 
             if (!copyRowHeight) {
                 row.setHeight((short)-1);
@@ -1456,11 +1458,39 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
             else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) {
                 row.shift(n);
             }
+
+            if(sheetComments != null){
+                //TODO shift Note's anchor in the associated /xl/drawing/vmlDrawings#.vml
+                CTCommentList lst = sheetComments.getCTComments().getCommentList();
+                for (CTComment comment : lst.getCommentArray()) {
+                    CellReference ref = new CellReference(comment.getRef());
+                    if(ref.getRow() == rownum){
+                        ref = new CellReference(rownum + n, ref.getCol());
+                        comment.setRef(ref.formatAsString());
+                    }
+                }
+            }
         }
         //rebuild the rows map
+        int sheetIndex = getWorkbook().getSheetIndex(this);
+        FormulaShifter shifter = FormulaShifter.createForRowShift(sheetIndex, startRow, endRow, n);
         TreeMap<Integer, Row> map = new TreeMap<Integer, Row>();
-        for(Row r : this) map.put(r.getRowNum(), r);
+        for(Row r : this) {
+            XSSFRow row = (XSSFRow)r;
+            row.updateFormulasAfterCellShift(shifter);
+            map.put(r.getRowNum(), r);
+        }
         rows = map;
+
+        //update formulas on other sheets
+        for(XSSFSheet sheet : getWorkbook()) {
+            if (sheet == this) continue;
+            for(Row r : sheet) {
+                XSSFRow row = (XSSFRow)r;
+                row.updateFormulasAfterCellShift(shifter);
+            }
+        }
+
     }
 
     /**
index ce1724aed19ca552ddf41c25ad7f2193a8e7e854..c2cdcd06d4c19e900bb9c23828afffac74570ca4 100644 (file)
@@ -1068,12 +1068,22 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
                 workbook.unsetDefinedNames();
             }
         }
+    }
 
+    private void saveCalculationChain(){
+        if(calcChain != null){
+            int count = calcChain.getCTCalcChain().getCArray().length;
+            if(count == 0){
+                removeRelation(calcChain);
+                calcChain = null;
+            }
+        }
     }
 
     @Override
     protected void commit() throws IOException {
         saveNamedRanges();
+        saveCalculationChain();
 
         XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
         xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetShiftRows.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSheetShiftRows.java
new file mode 100755 (executable)
index 0000000..f3a0fb5
--- /dev/null
@@ -0,0 +1,68 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows;\r
+import org.apache.poi.ss.usermodel.Workbook;\r
+import org.apache.poi.xssf.XSSFTestDataSamples;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class TestSheetShiftRows  extends BaseTestSheetShiftRows {\r
+\r
+    @Override\r
+    protected Workbook openSampleWorkbook(String sampleFileName) {\r
+        return XSSFTestDataSamples.openSampleWorkbook(sampleFileName);\r
+    }\r
+\r
+    @Override\r
+    protected Workbook writeOutAndReadBack(Workbook wb) {\r
+        return XSSFTestDataSamples.writeOutAndReadBack(wb);\r
+    }\r
+\r
+    @Override\r
+    protected Workbook createWorkbook() {\r
+        return new XSSFWorkbook();\r
+    }\r
+\r
+    public void testShiftRows() {\r
+        baseTestShiftRows("SimpleMultiCell.xlsx");\r
+    }\r
+\r
+    public void testShiftRow() {\r
+        baseTestShiftRow();\r
+    }\r
+\r
+    public void testShiftRow0() {\r
+        baseTestShiftRow0();\r
+    }\r
+\r
+    //TODO support shifting of page breaks\r
+    public void $testShiftRowBreaks() {\r
+        baseTestShiftRowBreaks();\r
+    }\r
+\r
+    //TODO support shifting of comments. \r
+    public void $testShiftWithComments() {\r
+        baseTestShiftWithComments("comments.xlsx");\r
+    }\r
+\r
+    public void testShiftWithFormulas() {\r
+        baseTestShiftWithFormulas("ForShifting.xlsx");\r
+    }\r
+}\r
diff --git a/src/testcases/org/apache/poi/hssf/data/ForShifting.xlsx b/src/testcases/org/apache/poi/hssf/data/ForShifting.xlsx
new file mode 100755 (executable)
index 0000000..f05923b
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/ForShifting.xlsx differ
diff --git a/src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx b/src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx
new file mode 100755 (executable)
index 0000000..d5dfe7a
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/SimpleMultiCell.xlsx differ
diff --git a/src/testcases/org/apache/poi/hssf/data/comments.xlsx b/src/testcases/org/apache/poi/hssf/data/comments.xlsx
new file mode 100755 (executable)
index 0000000..d4e1398
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/comments.xlsx differ
diff --git a/src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/hssf/usermodel/BaseTestSheetShiftRows.java
deleted file mode 100755 (executable)
index 5c6716c..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/* ====================================================================
-   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.hssf.usermodel;
-
-import junit.framework.TestCase;
-
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
-
-/**
- * Tests row shifting capabilities (common base class for HSSF and XSSF tests).
- *
- *
- * @author Shawn Laubach (slaubach at apache dot com)
- * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)
- */
-public abstract class BaseTestSheetShiftRows extends TestCase {
-       /**
-        * Override to provide HSSF / XSSF specific way for re-serialising a workbook
-        */
-       protected abstract Workbook writeOutAndReadBack(Workbook wb);
-       /**
-        * Override to provide way of loading HSSF / XSSF sample workbooks
-        * @param sampleFileName without the ".xls" or ".xlsx" suffix
-        */
-       protected abstract Workbook openSampleWorkbook(String sampleFileName);
-       /**
-        * Override to provide way of creating HSSF / XSSF workbooks
-        */
-       protected abstract Workbook createWorkbook();
-
-       /**
-        * Tests the shiftRows function.  Does three different shifts.
-        * After each shift, writes the workbook to file and reads back to
-        * check.  This ensures that if some changes code that breaks
-        * writing or what not, they realize it.
-        *
-        * @author Shawn Laubach (slaubach at apache dot org)
-        */
-       public final void testShiftRows(){
-               final String sampleName = "SimpleMultiCell";
-               // Read initial file in
-               Workbook wb = openSampleWorkbook(sampleName);
-               Sheet s = wb.getSheetAt( 0 );
-
-               // Shift the second row down 1 and write to temp file
-               s.shiftRows( 1, 1, 1 );
-
-               wb = writeOutAndReadBack(wb);
-
-               // Read from temp file and check the number of cells in each
-               // row (in original file each row was unique)
-               s = wb.getSheetAt( 0 );
-
-               assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 1);
-               confirmEmptyRow(s, 1);
-               assertEquals(s.getRow(2).getPhysicalNumberOfCells(), 2);
-               assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 4);
-               assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5);
-
-               // Shift rows 1-3 down 3 in the current one.  This tests when
-               // 1 row is blank.  Write to a another temp file
-               s.shiftRows( 0, 2, 3 );
-               wb = writeOutAndReadBack(wb);
-
-               // Read and ensure things are where they should be
-               s = wb.getSheetAt(0);
-               confirmEmptyRow(s, 0);
-               confirmEmptyRow(s, 1);
-               confirmEmptyRow(s, 2);
-               assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 1);
-               confirmEmptyRow(s, 4);
-               assertEquals(s.getRow(5).getPhysicalNumberOfCells(), 2);
-
-               // Read the first file again
-               wb = openSampleWorkbook(sampleName);
-               s = wb.getSheetAt( 0 );
-
-               // Shift rows 3 and 4 up and write to temp file
-               s.shiftRows( 2, 3, -2 );
-               wb = writeOutAndReadBack(wb);
-               s = wb.getSheetAt( 0 );
-               assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 3);
-               assertEquals(s.getRow(1).getPhysicalNumberOfCells(), 4);
-               confirmEmptyRow(s, 2);
-               confirmEmptyRow(s, 3);
-               assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5);
-       }
-       private static void confirmEmptyRow(Sheet s, int rowIx) {
-               Row row = s.getRow(rowIx);
-               assertTrue(row == null || row.getPhysicalNumberOfCells() == 0);
-       }
-
-       /**
-        * Tests when rows are null.
-        *
-        * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)
-        */
-       public final void testShiftRow() {
-               Workbook b = createWorkbook();
-               Sheet s = b.createSheet();
-               s.createRow(0).createCell(0).setCellValue("TEST1");
-               s.createRow(3).createCell(0).setCellValue("TEST2");
-               s.shiftRows(0,4,1);
-       }
-
-       /**
-        * Tests when shifting the first row.
-        *
-        * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)
-        */
-       public final void testShiftRow0() {
-               Workbook b = createWorkbook();
-               Sheet s = b.createSheet();
-               s.createRow(0).createCell(0).setCellValue("TEST1");
-               s.createRow(3).createCell(0).setCellValue("TEST2");
-               s.shiftRows(0,4,1);
-       }
-
-       /**
-        * When shifting rows, the page breaks should go with it
-        *
-        */
-       public final void testShiftRowBreaks() {
-               Workbook b = createWorkbook();
-               Sheet s = b.createSheet();
-               Row row = s.createRow(4);
-               row.createCell(0).setCellValue("test");
-               s.setRowBreak(4);
-
-               s.shiftRows(4, 4, 2);
-               assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6));
-       }
-
-
-       public final void testShiftWithComments() {
-               final String sampleName = "comments";
-               Workbook wb = openSampleWorkbook(sampleName);
-
-               Sheet sheet = wb.getSheet("Sheet1");
-               assertEquals(3, sheet.getLastRowNum());
-
-               // Verify comments are in the position expected
-               assertNotNull(sheet.getCellComment(0,0));
-               assertNull(sheet.getCellComment(1,0));
-               assertNotNull(sheet.getCellComment(2,0));
-               assertNotNull(sheet.getCellComment(3,0));
-
-               String comment1 = sheet.getCellComment(0,0).getString().getString();
-               assertEquals(comment1,"comment top row1 (index0)\n");
-               String comment3 = sheet.getCellComment(2,0).getString().getString();
-               assertEquals(comment3,"comment top row3 (index2)\n");
-               String comment4 = sheet.getCellComment(3,0).getString().getString();
-               assertEquals(comment4,"comment top row4 (index3)\n");
-
-               // Shifting all but first line down to test comments shifting
-               sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true);
-
-               // Test that comments were shifted as expected
-               assertEquals(4, sheet.getLastRowNum());
-               assertNotNull(sheet.getCellComment(0,0));
-               assertNull(sheet.getCellComment(1,0));
-               assertNull(sheet.getCellComment(2,0));
-               assertNotNull(sheet.getCellComment(3,0));
-               assertNotNull(sheet.getCellComment(4,0));
-
-               String comment1_shifted = sheet.getCellComment(0,0).getString().getString();
-               assertEquals(comment1,comment1_shifted);
-               String comment3_shifted = sheet.getCellComment(3,0).getString().getString();
-               assertEquals(comment3,comment3_shifted);
-               String comment4_shifted = sheet.getCellComment(4,0).getString().getString();
-               assertEquals(comment4,comment4_shifted);
-
-               // Write out and read back in again
-               // Ensure that the changes were persisted
-               wb = writeOutAndReadBack(wb);
-               sheet = wb.getSheet("Sheet1");
-               assertEquals(4, sheet.getLastRowNum());
-
-               // Verify comments are in the position expected after the shift
-               assertNotNull(sheet.getCellComment(0,0));
-               assertNull(sheet.getCellComment(1,0));
-               assertNull(sheet.getCellComment(2,0));
-               assertNotNull(sheet.getCellComment(3,0));
-               assertNotNull(sheet.getCellComment(4,0));
-
-               comment1_shifted = sheet.getCellComment(0,0).getString().getString();
-               assertEquals(comment1,comment1_shifted);
-               comment3_shifted = sheet.getCellComment(3,0).getString().getString();
-               assertEquals(comment3,comment3_shifted);
-               comment4_shifted = sheet.getCellComment(4,0).getString().getString();
-               assertEquals(comment4,comment4_shifted);
-       }
-
-       /**
-        * See bug #34023
-        */
-       public void testShiftWithFormulas() {
-               String sampleName = "ForShifting";
-               Workbook wb = openSampleWorkbook(sampleName);
-
-               Sheet sheet = wb.getSheet("Sheet1");
-               assertEquals(20, sheet.getLastRowNum());
-               
-               confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)");
-               confirmRow(sheet, 1, 2, 172, 1, "ROW(D2)", "100+B2", "COUNT(D2:E2)");
-               confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)");
-               
-               confirmCell(sheet, 6, 1, 271, "200+B1");
-               confirmCell(sheet, 7, 1, 272, "200+B2");
-               confirmCell(sheet, 8, 1, 273, "200+B3");
-
-               confirmCell(sheet, 14, 0, 0.0, "A12"); // the cell referred to by this formula will be replaced
-               
-               // -----------
-               // Row index 1 -> 11 (row "2" -> row "12")
-               sheet.shiftRows(1, 1, 10);
-               
-               // Now check what sheet looks like after move
-
-               // no changes on row "1"
-               confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)");
-               
-               // row "2" is now empty
-               assertEquals(0, sheet.getRow(1).getPhysicalNumberOfCells());
-
-               // Row "2" moved to row "12", and the formula has been updated.
-               // note however that the cached formula result (2) has not been updated. (POI differs from Excel here)
-               confirmRow(sheet, 11, 2, 172, 1, "ROW(D12)", "100+B12", "COUNT(D12:E12)");
-
-               // no changes on row "3"
-               confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)");
-
-               
-               confirmCell(sheet, 14, 0, 0.0, "#REF!");  
-               
-               
-               // Formulas on rows that weren't shifted:
-               confirmCell(sheet, 6, 1, 271, "200+B1");
-               confirmCell(sheet, 7, 1, 272, "200+B12"); // this one moved
-               confirmCell(sheet, 8, 1, 273, "200+B3");
-               
-               // check formulas on other sheets
-               Sheet sheet2 = wb.getSheet("Sheet2");
-               confirmCell(sheet2,  0, 0, 371, "300+Sheet1!B1");
-               confirmCell(sheet2,  1, 0, 372, "300+Sheet1!B12");
-               confirmCell(sheet2,  2, 0, 373, "300+Sheet1!B3");
-               
-               confirmCell(sheet2, 11, 0, 300, "300+Sheet1!#REF!");
-               
-               
-               // Note - named ranges formulas have not been updated
-       }
-
-       private static void confirmRow(Sheet sheet, int rowIx, double valA, double valB, double valC,
-                               String formulaA, String formulaB, String formulaC) {
-               confirmCell(sheet, rowIx, 4, valA, formulaA);
-               confirmCell(sheet, rowIx, 5, valB, formulaB);
-               confirmCell(sheet, rowIx, 6, valC, formulaC);
-       }
-
-       private static void confirmCell(Sheet sheet, int rowIx, int colIx, 
-                       double expectedValue, String expectedFormula) {
-               Cell cell = sheet.getRow(rowIx).getCell(colIx);
-               assertEquals(expectedValue, cell.getNumericCellValue(), 0.0);
-               assertEquals(expectedFormula, cell.getCellFormula());
-       }
-}
index d29469111d7f9a340494961f23908cc9a20edbb4..962a565503dc886c33223894138322bf2cfdb024 100755 (executable)
@@ -19,6 +19,7 @@ package org.apache.poi.hssf.usermodel;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.BaseTestSheetShiftRows;
 
 /**
  * Tests row shifting capabilities.
@@ -31,7 +32,7 @@ public final class TestSheetShiftRows extends BaseTestSheetShiftRows {
 
        @Override
        protected Workbook openSampleWorkbook(String sampleFileName) {
-               return HSSFTestDataSamples.openSampleWorkbook(sampleFileName + ".xls");
+               return HSSFTestDataSamples.openSampleWorkbook(sampleFileName);
        }
 
        @Override
@@ -46,4 +47,29 @@ public final class TestSheetShiftRows extends BaseTestSheetShiftRows {
        protected Workbook createWorkbook() {
                return new HSSFWorkbook();
        }
+
+    public void testShiftRows() {
+        baseTestShiftRows("SimpleMultiCell.xls");
+    }
+
+    public void testShiftRow() {
+        baseTestShiftRow();
+    }
+
+    public void testShiftRow0() {
+        baseTestShiftRow0();
+    }
+
+    public void testShiftRowBreaks() {
+        baseTestShiftRowBreaks();
+    }
+
+    public void testShiftWithComments() {
+        baseTestShiftWithComments("comments.xls");
+    }
+
+    public void testShiftWithFormulas() {
+        baseTestShiftWithFormulas("ForShifting.xls");
+    }
+
 }
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestSheetShiftRows.java
new file mode 100755 (executable)
index 0000000..7b83cbb
--- /dev/null
@@ -0,0 +1,276 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.ss.usermodel;\r
+\r
+import junit.framework.TestCase;\r
+\r
+/**\r
+ * Tests row shifting capabilities.\r
+ *\r
+ * @author Shawn Laubach (slaubach at apache dot com)\r
+ * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)\r
+ */\r
+public abstract class BaseTestSheetShiftRows  extends TestCase {\r
+    /**\r
+     * Override to provide HSSF / XSSF specific way for re-serialising a workbook\r
+     */\r
+    protected abstract Workbook writeOutAndReadBack(Workbook wb);\r
+    /**\r
+     * Override to provide way of loading HSSF / XSSF sample workbooks\r
+     * @param sampleFileName without the ".xls" or ".xlsx" suffix\r
+     */\r
+    protected abstract Workbook openSampleWorkbook(String sampleFileName);\r
+    /**\r
+     * Override to provide way of creating HSSF / XSSF workbooks\r
+     */\r
+    protected abstract Workbook createWorkbook();\r
+\r
+    /**\r
+     * Tests the shiftRows function.  Does three different shifts.\r
+     * After each shift, writes the workbook to file and reads back to\r
+     * check.  This ensures that if some changes code that breaks\r
+     * writing or what not, they realize it.\r
+     *\r
+     * @author Shawn Laubach (slaubach at apache dot org)\r
+     */\r
+    public final void baseTestShiftRows(String sampleName){\r
+        // Read initial file in\r
+        Workbook wb = openSampleWorkbook(sampleName);\r
+        Sheet s = wb.getSheetAt( 0 );\r
+\r
+        // Shift the second row down 1 and write to temp file\r
+        s.shiftRows( 1, 1, 1 );\r
+\r
+        wb = writeOutAndReadBack(wb);\r
+\r
+        // Read from temp file and check the number of cells in each\r
+        // row (in original file each row was unique)\r
+        s = wb.getSheetAt( 0 );\r
+\r
+        assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 1);\r
+        confirmEmptyRow(s, 1);\r
+        assertEquals(s.getRow(2).getPhysicalNumberOfCells(), 2);\r
+        assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 4);\r
+        assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5);\r
+\r
+        // Shift rows 1-3 down 3 in the current one.  This tests when\r
+        // 1 row is blank.  Write to a another temp file\r
+        s.shiftRows( 0, 2, 3 );\r
+        wb = writeOutAndReadBack(wb);\r
+\r
+        // Read and ensure things are where they should be\r
+        s = wb.getSheetAt(0);\r
+        confirmEmptyRow(s, 0);\r
+        confirmEmptyRow(s, 1);\r
+        confirmEmptyRow(s, 2);\r
+        assertEquals(s.getRow(3).getPhysicalNumberOfCells(), 1);\r
+        confirmEmptyRow(s, 4);\r
+        assertEquals(s.getRow(5).getPhysicalNumberOfCells(), 2);\r
+\r
+        // Read the first file again\r
+        wb = openSampleWorkbook(sampleName);\r
+        s = wb.getSheetAt( 0 );\r
+\r
+        // Shift rows 3 and 4 up and write to temp file\r
+        s.shiftRows( 2, 3, -2 );\r
+        wb = writeOutAndReadBack(wb);\r
+        s = wb.getSheetAt( 0 );\r
+        assertEquals(s.getRow(0).getPhysicalNumberOfCells(), 3);\r
+        assertEquals(s.getRow(1).getPhysicalNumberOfCells(), 4);\r
+        confirmEmptyRow(s, 2);\r
+        confirmEmptyRow(s, 3);\r
+        assertEquals(s.getRow(4).getPhysicalNumberOfCells(), 5);\r
+    }\r
+    private static void confirmEmptyRow(Sheet s, int rowIx) {\r
+        Row row = s.getRow(rowIx);\r
+        assertTrue(row == null || row.getPhysicalNumberOfCells() == 0);\r
+    }\r
+\r
+    /**\r
+     * Tests when rows are null.\r
+     *\r
+     * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)\r
+     */\r
+    public final void baseTestShiftRow() {\r
+        Workbook b = createWorkbook();\r
+        Sheet s        = b.createSheet();\r
+        s.createRow(0).createCell(0).setCellValue("TEST1");\r
+        s.createRow(3).createCell(0).setCellValue("TEST2");\r
+        s.shiftRows(0,4,1);\r
+    }\r
+\r
+    /**\r
+     * Tests when shifting the first row.\r
+     *\r
+     * @author Toshiaki Kamoshida (kamoshida.toshiaki at future dot co dot jp)\r
+     */\r
+    public final void baseTestShiftRow0() {\r
+        Workbook b = createWorkbook();\r
+        Sheet s        = b.createSheet();\r
+        s.createRow(0).createCell(0).setCellValue("TEST1");\r
+        s.createRow(3).createCell(0).setCellValue("TEST2");\r
+        s.shiftRows(0,4,1);\r
+    }\r
+\r
+    /**\r
+     * When shifting rows, the page breaks should go with it\r
+     *\r
+     */\r
+    public final void baseTestShiftRowBreaks() {\r
+        Workbook b = createWorkbook();\r
+        Sheet s        = b.createSheet();\r
+        Row row = s.createRow(4);\r
+        row.createCell(0).setCellValue("test");\r
+        s.setRowBreak(4);\r
+\r
+        s.shiftRows(4, 4, 2);\r
+        assertTrue("Row number 6 should have a pagebreak", s.isRowBroken(6));\r
+    }\r
+\r
+\r
+    public final void baseTestShiftWithComments(String sampleName) {\r
+        Workbook wb = openSampleWorkbook(sampleName);\r
+\r
+        Sheet sheet = wb.getSheet("Sheet1");\r
+        assertEquals(3, sheet.getLastRowNum());\r
+\r
+        // Verify comments are in the position expected\r
+        assertNotNull(sheet.getCellComment(0,0));\r
+        assertNull(sheet.getCellComment(1,0));\r
+        assertNotNull(sheet.getCellComment(2,0));\r
+        assertNotNull(sheet.getCellComment(3,0));\r
+\r
+        String comment1 = sheet.getCellComment(0,0).getString().getString();\r
+        assertEquals(comment1,"comment top row1 (index0)\n");\r
+        String comment3 = sheet.getCellComment(2,0).getString().getString();\r
+        assertEquals(comment3,"comment top row3 (index2)\n");\r
+        String comment4 = sheet.getCellComment(3,0).getString().getString();\r
+        assertEquals(comment4,"comment top row4 (index3)\n");\r
+\r
+        // Shifting all but first line down to test comments shifting\r
+        sheet.shiftRows(1, sheet.getLastRowNum(), 1, true, true);\r
+\r
+        // Test that comments were shifted as expected\r
+        assertEquals(4, sheet.getLastRowNum());\r
+        assertNotNull(sheet.getCellComment(0,0));\r
+        assertNull(sheet.getCellComment(1,0));\r
+        assertNull(sheet.getCellComment(2,0));\r
+        assertNotNull(sheet.getCellComment(3,0));\r
+        assertNotNull(sheet.getCellComment(4,0));\r
+\r
+        String comment1_shifted = sheet.getCellComment(0,0).getString().getString();\r
+        assertEquals(comment1,comment1_shifted);\r
+        String comment3_shifted = sheet.getCellComment(3,0).getString().getString();\r
+        assertEquals(comment3,comment3_shifted);\r
+        String comment4_shifted = sheet.getCellComment(4,0).getString().getString();\r
+        assertEquals(comment4,comment4_shifted);\r
+\r
+        // Write out and read back in again\r
+        // Ensure that the changes were persisted\r
+        wb = writeOutAndReadBack(wb);\r
+        sheet = wb.getSheet("Sheet1");\r
+        assertEquals(4, sheet.getLastRowNum());\r
+\r
+        // Verify comments are in the position expected after the shift\r
+        assertNotNull(sheet.getCellComment(0,0));\r
+        assertNull(sheet.getCellComment(1,0));\r
+        assertNull(sheet.getCellComment(2,0));\r
+        assertNotNull(sheet.getCellComment(3,0));\r
+        assertNotNull(sheet.getCellComment(4,0));\r
+\r
+        comment1_shifted = sheet.getCellComment(0,0).getString().getString();\r
+        assertEquals(comment1,comment1_shifted);\r
+        comment3_shifted = sheet.getCellComment(3,0).getString().getString();\r
+        assertEquals(comment3,comment3_shifted);\r
+        comment4_shifted = sheet.getCellComment(4,0).getString().getString();\r
+        assertEquals(comment4,comment4_shifted);\r
+    }\r
+\r
+    /**\r
+     * See bug #34023\r
+     */\r
+    public void baseTestShiftWithFormulas(String sampleName) {\r
+        Workbook wb = openSampleWorkbook(sampleName);\r
+\r
+        Sheet sheet = wb.getSheet("Sheet1");\r
+        assertEquals(20, sheet.getLastRowNum());\r
+\r
+        confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)");\r
+        confirmRow(sheet, 1, 2, 172, 1, "ROW(D2)", "100+B2", "COUNT(D2:E2)");\r
+        confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)");\r
+\r
+        confirmCell(sheet, 6, 1, 271, "200+B1");\r
+        confirmCell(sheet, 7, 1, 272, "200+B2");\r
+        confirmCell(sheet, 8, 1, 273, "200+B3");\r
+\r
+        confirmCell(sheet, 14, 0, 0.0, "A12"); // the cell referred to by this formula will be replaced\r
+\r
+        // -----------\r
+        // Row index 1 -> 11 (row "2" -> row "12")\r
+        sheet.shiftRows(1, 1, 10);\r
+\r
+        // Now check what sheet looks like after move\r
+\r
+        // no changes on row "1"\r
+        confirmRow(sheet, 0, 1, 171, 1, "ROW(D1)", "100+B1", "COUNT(D1:E1)");\r
+\r
+        // row "2" is now empty\r
+        confirmEmptyRow(sheet, 1);\r
+\r
+        // Row "2" moved to row "12", and the formula has been updated.\r
+        // note however that the cached formula result (2) has not been updated. (POI differs from Excel here)\r
+        confirmRow(sheet, 11, 2, 172, 1, "ROW(D12)", "100+B12", "COUNT(D12:E12)");\r
+\r
+        // no changes on row "3"\r
+        confirmRow(sheet, 2, 3, 173, 1, "ROW(D3)", "100+B3", "COUNT(D3:E3)");\r
+\r
+\r
+        confirmCell(sheet, 14, 0, 0.0, "#REF!");\r
+\r
+\r
+        // Formulas on rows that weren't shifted:\r
+        confirmCell(sheet, 6, 1, 271, "200+B1");\r
+        confirmCell(sheet, 7, 1, 272, "200+B12"); // this one moved\r
+        confirmCell(sheet, 8, 1, 273, "200+B3");\r
+\r
+        // check formulas on other sheets\r
+        Sheet sheet2 = wb.getSheet("Sheet2");\r
+        confirmCell(sheet2,  0, 0, 371, "300+Sheet1!B1");\r
+        confirmCell(sheet2,  1, 0, 372, "300+Sheet1!B12");\r
+        confirmCell(sheet2,  2, 0, 373, "300+Sheet1!B3");\r
+\r
+        confirmCell(sheet2, 11, 0, 300, "300+Sheet1!#REF!");\r
+\r
+\r
+        // Note - named ranges formulas have not been updated\r
+    }\r
+\r
+    private static void confirmRow(Sheet sheet, int rowIx, double valA, double valB, double valC,\r
+                String formulaA, String formulaB, String formulaC) {\r
+        confirmCell(sheet, rowIx, 4, valA, formulaA);\r
+        confirmCell(sheet, rowIx, 5, valB, formulaB);\r
+        confirmCell(sheet, rowIx, 6, valC, formulaC);\r
+    }\r
+\r
+    private static void confirmCell(Sheet sheet, int rowIx, int colIx,\r
+            double expectedValue, String expectedFormula) {\r
+        Cell cell = sheet.getRow(rowIx).getCell(colIx);\r
+        assertEquals(expectedValue, cell.getNumericCellValue(), 0.0);\r
+        assertEquals(expectedFormula, cell.getCellFormula());\r
+    }\r
+}\r