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

Some Fixes for Column and Row Shifting #47

Merged
merged 8 commits into from
Jun 30, 2023
26 changes: 4 additions & 22 deletions main/SS/UserModel/Helpers/RowShifter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,13 @@ public List<CellRangeAddress> ShiftMergedRegions(int startRow, int endRow, int n
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
var lastCol = sheet.GetRow(startRow) != null
? sheet.GetRow(startRow).LastCellNum
: sheet.GetRow(endRow) != null
? sheet.GetRow(endRow).LastCellNum
: 0;
if (RemovalNeeded(merged, startRow, endRow, n, lastCol))
{
removedIndices.Add(i);
Expand Down Expand Up @@ -105,25 +101,11 @@ public List<CellRangeAddress> ShiftMergedRegions(int startRow, int endRow, int n
// Keep in sync with {@link ColumnShifter#removalNeeded}
private bool RemovalNeeded(CellRangeAddress merged, int startRow, int endRow, int n, int lastCol)
{
var movedRows = endRow - startRow + 1;

// build a range of the rows that are overwritten, i.e. the target-area, but without
// rows that are moved along
CellRangeAddress overwrite;
if (n > 0)
{
// area is moved down => overwritten area is [endRow + n - movedRows, endRow + n]
var firstRow = Math.Max(endRow + 1, endRow + n - movedRows);
var lastRow = endRow + n;
overwrite = new CellRangeAddress(firstRow, lastRow, 0, lastCol);
}
else
{
// area is moved up => overwritten area is [startRow + n, startRow + n + movedRows]
var firstRow = startRow + n;
var lastRow = Math.Min(startRow - 1, startRow + n + movedRows);
overwrite = new CellRangeAddress(firstRow, lastRow, 0, lastCol);
}
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);
Expand Down
49 changes: 10 additions & 39 deletions ooxml/XSSF/UserModel/Helpers/ColumnShifter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public List<CellRangeAddress> ShiftMergedRegions(
int endColumn,
int n)
{
List<CellRangeAddress> ShiftedRegions = new List<CellRangeAddress>();
List<CellRangeAddress> 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
Expand All @@ -64,13 +64,7 @@ public List<CellRangeAddress> ShiftMergedRegions(
CellRangeAddress merged = sheet.GetMergedRegion(i);

// remove merged region that overlaps Shifting
int lastCol = sheet.GetColumn(startColumn) != null
? sheet.GetColumn(startColumn).LastCellNum
: sheet.GetColumn(endColumn) != null
? sheet.GetColumn(endColumn).LastCellNum
: 0;

if (RemovalNeeded(merged, startColumn, endColumn, n, lastCol))
if (RemovalNeeded(merged, startColumn, endColumn, n))
{
_ = removedIndices.Add(i);
continue;
Expand All @@ -95,7 +89,7 @@ public List<CellRangeAddress> ShiftMergedRegions(
merged.FirstColumn += n;
merged.LastColumn += n;
//have to Remove/add it back
ShiftedRegions.Add(merged);
shiftedRegions.Add(merged);
_ = removedIndices.Add(i);
}
}
Expand All @@ -106,48 +100,25 @@ public List<CellRangeAddress> ShiftMergedRegions(
}

//read so it doesn't Get Shifted again
foreach (CellRangeAddress region in ShiftedRegions)
foreach (CellRangeAddress region in shiftedRegions)
{
_ = sheet.AddMergedRegion(region);
}

return ShiftedRegions;
return shiftedRegions;
}

// Keep in sync with {@link ColumnShifter#removalNeeded}
private bool RemovalNeeded(
CellRangeAddress merged,
int startColumn,
int endColumn,
int n,
int lastCol)
int n)
{
int movedColumns = endColumn - startColumn + 1;

// build a range of the columns that are overwritten, i.e. the
// target-area, but without columns that are moved along
CellRangeAddress overwrite;

if (n > 0)
{
// area is moved down => overwritten area is
// [endColumn + n - movedColumns, endColumn + n]
int firstColumn =
Math.Max(endColumn + 1, endColumn + n - movedColumns);
int lastColumn = endColumn + n;
overwrite =
new CellRangeAddress(firstColumn, lastColumn, 0, lastCol);
}
else
{
// area is moved up => overwritten area is
// [startColumn + n, startColumn + n + movedColumns]
int firstColumn = startColumn + n;
int lastColumn =
Math.Min(startColumn - 1, startColumn + n + movedColumns);
overwrite =
new CellRangeAddress(firstColumn, lastColumn, 0, lastCol);
}
int firstColumn = startColumn + n;
int lastColumn = endColumn + n;
CellRangeAddress overwrite =
new CellRangeAddress(0, sheet.LastRowNum, firstColumn, lastColumn);

// if the merged-region and the overwritten area intersect,
// we need to remove it
Expand Down
73 changes: 23 additions & 50 deletions ooxml/XSSF/UserModel/XSSFSheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,18 @@ public void RemoveColumn(IColumn column)
}
}

if (hyperlinks != null)
{
foreach (XSSFHyperlink link in new List<XSSFHyperlink>(hyperlinks))
{
CellReference ref1 = new CellReference(link.CellRef);
if (ref1.Col == column.ColumnNum)
{
hyperlinks.Remove(link);
}
}
}

DestroyColumn(column);
}

Expand Down Expand Up @@ -4466,7 +4478,7 @@ private int AddMergedRegion(CellRangeAddress region, bool validate)
: worksheet.AddNewMergeCells();
CT_MergeCell ctMergeCell = ctMergeCells.AddNewMergeCell();
ctMergeCell.@ref = region.FormatAsString();
return ctMergeCells.sizeOfMergeCellArray();
return ctMergeCells.sizeOfMergeCellArray() - 1;
}

