You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2020/05/15 19:46:17 UTC

svn commit: r1877792 - in /poi/trunk/src: java/org/apache/poi/ss/usermodel/RangeCopier.java testcases/org/apache/poi/ss/usermodel/TestRangeCopier.java

Author: fanningpj
Date: Fri May 15 19:46:17 2020
New Revision: 1877792

URL: http://svn.apache.org/viewvc?rev=1877792&view=rev
Log:
[github-179] add an option for RangeCopier.copyRange() to clone styles. Thanks to xjlin0. This closes #179

Modified:
    poi/trunk/src/java/org/apache/poi/ss/usermodel/RangeCopier.java
    poi/trunk/src/testcases/org/apache/poi/ss/usermodel/TestRangeCopier.java

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/RangeCopier.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/RangeCopier.java?rev=1877792&r1=1877791&r2=1877792&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/RangeCopier.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/RangeCopier.java Fri May 15 19:46:17 2020
@@ -19,6 +19,7 @@
 
 package org.apache.poi.ss.usermodel;
 
+import java.util.HashMap;
 import java.util.Map;
 import org.apache.poi.ss.formula.FormulaShifter;
 import org.apache.poi.ss.formula.ptg.Ptg;
@@ -46,10 +47,25 @@ public abstract class RangeCopier {
      * 2.Paste source but only inside of destination borders.
      * 3.If there is space left on right or bottom side of copy, process it as in step 2.
      * @param tilePatternRange source range which should be copied in tiled manner
-     * @param tileDestRange     destination range, which should be overridden
+     * @param tileDestRange    destination range, which should be overridden
      */
     public void copyRange(CellRangeAddress tilePatternRange, CellRangeAddress tileDestRange) {
+        copyRange(tilePatternRange, tileDestRange, false, false);
+    }
+
+    /** Uses input pattern to tile destination region, overwriting existing content. Works in following manner :
+     * 1.Start from top-left of destination.
+     * 2.Paste source but only inside of destination borders.
+     * 3.If there is space left on right or bottom side of copy, process it as in step 2.
+     * @param tilePatternRange source range which should be copied in tiled manner
+     * @param tileDestRange    destination range, which should be overridden
+     * @param copyStyles       whether to copy the cell styles
+     * @param copyMergedRanges whether to copy merged ranges
+     * @since 4.1.3
+     */
+    public void copyRange(CellRangeAddress tilePatternRange, CellRangeAddress tileDestRange, boolean copyStyles, boolean copyMergedRanges) {
         Sheet sourceCopy = sourceSheet.getWorkbook().cloneSheet(sourceSheet.getWorkbook().getSheetIndex(sourceSheet));
+        Map<Integer, CellStyle> styleMap = copyStyles ? new HashMap<Integer, CellStyle>() {} : null;
         int sourceWidthMinus1 = tilePatternRange.getLastColumn() - tilePatternRange.getFirstColumn();
         int sourceHeightMinus1 = tilePatternRange.getLastRow() - tilePatternRange.getFirstRow();
         int rightLimitToCopy;
@@ -67,17 +83,21 @@ public abstract class RangeCopier {
                         tilePatternRange.getFirstRow(),     bottomLimitToCopy,
                         tilePatternRange.getFirstColumn(),  rightLimitToCopy
                        );
-                copyRange(rangeToCopy, nextCellIndexInRowToCopy - rangeToCopy.getFirstColumn(), nextRowIndexToCopy - rangeToCopy.getFirstRow(), sourceCopy);
+                copyRange(rangeToCopy, nextCellIndexInRowToCopy - rangeToCopy.getFirstColumn(), nextRowIndexToCopy - rangeToCopy.getFirstRow(), sourceCopy, styleMap);
                 nextCellIndexInRowToCopy += widthToCopyMinus1 + 1;
             } while (nextCellIndexInRowToCopy <= tileDestRange.getLastColumn());
             nextRowIndexToCopy += heightToCopyMinus1 + 1;
         } while (nextRowIndexToCopy <= tileDestRange.getLastRow());
 
+        if (copyMergedRanges) {
+            sourceSheet.getMergedRegions().forEach((mergedRangeAddress) -> destSheet.addMergedRegion(mergedRangeAddress));
+        }
+
         int tempCopyIndex = sourceSheet.getWorkbook().getSheetIndex(sourceCopy);
         sourceSheet.getWorkbook().removeSheetAt(tempCopyIndex);
     }
 
