diff --git a/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/Excel/XLWorkbook_Save.cs index 8f47b30..74f0f52 100644 --- a/ClosedXML/Excel/XLWorkbook_Save.cs +++ b/ClosedXML/Excel/XLWorkbook_Save.cs @@ -5189,21 +5189,35 @@ #region RowBreaks - if (!worksheetPart.Worksheet.Elements().Any()) - { - var previousElement = cm.GetPreviousElementFor(XLWSContentManager.XLWSContents.RowBreaks); - worksheetPart.Worksheet.InsertAfter(new RowBreaks(), previousElement); - } - - var rowBreaks = worksheetPart.Worksheet.Elements().First(); - var rowBreakCount = xlWorksheet.PageSetup.RowBreaks.Count; if (rowBreakCount > 0) { + if (!worksheetPart.Worksheet.Elements().Any()) + { + var previousElement = cm.GetPreviousElementFor(XLWSContentManager.XLWSContents.RowBreaks); + worksheetPart.Worksheet.InsertAfter(new RowBreaks(), previousElement); + } + + var rowBreaks = worksheetPart.Worksheet.Elements().First(); + + var existingBreaks = rowBreaks.ChildElements.OfType(); + var rowBreaksToDelete = existingBreaks + .Where(rb => !rb.Id.HasValue || + !xlWorksheet.PageSetup.RowBreaks.Contains((int)rb.Id.Value)) + .ToList(); + + foreach (var rb in rowBreaksToDelete) + { + rowBreaks.RemoveChild(rb); + } + + var rowBreaksToAdd = xlWorksheet.PageSetup.RowBreaks + .Where(xlRb => !existingBreaks.Any(rb => rb.Id.HasValue && rb.Id.Value == xlRb)); + rowBreaks.Count = (UInt32)rowBreakCount; rowBreaks.ManualBreakCount = (UInt32)rowBreakCount; var lastRowNum = (UInt32)xlWorksheet.RangeAddress.LastAddress.RowNumber; - foreach (var break1 in xlWorksheet.PageSetup.RowBreaks.Select(rb => new Break + foreach (var break1 in rowBreaksToAdd.Select(rb => new Break { Id = (UInt32)rb, Max = lastRowNum, @@ -5222,21 +5236,35 @@ #region ColumnBreaks - if (!worksheetPart.Worksheet.Elements().Any()) - { - var previousElement = cm.GetPreviousElementFor(XLWSContentManager.XLWSContents.ColumnBreaks); - worksheetPart.Worksheet.InsertAfter(new ColumnBreaks(), previousElement); - } - - var columnBreaks = worksheetPart.Worksheet.Elements().First(); - var columnBreakCount = xlWorksheet.PageSetup.ColumnBreaks.Count; if (columnBreakCount > 0) { + if (!worksheetPart.Worksheet.Elements().Any()) + { + var previousElement = cm.GetPreviousElementFor(XLWSContentManager.XLWSContents.ColumnBreaks); + worksheetPart.Worksheet.InsertAfter(new ColumnBreaks(), previousElement); + } + + var columnBreaks = worksheetPart.Worksheet.Elements().First(); + + var existingBreaks = columnBreaks.ChildElements.OfType(); + var columnBreaksToDelete = existingBreaks + .Where(cb => !cb.Id.HasValue || + !xlWorksheet.PageSetup.ColumnBreaks.Contains((int)cb.Id.Value)) + .ToList(); + + foreach (var rb in columnBreaksToDelete) + { + columnBreaks.RemoveChild(rb); + } + + var columnBreaksToAdd = xlWorksheet.PageSetup.ColumnBreaks + .Where(xlCb => !existingBreaks.Any(cb => cb.Id.HasValue && cb.Id.Value == xlCb)); + columnBreaks.Count = (UInt32)columnBreakCount; columnBreaks.ManualBreakCount = (UInt32)columnBreakCount; var maxColumnNumber = (UInt32)xlWorksheet.RangeAddress.LastAddress.ColumnNumber; - foreach (var break1 in xlWorksheet.PageSetup.ColumnBreaks.Select(cb => new Break + foreach (var break1 in columnBreaksToAdd.Select(cb => new Break { Id = (UInt32)cb, Max = maxColumnNumber, diff --git a/ClosedXML_Tests/Excel/Saving/SavingTests.cs b/ClosedXML_Tests/Excel/Saving/SavingTests.cs index 2dc3f2f..d17ab21 100644 --- a/ClosedXML_Tests/Excel/Saving/SavingTests.cs +++ b/ClosedXML_Tests/Excel/Saving/SavingTests.cs @@ -191,6 +191,32 @@ Assert.Throws(typeof(UnauthorizedAccessException), saveAs); } + [Test] + public void PageBreaksDontDuplicateAtSaving() + { + // https://github.com/ClosedXML/ClosedXML/issues/666 + + using (var ms = new MemoryStream()) + { + using (var wb1 = new XLWorkbook()) + { + var ws = wb1.Worksheets.Add("Page Breaks"); + ws.PageSetup.PrintAreas.Add("A1:D5"); + ws.PageSetup.AddHorizontalPageBreak(2); + ws.PageSetup.AddVerticalPageBreak(2); + wb1.SaveAs(ms); + wb1.Save(); + } + using (var wb2 = new XLWorkbook(ms)) + { + var ws = wb2.Worksheets.First(); + + Assert.AreEqual(1, ws.PageSetup.ColumnBreaks.Count); + Assert.AreEqual(1, ws.PageSetup.RowBreaks.Count); + } + } + } + [TearDown] public void DeleteTempFiles() diff --git a/ClosedXML_Tests/Resource/Examples/PageSetup/Sheets.xlsx b/ClosedXML_Tests/Resource/Examples/PageSetup/Sheets.xlsx index f91eecc..2ac5d1d 100644 --- a/ClosedXML_Tests/Resource/Examples/PageSetup/Sheets.xlsx +++ b/ClosedXML_Tests/Resource/Examples/PageSetup/Sheets.xlsx Binary files differ