This is an automated email from the ASF dual-hosted git repository.
fanningpj pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
The following commit(s) were added to refs/heads/trunk by this push:
new 006e49765c Bugzilla 69303: Fix RangeCopier's copyMergedRanges when
copying withing the same sheet (#958)
006e49765c is described below
commit 006e49765c641380dbf3bca12196358e1702bdd4
Author: vo0ff <[email protected]>
AuthorDate: Tue Dec 2 00:38:04 2025 +0300
Bugzilla 69303: Fix RangeCopier's copyMergedRanges when copying withing the
same sheet (#958)
* Bugzilla 69303: added failing test for case with same sheet RangeCopier
for merged regions
* Bugzilla 69303: fixed same sheet issue when enabling copy of merged ranges
* Bugzilla 69303: added @since 6.0.0 to new public methods
---------
Co-authored-by: Viktor Ozerov <[email protected]>
---
.../org/apache/poi/ss/usermodel/RangeCopier.java | 15 ++++++++++----
.../org/apache/poi/ss/util/CellRangeAddress.java | 14 +++++++++++++
.../apache/poi/ss/util/CellRangeAddressBase.java | 15 ++++++++++++++
.../poi/ss/usermodel/BaseTestRangeCopier.java | 24 +++++++++++++++++++---
4 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/poi/src/main/java/org/apache/poi/ss/usermodel/RangeCopier.java
b/poi/src/main/java/org/apache/poi/ss/usermodel/RangeCopier.java
index c6b82a6860..97aaa94e79 100644
--- a/poi/src/main/java/org/apache/poi/ss/usermodel/RangeCopier.java
+++ b/poi/src/main/java/org/apache/poi/ss/usermodel/RangeCopier.java
@@ -54,9 +54,11 @@ public abstract class RangeCopier {
}
/** 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.
+ * <ol>
+ * <li>Start from top-left of destination.</li>
+ * <li>Paste source but only inside of destination borders.</li>
+ * <li>If there is space left on right or bottom side of copy, process
it as in step 2.</li>
+ * </ol>
* @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
@@ -90,7 +92,12 @@ public abstract class RangeCopier {
} while (nextRowIndexToCopy <= tileDestRange.getLastRow());
if (copyMergedRanges) {
- sourceSheet.getMergedRegions().forEach((mergedRangeAddress) ->
destSheet.addMergedRegion(mergedRangeAddress));
+ int rowOffset = tileDestRange.getFirstRow() -
tilePatternRange.getFirstRow();
+ int columnOffset = tileDestRange.getFirstColumn() -
tilePatternRange.getFirstColumn();
+ sourceSheet.getMergedRegions().stream()
+ .filter(tilePatternRange::contains)
+ .map(sourceMergedRegion ->
sourceMergedRegion.shift(rowOffset, columnOffset))
+ .forEach(destSheet::addMergedRegion);
}
int tempCopyIndex =
sourceSheet.getWorkbook().getSheetIndex(sourceCopy);
diff --git a/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddress.java
b/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddress.java
index 91a60273a4..9cd1612d8f 100644
--- a/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddress.java
+++ b/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddress.java
@@ -133,4 +133,18 @@ public class CellRangeAddress extends CellRangeAddressBase
{
}
return new CellRangeAddress(a.getRow(), b.getRow(), a.getCol(),
b.getCol());
}
+
+ /**
+ * Shifts cell range by specified number of rows and columns.
+ *
+ * @param rows rows to shift by.
+ * @param columns columns to shift by.
+ * @return copy of this {@link CellRangeAddress}, shifted by rows and
columns.
+ * @since 6.0.0
+ */
+ public CellRangeAddress shift(int rows, int columns) {
+ return new CellRangeAddress(getFirstRow() + rows, getLastRow() + rows,
+ getFirstColumn() + columns, getLastColumn() + columns);
+ }
+
}
diff --git a/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
b/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
index 7153dff29a..3b2e1e373c 100644
--- a/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
+++ b/poi/src/main/java/org/apache/poi/ss/util/CellRangeAddressBase.java
@@ -228,6 +228,21 @@ public abstract class CellRangeAddressBase implements
Iterable<CellAddress>, Dup
other._firstCol <= this._lastCol;
}
+ /**
+ * Determines whether this CellRangeAddress fully contains
CellRangeAddress.
+ *
+ * @param other a candidate cell range address to check if contained
within this range
+ * @return returns true if this range contains other range.
+ * @see #isInRange(int, int) for checking if a single cell contains
+ * @since 6.0.0
+ */
+ public boolean contains(CellRangeAddressBase other) {
+ return this._firstRow <= other._firstRow &&
+ this._lastRow >= other._lastRow &&
+ this._firstCol <= other._firstCol &&
+ this._lastCol >= other._lastCol;
+ }
+
/**
* Useful for logic like table/range styling, where some elements apply
based on relative position in a range.
* @return set of {@link CellPosition}s occupied by the given coordinates.
Empty if the coordinates are not in the range, never null.
diff --git
a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRangeCopier.java
b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRangeCopier.java
index 6239eb22b5..5ba489385b 100644
--- a/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRangeCopier.java
+++ b/poi/src/test/java/org/apache/poi/ss/usermodel/BaseTestRangeCopier.java
@@ -152,9 +152,27 @@ public abstract class BaseTestRangeCopier {
transSheetRangeCopier.copyRange(tileRange, tileRange, false, true);
assertEquals(cellContent, getCellContent(destSheet, "D6"));
assertFalse(destSheet.getMergedRegions().isEmpty());
- destSheet.getMergedRegions().forEach((mergedRegion) -> {
- assertEquals(mergedRangeAddress, mergedRegion);
- });
+ destSheet.getMergedRegions().forEach(mergedRegion ->
+ assertEquals(mergedRangeAddress, mergedRegion)
+ );
+ }
+
+ @Test
+ void testSameSheetMergedRanges() {
+ 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);
+
+ CellRangeAddress tileRange = CellRangeAddress.valueOf("D6:E7");
+ CellRangeAddress targetRange = CellRangeAddress.valueOf("D8:E9");
+ rangeCopier.copyRange(tileRange, targetRange, false, true);
+ assertEquals(cellContent, getCellContent(sheet1, "D8"));
+ assertFalse(sheet1.getMergedRegions().isEmpty());
+
assertTrue(sheet1.getMergedRegions().stream().anyMatch(targetRange::equals));
}
protected static String getCellContent(Sheet sheet, String coordinates) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]