/// <summary>
Expand Down Expand Up @@ -5065,10 +5077,13 @@ private void RemoveOverwrittenColumns(int startColumn, int endColumn, int n)
throw new RuntimeException("There is no columns in XML part");
}

XSSFVMLDrawing vml = GetVMLDrawing(false);
List<int> columnsToRemove = new List<int>();
List<CellAddress> commentsToRemove = new List<CellAddress>();
List<CT_Col> ctColsToRemove = new List<CT_Col>();
for (int i = startColumn + n; i <= endColumn + n; i++)
{
_ = GetColumn(i) ?? CreateColumn(i);
}

List<IColumn> columnsToRemove = new List<IColumn>();

// first remove all columns which will be overwritten
foreach (KeyValuePair<int, XSSFColumn> columnDict in _columns)
{
Expand All @@ -5079,56 +5094,14 @@ private void RemoveOverwrittenColumns(int startColumn, int endColumn, int n)
// by the data later
if (ShouldRemoveAtIndex(startColumn, endColumn, n, columnNum))
{
int idx = _columns.IndexOfValue(column);
ctColsToRemove.Add(worksheet.cols.FirstOrDefault().GetColArray(idx));

// remove column from _columns
columnsToRemove.Add(columnDict.Key);

commentsToRemove.Clear();

if (sheetComments != null)
{
CT_CommentList lst = sheetComments.GetCTComments().commentList;
foreach (CT_Comment comment in lst.comment)
{
string strRef = comment.@ref;
CellAddress ref1 = new CellAddress(strRef);

// is this comment part of the current column?
if (ref1.Column == columnNum)
{
commentsToRemove.Add(ref1);
}
}
}

foreach (CellAddress ref1 in commentsToRemove)
{
sheetComments.RemoveComment(ref1);
vml.RemoveCommentShape(ref1.Row, ref1.Column);
}

if (hyperlinks != null)
{
foreach (XSSFHyperlink link in new List<XSSFHyperlink>(hyperlinks))
{
CellReference ref1 = new CellReference(link.CellRef);
if (ref1.Col == columnNum)
{
hyperlinks.Remove(link);
}
}
}
columnsToRemove.Add(column);
}
}

foreach (int columnKey in columnsToRemove)
foreach (IColumn column in columnsToRemove)
{
_columns.Remove(columnKey);
RemoveColumn(column);
}

worksheet.cols.FirstOrDefault().RemoveCols(ctColsToRemove);
}

private void RebuildRows()
Expand Down
Loading
Loading