Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ShiftMergedRegions #1462

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 29 additions & 31 deletions main/SS/UserModel/Helpers/RowShifter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,67 +49,65 @@ public List<CellRangeAddress> ShiftMergedRegions(int startRow, int endRow, int n
{
var ShiftedRegions = new List<CellRangeAddress>();
ISet<int> removedIndices = new HashSet<int>();
//move merged regions completely if they fall within the new region boundaries when they are Shifted
var size = sheet.NumMergedRegions;
var lastCol = sheet.Any() ? sheet.Max(r => r.LastCellNum) : 0;

for (var i = 0; i < size; i++)
{
var merged = sheet.GetMergedRegion(i);

// remove merged region that overlaps Shifting
if (RemovalNeeded(merged, startRow, endRow, n, lastCol))
//Shift if the merged region inside the Shifting rows
if (merged.FirstRow >= startRow && merged.LastRow <= endRow)
{
merged.FirstRow += n;
merged.LastRow += n;
//have to Remove/add it back
ShiftedRegions.Add(merged);
removedIndices.Add(i);

continue;
}

var inStart = merged.FirstRow >= startRow || merged.LastRow >= startRow;
var inEnd = merged.FirstRow <= endRow || merged.LastRow <= endRow;

//don't check if it's not within the Shifted area
if (!inStart || !inEnd)
if (n > 0)
{
continue;
// area is moved down
if (merged.LastRow < startRow
|| merged.FirstRow > endRow + n
|| merged.FirstRow > endRow && merged.LastRow < startRow + n
)
{
continue;
}
}

//only shift if the region outside the Shifted rows is not merged too
if (!merged.ContainsRow(startRow - 1) && !merged.ContainsRow(endRow + 1))
else
{
merged.FirstRow += n;
merged.LastRow += n;
//have to Remove/add it back
ShiftedRegions.Add(merged);
removedIndices.Add(i);
// area is moved up
if (merged.LastRow < startRow + n
|| merged.FirstRow > endRow
|| merged.FirstRow > endRow + n && merged.LastRow < startRow
)
{
continue;
}
}

//remove merged region that overlaps Shifting
removedIndices.Add(i);
}

if (removedIndices.Count != 0)
{
sheet.RemoveMergedRegions(removedIndices.ToList());
}

//read so it doesn't Get Shifted again
//add it which is within the shifted area back
foreach (var region in ShiftedRegions)
{
sheet.AddMergedRegion(region);
}

return ShiftedRegions;
}

// Keep in sync with {@link ColumnShifter#removalNeeded}
private bool RemovalNeeded(CellRangeAddress merged, int startRow, int endRow, int n, int lastCol)
{
// build a range of the rows that are overwritten, i.e. the target-area, but without
// rows that are moved along
var firstRow = startRow + n;
var lastRow = endRow + n;
CellRangeAddress overwrite = new CellRangeAddress(firstRow, lastRow, 0, lastCol);

// if the merged-region and the overwritten area intersect, we need to remove it
return merged.Intersects(overwrite);
}

/// <summary>
/// Verify that the given column indices and step denote a valid range of columns to shift
Expand Down
12 changes: 6 additions & 6 deletions testcases/ooxml/XSSF/UserModel/TestXSSFSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,13 @@ public void ShiftRows_ShiftRowsWithVariousMergedRegions_RowsShiftedWithMergedReg
Assert.True(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("J11:K12")));

Assert.AreEqual("regionThatEndsWithinShiftedRows", sheet.GetRow(1).GetCell(11).StringCellValue);
Assert.True(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("L2:M3")));
Assert.False(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("L2:M3")));

Assert.AreEqual("regionThatEndsOnLastShiftedRow", sheet.GetRow(1).GetCell(13).StringCellValue);
Assert.True(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("N2:O4")));
Assert.False(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("N2:O4")));

Assert.AreEqual("regionThatEndsOutsideShiftedRows", sheet.GetRow(1).GetCell(15).StringCellValue);
Assert.True(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("P2:Q5")));
Assert.False(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("P2:Q5")));

Assert.AreEqual("reallyLongRegion", sheet.GetRow(1).GetCell(17).StringCellValue);
Assert.False(sheet.MergedRegions.Any(r => r.FormatAsString().Equals("R2:S12")));
Expand Down Expand Up @@ -180,13 +180,13 @@ public void ShiftRows_ShiftRowsWithVariousMergedRegions_RowsShiftedWithMergedReg
Assert.True(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("J11:K12")));

Assert.AreEqual("regionThatEndsWithinShiftedRows", sheetLoaded.GetRow(1).GetCell(11).StringCellValue);
Assert.True(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("L2:M3")));
Assert.False(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("L2:M3")));

Assert.AreEqual("regionThatEndsOnLastShiftedRow", sheetLoaded.GetRow(1).GetCell(13).StringCellValue);
Assert.True(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("N2:O4")));
Assert.False(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("N2:O4")));

Assert.AreEqual("regionThatEndsOutsideShiftedRows", sheetLoaded.GetRow(1).GetCell(15).StringCellValue);
Assert.True(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("P2:Q5")));
Assert.False(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("P2:Q5")));

Assert.AreEqual("reallyLongRegion", sheetLoaded.GetRow(1).GetCell(17).StringCellValue);
Assert.False(sheetLoaded.MergedRegions.Any(r => r.FormatAsString().Equals("R2:S12")));
Expand Down
Loading