-    private void copyRange(CellRangeAddress sourceRange, int deltaX, int deltaY, Sheet sourceClone) { //NOSONAR, it's a bit complex but monolith method, does not make much sense to divide it
+    private void copyRange(CellRangeAddress sourceRange, int deltaX, int deltaY, Sheet sourceClone, Map<Integer, CellStyle> styleMap) { //NOSONAR, it's a bit complex but monolith method, does not make much sense to divide it
         if(deltaX != 0)
             horizontalFormulaShifter = FormulaShifter.createForColumnCopy(sourceSheet.getWorkbook().getSheetIndex(sourceSheet),
                     sourceSheet.getSheetName(), sourceRange.getFirstColumn(), sourceRange.getLastColumn(), deltaX, sourceSheet.getWorkbook().getSpreadsheetVersion());
@@ -105,7 +125,7 @@ public abstract class RangeCopier {
                     newCell = destRow.createCell(columnIndex + deltaX);
                 }
 
-                cloneCellContent(sourceCell, newCell, null);
+                cloneCellContent(sourceCell, newCell, styleMap);
                 if(newCell.getCellType() == CellType.FORMULA)
                     adjustCellReferencesInsideFormula(newCell, destSheet, deltaX, deltaY);
             }

Modified: poi/trunk/src/testcases/org/apache/poi/ss/usermodel/TestRangeCopier.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/ss/usermodel/TestRangeCopier.java?rev=1877792&r1=1877791&r2=1877792&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/ss/usermodel/TestRangeCopier.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/ss/usermodel/TestRangeCopier.java Fri May 15 19:46:17 2020
@@ -19,14 +19,14 @@
 
 package org.apache.poi.ss.usermodel;
 
-import static org.junit.Assert.assertEquals;
-
 import org.junit.Ignore;
 import org.junit.Test;
 import org.apache.poi.ss.ITestDataProvider;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellReference;
 
+import static org.junit.Assert.*;
+
 @Ignore
 public abstract class TestRangeCopier {
     protected Sheet sheet1;
@@ -116,13 +116,57 @@ public abstract class TestRangeCopier {
         assertEquals("1.2", getCellContent(sheet1, "G24"));
     }
 
-    protected static String getCellContent(Sheet sheet, String coordinates) {
+    @Test
+    public void testCopyStyles() {
+        String cellContent = "D6 aligned to the right";
+        HorizontalAlignment toTheRight = HorizontalAlignment.RIGHT;
+        // create cell with content aligned to the right
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(toTheRight);
+        Cell cell = sheet1.createRow(5).createCell(3);
+        cell.setCellValue(cellContent);
+        cell.setCellStyle(style);
+
+        Sheet destSheet = sheet2;
+        CellRangeAddress tileRange = CellRangeAddress.valueOf("D6:D6"); // on sheet1
+        CellRangeAddress destRange = CellRangeAddress.valueOf("J6:J6"); // on sheet2
+        transSheetRangeCopier.copyRange(tileRange, destRange, true, false);
+        assertEquals(cellContent, getCellContent(destSheet, "J6"));
+        assertEquals(toTheRight, getCell(destSheet, "J6").getCellStyle().getAlignment());
+    }
+
+    @Test
+    public void testMergedRanges() {
+        String cellContent = "D6 merged to E7";
+
+        // create cell merged from D6 to E7
+        CellRangeAddress mergedRangeAddress = new CellRangeAddress(5,6,3,4);
+        Cell cell = sheet1.createRow(5).createCell(3);
+        cell.setCellValue(cellContent);
+        sheet1.addMergedRegion(mergedRangeAddress);
+
+        Sheet destSheet = sheet2;
+        CellRangeAddress tileRange = CellRangeAddress.valueOf("D6:E7"); // on sheet1
+        transSheetRangeCopier.copyRange(tileRange, tileRange, false, true);
+        assertEquals(cellContent, getCellContent(destSheet, "D6"));
+        assertFalse(destSheet.getMergedRegions().isEmpty());
+        destSheet.getMergedRegions().forEach((mergedRegion) -> {
+            assertTrue(mergedRegion.equals(mergedRangeAddress));
+        });
+    }
+
+   protected static String getCellContent(Sheet sheet, String coordinates) {
+        Cell cell = getCell(sheet, coordinates);
+        return cell == null ? "" : cell.toString();
+   }
+
+   protected static Cell getCell(Sheet sheet, String coordinates) {
         try {
             CellReference p = new CellReference(coordinates);
-            return sheet.getRow(p.getRow()).getCell(p.getCol()).toString();
+            return sheet.getRow(p.getRow()).getCell(p.getCol());
         }
         catch (NullPointerException e) { // row or cell does not exist
-            return "";
+            return null;
         }
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org