From 7a7099d05ce07cd32bc639e843d8bd214235cd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Fri, 15 Feb 2019 15:56:36 +0700 Subject: [PATCH 01/14] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=BD=D0=BE=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=B4?= =?UTF-8?q?=D0=B8=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлена ошибка копирования диапазонов ячеек, часть которых на момент копирования уже объединена --- EPPlus/EPPlus.csproj | 2 +- EPPlus/ExcelRangeBase.cs | 40 +++++++++++--------- EPPlus/ExcelWorksheet.cs | 80 +++++++++++++++++++++++----------------- 3 files changed, 70 insertions(+), 52 deletions(-) diff --git a/EPPlus/EPPlus.csproj b/EPPlus/EPPlus.csproj index 1f411ce0..00b7eafb 100644 --- a/EPPlus/EPPlus.csproj +++ b/EPPlus/EPPlus.csproj @@ -25,7 +25,7 @@ 3.5 - v3.5 + v4.0 publish\ true Disk diff --git a/EPPlus/ExcelRangeBase.cs b/EPPlus/ExcelRangeBase.cs index 0519de60..216d29f6 100644 --- a/EPPlus/ExcelRangeBase.cs +++ b/EPPlus/ExcelRangeBase.cs @@ -2609,29 +2609,35 @@ public void Copy(ExcelRangeBase Destination, ExcelRangeCopyOptionFlags? excelRan } var copiedMergedCells = new Dictionary(); //Merged cells - var csem = new CellsStoreEnumerator(_worksheet.MergedCells._cells, _fromRow, _fromCol, _toRow, _toCol); - while (csem.Next()) + + for (var row = _fromRow; row <= _toRow; row++) { - if (!copiedMergedCells.ContainsKey(csem.Value)) + for (var col = _fromCol; col <= _toCol; col++) { - var adr = new ExcelAddress(_worksheet.Name, _worksheet.MergedCells.List[csem.Value]); - var collideResult = Collide(adr); - if (collideResult == eAddressCollition.Inside || collideResult == eAddressCollition.Equal) + var key = _worksheet.GetMergeCellId(row, col) - 1; + if (key >= 0 && !copiedMergedCells.ContainsKey(key)) { - copiedMergedCells.Add(csem.Value, new ExcelAddress( - Destination._fromRow + (adr.Start.Row - _fromRow), - Destination._fromCol + (adr.Start.Column - _fromCol), - Destination._fromRow + (adr.End.Row - _fromRow), - Destination._fromCol + (adr.End.Column - _fromCol))); - } - else - { - //Partial merge of the address ignore. - copiedMergedCells.Add(csem.Value, null); + var adr = new ExcelAddress(_worksheet.Name, _worksheet.MergedCells.List[key]); + var collideResult = Collide(adr); + if (collideResult == eAddressCollition.Inside || collideResult == eAddressCollition.Equal) + { + copiedMergedCells.Add( + key, + new ExcelAddress( + Destination._fromRow + (adr.Start.Row - _fromRow), + Destination._fromCol + (adr.Start.Column - _fromCol), + Destination._fromRow + (adr.End.Row - _fromRow), + Destination._fromCol + (adr.End.Column - _fromCol))); + } + else + { + //Partial merge of the address ignore. + copiedMergedCells.Add(key, null); + } } } } - + Destination._worksheet.MergedCells.Clear(new ExcelAddressBase(Destination._fromRow, Destination._fromCol, Destination._fromRow + toRow - 1, Destination._fromCol + toCol - 1)); Destination._worksheet._values.Clear(Destination._fromRow, Destination._fromCol, toRow, toCol); diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs index ac1ff800..d2acad28 100644 --- a/EPPlus/ExcelWorksheet.cs +++ b/EPPlus/ExcelWorksheet.cs @@ -185,13 +185,41 @@ public Formulas Clone() /// public class MergeCellsCollection : IEnumerable { - internal MergeCellsCollection() + private readonly ExcelWorksheet _ws; + internal MergeCellsCollection(ExcelWorksheet ws) { - + _ws = ws; } internal CellStore _cells = new CellStore(); List _list = new List(); internal List List { get { return _list; } } + + /// + /// Get MergeCell Index No + /// + /// + /// + /// + public int GetId(int row, int column) + { + for (int i = 0; i < _list.Count; i++) + { + if(!string.IsNullOrEmpty( _list[i])) + { + ExcelRange range = _ws.Cells[_list[i]]; + + if (range.Start.Row <= row && row <= range.End.Row) + { + if (range.Start.Column <= column && column <= range.End.Column) + { + return i + 1; + } + } + } + } + return 0; + } + public string this[int row, int column] { get @@ -324,26 +352,24 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() #endregion internal void Clear(ExcelAddressBase Destination) { - var cse = new CellsStoreEnumerator(_cells, Destination._fromRow, Destination._fromCol, Destination._toRow, Destination._toCol); - var used = new HashSet(); - while (cse.Next()) + _cells.Clear(Destination._fromRow, Destination._fromCol, Destination._toRow - Destination._fromRow + 1, Destination._toCol - Destination._fromCol + 1); + for (var row = Destination._fromRow; row <= Destination._toRow; row++) { - var v = cse.Value; - if (!used.Contains(v) && _list[v] != null) + for (var col = Destination._fromCol; col <= Destination._toCol; col++) { - var adr = new ExcelAddressBase(_list[v]); - if (!(Destination.Collide(adr) == ExcelAddressBase.eAddressCollition.Inside || Destination.Collide(adr) == ExcelAddressBase.eAddressCollition.Equal)) + var mergedRangeId = GetId(row, col); + if (mergedRangeId == 0) { - throw (new InvalidOperationException(string.Format("Can't delete/overwrite merged cells. A range is partly merged with the another merged range. {0}", adr._address))); + continue; } - used.Add(v); - } - } - _cells.Clear(Destination._fromRow, Destination._fromCol, Destination._toRow - Destination._fromRow + 1, Destination._toCol - Destination._fromCol + 1); - foreach (var i in used) - { - _list[i] = null; + var mergedRangeAddress = new ExcelAddressBase(_list[mergedRangeId]); + if (Destination.Collide(mergedRangeAddress) == ExcelAddressBase.eAddressCollition.Partly) + { + throw (new InvalidOperationException(string.Format("Can't delete/overwrite merged cells. A range is partly merged with the another merged range. {0}", mergedRangeAddress._address))); + } + _list[mergedRangeId] = null; + } } } } @@ -396,6 +422,7 @@ public ExcelWorksheet(XmlNamespaceManager ns, ExcelPackage excelPackage, string _name = sheetName; _sheetID = sheetID; _positionID = positionID; + _mergedCells = new MergeCellsCollection(this); Hidden = hide; /**** Cellstore ****/ @@ -1664,7 +1691,7 @@ public ExcelRange SelectedRange return new ExcelRange(this, View.SelectedRange); } } - MergeCellsCollection _mergedCells = new MergeCellsCollection(); + MergeCellsCollection _mergedCells; /// /// Addresses to merged ranges /// @@ -2863,22 +2890,7 @@ public void SetValue(string Address, object Value) /// public int GetMergeCellId(int row, int column) { - for (int i = 0; i < _mergedCells.Count; i++) - { - if(!string.IsNullOrEmpty( _mergedCells[i])) - { - ExcelRange range = Cells[_mergedCells[i]]; - - if (range.Start.Row <= row && row <= range.End.Row) - { - if (range.Start.Column <= column && column <= range.End.Column) - { - return i + 1; - } - } - } - } - return 0; + return _mergedCells.GetId(row, column); } #endregion From 5da59708cdbb89e79b6b36166b63a7311c04505d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Fri, 22 Feb 2019 10:34:13 +0700 Subject: [PATCH 02/14] =?UTF-8?q?[*]=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B8=20=D1=83=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлены проверки на null при удалении комментариев --- EPPlus/ExcelCommentCollection.cs | 11 +++++++--- EPPlus/ExcelWorksheet.cs | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/EPPlus/ExcelCommentCollection.cs b/EPPlus/ExcelCommentCollection.cs index 9835142f..3b68d9d7 100644 --- a/EPPlus/ExcelCommentCollection.cs +++ b/EPPlus/ExcelCommentCollection.cs @@ -218,10 +218,15 @@ public void Remove(ExcelComment comment) } if (comment==c) { - comment.TopNode.ParentNode.RemoveChild(comment.TopNode); //Remove VML - comment._commentHelper.TopNode.ParentNode.RemoveChild(comment._commentHelper.TopNode); //Remove Comment + // + comment.TopNode.ParentNode?.RemoveChild(comment.TopNode); //Remove VML + comment._commentHelper.TopNode.ParentNode?.RemoveChild(comment._commentHelper.TopNode); //Remove Comment + + if (Worksheet.VmlDrawingsComments._drawings.ContainsKey(id)) + { + Worksheet.VmlDrawingsComments._drawings.Delete(id); + } - Worksheet.VmlDrawingsComments._drawings.Delete(id); _list.RemoveAt(i); Worksheet._commentsStore.Delete(comment.Range._fromRow, comment.Range._fromCol, 1, 1, false); //Issue 15549, Comments should not be shifted var ci = new CellsStoreEnumerator(Worksheet._commentsStore); diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs index d2acad28..b5e34299 100644 --- a/EPPlus/ExcelWorksheet.cs +++ b/EPPlus/ExcelWorksheet.cs @@ -2551,8 +2551,27 @@ public void DeleteRow(int rowFrom, int rows) { throw(new ArgumentException("Row out of range. Spans from 1 to " + ExcelPackage.MaxRows.ToString(CultureInfo.InvariantCulture))); } + lock (this) { + var commentsDictionary = new List(); + + foreach (ExcelComment excelComment in Comments) + { + var commentRow = Cells[excelComment.Reference].Start.Row; + if (commentRow < rowFrom) + { + continue; + } + + commentsDictionary.Add(excelComment); + } + + foreach (var c in commentsDictionary) + { + Comments.Remove(c); + } + _values.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns); _formulas.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns); _flags.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns); @@ -2570,6 +2589,7 @@ public void DeleteRow(int rowFrom, int rows) { tbl.Address = tbl.Address.DeleteRow(rowFrom, rows); } + foreach (var ptbl in PivotTables) { if (ptbl.Address.Start.Row > rowFrom + rows) @@ -2577,6 +2597,7 @@ public void DeleteRow(int rowFrom, int rows) ptbl.Address = ptbl.Address.DeleteRow(rowFrom, rows); } } + //Issue 15573 foreach (ExcelDataValidation dv in DataValidations) { @@ -2590,6 +2611,20 @@ public void DeleteRow(int rowFrom, int rows) } } } + + foreach (var commentToShift in commentsDictionary) + { + var commentTarget = Cells[commentToShift.Range.Start.Row - rows, commentToShift.Range.Start.Column]; + var existingComment = commentTarget.Comment; + if (existingComment != null) + { + existingComment.Text = commentToShift.Text; + } + else + { + commentTarget.AddComment(commentToShift.Text, commentToShift.Author); + } + } } } /// From c7902b228c94a6a3f2467d457867e90ff3050465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Mon, 25 Feb 2019 15:49:20 +0700 Subject: [PATCH 03/14] =?UTF-8?q?[*]=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D1=80=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B5=20=D1=81=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=B4=D0=B8=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8=20=D1=8F=D1=87=D0=B5=D0=B9?= =?UTF-8?q?=D0=BA=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлена ошибка --- EPPlus/ExcelWorksheet.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs index b5e34299..8f3d0124 100644 --- a/EPPlus/ExcelWorksheet.cs +++ b/EPPlus/ExcelWorksheet.cs @@ -358,12 +358,15 @@ internal void Clear(ExcelAddressBase Destination) for (var col = Destination._fromCol; col <= Destination._toCol; col++) { var mergedRangeId = GetId(row, col); + if (mergedRangeId == 0) { continue; } - var mergedRangeAddress = new ExcelAddressBase(_list[mergedRangeId]); + // из метода GetId возвращается индекс в списке _list + 1, т.к. результат 0 означает, что значение в списке не найдено + // поэтому, чтобы восстановить исходный индекс, передаем mergedRangeId-1 + var mergedRangeAddress = new ExcelAddressBase(_list[mergedRangeId-1]); if (Destination.Collide(mergedRangeAddress) == ExcelAddressBase.eAddressCollition.Partly) { throw (new InvalidOperationException(string.Format("Can't delete/overwrite merged cells. A range is partly merged with the another merged range. {0}", mergedRangeAddress._address))); From 4f3a917a2aa3f68f9aab4df82c7cdc52c2cf6ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Tue, 19 Mar 2019 17:38:22 +0700 Subject: [PATCH 04/14] =?UTF-8?q?[*]=20=D0=98=D1=81=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=87=D0=B8=D1=81=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=84=D0=BE=D1=80=D0=BC=D1=83=D0=BB,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Убрана логика замены формул, синтаксис которых является некорректным (их невозможно вычислить движком excel) на string.Empty --- EPPlus/ExcelRangeBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EPPlus/ExcelRangeBase.cs b/EPPlus/ExcelRangeBase.cs index 216d29f6..f325c7f0 100644 --- a/EPPlus/ExcelRangeBase.cs +++ b/EPPlus/ExcelRangeBase.cs @@ -257,7 +257,7 @@ private static void Set_Value(ExcelRangeBase range, object value, int row, int c { range.SplitFormulas(range._worksheet.Cells[row, col]); } - if (sfi != null) range._worksheet._formulas.SetValue(row, col, string.Empty); + // if (sfi != null) range._worksheet._formulas.SetValue(row, col, string.Empty); range._worksheet.SetValueInner(row, col, value); } private static void Set_Formula(ExcelRangeBase range, object value, int row, int col) From 271139626631c049172488f30d4cf8d3437d7428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Tue, 19 Mar 2019 17:39:59 +0700 Subject: [PATCH 05/14] =?UTF-8?q?[*]=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=B0=D0=BD=D0=BE=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20xlsx,=20=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D1=8E=D1=89=D0=B8=D1=85=20=D0=B2=20=D1=81=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B0=D0=B2=D0=B5=20=D0=BC=D0=B0=D0=BA=D1=80=D0=BE=D1=81?= =?UTF-8?q?=D1=8B=20VBA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По умолчанию при копировании листа содержимое VBA-проекта данного листа не копируется --- EPPlus/ExcelWorksheets.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EPPlus/ExcelWorksheets.cs b/EPPlus/ExcelWorksheets.cs index 715d4693..82fbe0f6 100644 --- a/EPPlus/ExcelWorksheets.cs +++ b/EPPlus/ExcelWorksheets.cs @@ -153,7 +153,7 @@ public ExcelWorksheet Add(string Name) ExcelWorksheet worksheet = AddSheet(Name,false, null); return worksheet; } - private ExcelWorksheet AddSheet(string Name, bool isChart, eChartType? chartType, ExcelPivotTable pivotTableSource = null) + private ExcelWorksheet AddSheet(string Name, bool isChart, eChartType? chartType, ExcelPivotTable pivotTableSource = null, bool createVbaModule = false) { int sheetID; Uri uriWorksheet; @@ -187,7 +187,7 @@ private ExcelWorksheet AddSheet(string Name, bool isChart, eChartType? chartType } _worksheets.Add(positionID, worksheet); - if (_pck.Workbook.VbaProject != null) + if (createVbaModule && _pck.Workbook.VbaProject != null) { var name = _pck.Workbook.VbaProject.GetModuleNameFromWorksheet(worksheet); _pck.Workbook.VbaProject.Modules.Add(new ExcelVBAModule(worksheet.CodeNameChange) { Name = name, Code = "", Attributes = _pck.Workbook.VbaProject.GetDocumentAttributes(Name, "0{00020820-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 }); @@ -202,7 +202,7 @@ private ExcelWorksheet AddSheet(string Name, bool isChart, eChartType? chartType /// /// The name of the workbook /// The worksheet to be copied - public ExcelWorksheet Add(string Name, ExcelWorksheet Copy) + public ExcelWorksheet Add(string Name, ExcelWorksheet Copy, bool copyVba= false) { lock (_worksheets) { @@ -268,7 +268,7 @@ public ExcelWorksheet Add(string Name, ExcelWorksheet Copy) CloneCells(Copy, added); //Copy the VBA code - if (_pck.Workbook.VbaProject != null) + if (copyVba && _pck.Workbook.VbaProject != null) { var name = _pck.Workbook.VbaProject.GetModuleNameFromWorksheet(added); _pck.Workbook.VbaProject.Modules.Add(new ExcelVBAModule(added.CodeNameChange) { Name = name, Code = Copy.CodeModule.Code, Attributes = _pck.Workbook.VbaProject.GetDocumentAttributes(Name, "0{00020820-0000-0000-C000-000000000046}"), Type = eModuleType.Document, HelpContext = 0 }); From e0c434996932a22724ff8aa09572f679fa4d1fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Tue, 19 Mar 2019 17:41:15 +0700 Subject: [PATCH 06/14] =?UTF-8?q?[*]=20fix=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BA=D0=BE=D0=BF=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D0=B8?= =?UTF-8?q?=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлена ошибка копирования стилей, при которой после копирования неименованного стиля его идентификатор начинал совпадать с идентификатором одного из именованных стилей --- EPPlus/ExcelStyles.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EPPlus/ExcelStyles.cs b/EPPlus/ExcelStyles.cs index 79708310..cfdc8a20 100644 --- a/EPPlus/ExcelStyles.cs +++ b/EPPlus/ExcelStyles.cs @@ -953,6 +953,7 @@ internal int CloneStyle(ExcelStyles style, int styleID, bool isNamedStyle, bool xfs = style.CellXfs[styleID]; } ExcelXfs newXfs = xfs.Copy(this); + newXfs.XfId = 0; //Numberformat if (xfs.NumberFormatId > 0) { @@ -1026,7 +1027,7 @@ internal int CloneStyle(ExcelStyles style, int styleID, bool isNamedStyle, bool } //Named style reference - if (xfs.XfId > 0) + if (isNamedStyle && xfs.XfId > 0) { var id = style.CellStyleXfs[xfs.XfId].Id; var newId = CellStyleXfs.FindIndexByID(id); From 5c4c97f5b3582de9d9b3ecae869046588d16ceb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Tue, 19 Mar 2019 17:41:38 +0700 Subject: [PATCH 07/14] =?UTF-8?q?[*]=20fix=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D1=80=D0=B8=20=D0=BE=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8=20=D1=81=20=D0=BE=D0=B1=D1=8A=D0=B5?= =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8=20=D1=8F?= =?UTF-8?q?=D1=87=D0=B5=D0=B9=D0=BA=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPPlus/ExcelWorksheet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs index 8f3d0124..c85b899a 100644 --- a/EPPlus/ExcelWorksheet.cs +++ b/EPPlus/ExcelWorksheet.cs @@ -371,7 +371,7 @@ internal void Clear(ExcelAddressBase Destination) { throw (new InvalidOperationException(string.Format("Can't delete/overwrite merged cells. A range is partly merged with the another merged range. {0}", mergedRangeAddress._address))); } - _list[mergedRangeId] = null; + _list[mergedRangeId-1] = null; } } } From 8e8b8aa628f97ce923dc1912eee6fe909a3d9f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Mon, 25 Mar 2019 16:35:51 +0700 Subject: [PATCH 08/14] =?UTF-8?q?[*]=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B5=20=D1=81=20sharedformulas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлены ошибки при работе с sharedformulas --- EPPlus/ExcelRangeBase.cs | 4 ++-- EPPlus/Properties/AssemblyInfo.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/EPPlus/ExcelRangeBase.cs b/EPPlus/ExcelRangeBase.cs index f325c7f0..67884c3d 100644 --- a/EPPlus/ExcelRangeBase.cs +++ b/EPPlus/ExcelRangeBase.cs @@ -253,7 +253,7 @@ private static void Set_StyleName(ExcelRangeBase range, object value, int row, i private static void Set_Value(ExcelRangeBase range, object value, int row, int col) { var sfi = range._worksheet._formulas.GetValue(row, col); - if (sfi is int) + if (sfi is int && !range.IsSingleCell) { range.SplitFormulas(range._worksheet.Cells[row, col]); } @@ -1608,7 +1608,7 @@ private void SplitFormula(ExcelAddressBase address, int ix) //The formula is inside the currenct range, remove it if (collide == eAddressCollition.Equal || collide == eAddressCollition.Inside) { - _worksheet._sharedFormulas.Remove(ix); + // _worksheet._sharedFormulas.Remove(ix); return; //fRange.SetSharedFormulaID(int.MinValue); } diff --git a/EPPlus/Properties/AssemblyInfo.cs b/EPPlus/Properties/AssemblyInfo.cs index b5c8c7fc..7862bff1 100644 --- a/EPPlus/Properties/AssemblyInfo.cs +++ b/EPPlus/Properties/AssemblyInfo.cs @@ -46,7 +46,7 @@ // // Major Version // Minor Version -// Build Number +// Build NumberS // Revision // // You can specify all the values or you can default the Revision and Build Numbers @@ -62,7 +62,7 @@ //[assembly: AssemblyCulture("")] //[assembly: ComVisible(false)] - //[assembly: AssemblyVersion("4.5.0.0")] - //[assembly: AssemblyFileVersion("4.5.0.0")] + [assembly: AssemblyVersion("4.5.3.6")] + [assembly: AssemblyFileVersion("4.5.3.6")] #endif [assembly: AllowPartiallyTrustedCallers] \ No newline at end of file From d618502ef26f1fcd7c62ce7cf9cc18f72135ba7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Mon, 25 Mar 2019 16:36:20 +0700 Subject: [PATCH 09/14] Update .gitignore --- .gitignore | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4bcc6612..4bc5bde0 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,12 @@ _ReSharper*/ ~$* #NuGet -packages/ \ No newline at end of file +packages/ +.idea/.idea.EPPlus/.idea/contentModel.xml +.idea/.idea.EPPlus/.idea/encodings.xml +.idea/.idea.EPPlus/.idea/indexLayout.xml +.idea/.idea.EPPlus/.idea/misc.xml +.idea/.idea.EPPlus/.idea/modules.xml +.idea/.idea.EPPlus/.idea/vcs.xml +.idea/.idea.EPPlus/.idea/workspace.xml +.idea/.idea.EPPlus/riderModule.iml From 1ac41a4c7b23372e5d9589d162eb12773449ad5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Fri, 29 Mar 2019 12:52:26 +0700 Subject: [PATCH 10/14] =?UTF-8?q?[*]=20=D0=98=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8?= =?UTF-8?q?=D0=B5=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлена ошибка обработки комментариев при копировании/удалении строк, в ячейках которых содержались комментарии --- EPPlus/Drawing/Vml/ExcelVmlDrawingCommentCollection.cs | 10 +++++++++- EPPlus/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/EPPlus/Drawing/Vml/ExcelVmlDrawingCommentCollection.cs b/EPPlus/Drawing/Vml/ExcelVmlDrawingCommentCollection.cs index d10f0af7..9dd780d8 100644 --- a/EPPlus/Drawing/Vml/ExcelVmlDrawingCommentCollection.cs +++ b/EPPlus/Drawing/Vml/ExcelVmlDrawingCommentCollection.cs @@ -113,7 +113,15 @@ private XmlNode AddDrawing(ExcelRangeBase cell) { ix = ~ix; var prevDraw = _drawings[ix] as ExcelVmlDrawingBase; - prevDraw.TopNode.ParentNode.InsertBefore(node, prevDraw.TopNode); + var parentNode = prevDraw.TopNode.ParentNode; + if (parentNode!=null) + { + parentNode.InsertBefore(node, prevDraw.TopNode); + } + else + { + VmlDrawingXml.DocumentElement.AppendChild(node); + } } else { diff --git a/EPPlus/Properties/AssemblyInfo.cs b/EPPlus/Properties/AssemblyInfo.cs index 7862bff1..b111fb50 100644 --- a/EPPlus/Properties/AssemblyInfo.cs +++ b/EPPlus/Properties/AssemblyInfo.cs @@ -62,7 +62,7 @@ //[assembly: AssemblyCulture("")] //[assembly: ComVisible(false)] - [assembly: AssemblyVersion("4.5.3.6")] - [assembly: AssemblyFileVersion("4.5.3.6")] + [assembly: AssemblyVersion("4.5.3.7")] + [assembly: AssemblyFileVersion("4.5.3.7")] #endif [assembly: AllowPartiallyTrustedCallers] \ No newline at end of file From e46b0d56374bc9aa56d23b682f9f2f2235a7d293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Thu, 11 Apr 2019 09:17:08 +0700 Subject: [PATCH 11/14] =?UTF-8?q?[*]=20=D0=9E=D0=BF=D1=82=D0=B8=D0=BC?= =?UTF-8?q?=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D1=8B=20=D1=81=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=B4=D0=B8=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8;=20=D1=80=D0=B5=D0=B0?= =?UTF-8?q?=D0=BB=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7?= =?UTF-8?q?=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B8=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D1=83=20=D0=BF=D0=B5=D1=80=D0=B5=D1=81?= =?UTF-8?q?=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=8A=D0=B5=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B8=20=D1=8F=D1=87=D0=B5=D0=B5=D0=BA=20=D0=BB=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Оптимизирована логика поиска пересечений диапазона объединямых ячеек с уже существующими объединенными ячейками листа --- EPPlus/ExcelRangeBase.cs | 6 +++++- EPPlus/ExcelWorksheet.cs | 44 ++++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/EPPlus/ExcelRangeBase.cs b/EPPlus/ExcelRangeBase.cs index 67884c3d..50921ec2 100644 --- a/EPPlus/ExcelRangeBase.cs +++ b/EPPlus/ExcelRangeBase.cs @@ -1270,7 +1270,11 @@ public bool Merge set { IsRangeValid("merging"); - _worksheet.MergedCells.Clear(this); + if (!_worksheet.DisableMergeValidation) + { + _worksheet.MergedCells.Clear(this); + } + if (value) { _worksheet.MergedCells.Add(new ExcelAddressBase(FirstAddress), true); diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs index c85b899a..3494afb2 100644 --- a/EPPlus/ExcelWorksheet.cs +++ b/EPPlus/ExcelWorksheet.cs @@ -185,6 +185,25 @@ public Formulas Clone() /// public class MergeCellsCollection : IEnumerable { + private struct AddressDimensions + { + internal int StartRow; + + internal int StartCol; + + internal int EndRow; + + internal int EndCol; + + internal AddressDimensions(int startRow, int startCol, int endRow, int endCol) + { + StartRow = startRow; + StartCol = startCol; + EndRow = endRow; + EndCol = endCol; + } + } + private readonly ExcelWorksheet _ws; internal MergeCellsCollection(ExcelWorksheet ws) { @@ -194,6 +213,8 @@ internal MergeCellsCollection(ExcelWorksheet ws) List _list = new List(); internal List List { get { return _list; } } + private IDictionary _mergedAreasDimsCache = new Dictionary(); + /// /// Get MergeCell Index No /// @@ -204,13 +225,20 @@ public int GetId(int row, int column) { for (int i = 0; i < _list.Count; i++) { - if(!string.IsNullOrEmpty( _list[i])) + var mergedAddress = _list[i]; + if(!string.IsNullOrEmpty( mergedAddress)) { - ExcelRange range = _ws.Cells[_list[i]]; - - if (range.Start.Row <= row && row <= range.End.Row) + if (!_mergedAreasDimsCache.ContainsKey(mergedAddress)) + { + ExcelCellBase.GetRowColFromAddress(mergedAddress, out var startRow, out var startColumn, out int toRow, out int toColumn); + _mergedAreasDimsCache.Add(mergedAddress, new AddressDimensions(startRow, startColumn, toRow, toColumn)); + } + + var mergedDims = _mergedAreasDimsCache[mergedAddress]; + + if (mergedDims.StartRow <= row && row <= mergedDims.EndRow) { - if (range.Start.Column <= column && column <= range.End.Column) + if (mergedDims.StartCol <= column && column <= mergedDims.EndCol) { return i + 1; } @@ -254,6 +282,7 @@ internal void Add(ExcelAddressBase address, bool doValidate) lock (this) { ix = _list.Count; + _mergedAreasDimsCache.Add(address.Address, new AddressDimensions(address.Start.Row, address.Start.Column, address.End.Row, address.End.Column)); _list.Add(address.Address); SetIndex(address, ix); } @@ -352,6 +381,7 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() #endregion internal void Clear(ExcelAddressBase Destination) { + var used = new HashSet(); _cells.Clear(Destination._fromRow, Destination._fromCol, Destination._toRow - Destination._fromRow + 1, Destination._toCol - Destination._fromCol + 1); for (var row = Destination._fromRow; row <= Destination._toRow; row++) { @@ -359,11 +389,12 @@ internal void Clear(ExcelAddressBase Destination) { var mergedRangeId = GetId(row, col); - if (mergedRangeId == 0) + if (mergedRangeId == 0 || used.Contains(mergedRangeId)) { continue; } + used.Add(mergedRangeId); // из метода GetId возвращается индекс в списке _list + 1, т.к. результат 0 означает, что значение в списке не найдено // поэтому, чтобы восстановить исходный индекс, передаем mergedRangeId-1 var mergedRangeAddress = new ExcelAddressBase(_list[mergedRangeId-1]); @@ -376,6 +407,7 @@ internal void Clear(ExcelAddressBase Destination) } } } + public bool DisableMergeValidation { get; set; } //internal CellStore _values; //internal CellStore _types; //internal CellStore _styles; From a7c09e562e8655df178fe37935ebbc5a5faaffc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=A1=D0=B5=D1=80=D0=B3?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2?= Date: Wed, 22 May 2019 15:45:50 +0700 Subject: [PATCH 12/14] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0?= =?UTF-8?q?=20=D0=BA=D1=8D=D1=88=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=8F=D1=87=D0=B5=D0=B5=D0=BA=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=BA=D0=BE=D0=BF=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B8=20=D0=B4=D0=B8=D0=B0=D0=BF=D0=B0=D0=B7=D0=BE?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправлена ошибка кэширования объединенных ячеек при копировании диапазонов --- EPPlus/ExcelWorksheet.cs | 10 +++++++++- EPPlus/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/EPPlus/ExcelWorksheet.cs b/EPPlus/ExcelWorksheet.cs index 3494afb2..2a6e7e3d 100644 --- a/EPPlus/ExcelWorksheet.cs +++ b/EPPlus/ExcelWorksheet.cs @@ -282,7 +282,15 @@ internal void Add(ExcelAddressBase address, bool doValidate) lock (this) { ix = _list.Count; - _mergedAreasDimsCache.Add(address.Address, new AddressDimensions(address.Start.Row, address.Start.Column, address.End.Row, address.End.Column)); + var addressDimension = new AddressDimensions(address.Start.Row, address.Start.Column, address.End.Row, address.End.Column); + if (!_mergedAreasDimsCache.ContainsKey(address.Address)) + { + _mergedAreasDimsCache.Add(address.Address, addressDimension); + } + else + { + _mergedAreasDimsCache[address.Address] = addressDimension; + } _list.Add(address.Address); SetIndex(address, ix); } diff --git a/EPPlus/Properties/AssemblyInfo.cs b/EPPlus/Properties/AssemblyInfo.cs index b111fb50..1c3c0588 100644 --- a/EPPlus/Properties/AssemblyInfo.cs +++ b/EPPlus/Properties/AssemblyInfo.cs @@ -62,7 +62,7 @@ //[assembly: AssemblyCulture("")] //[assembly: ComVisible(false)] - [assembly: AssemblyVersion("4.5.3.7")] - [assembly: AssemblyFileVersion("4.5.3.7")] + [assembly: AssemblyVersion("4.5.3.9")] + [assembly: AssemblyFileVersion("4.5.3.9")] #endif [assembly: AllowPartiallyTrustedCallers] \ No newline at end of file From d64ccbed4ca5bdc1af699f962839ce463181e36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=98=D0=BB=D1=8C=D1=8F?= =?UTF-8?q?=D1=81=D0=BE=D0=B2?= Date: Mon, 22 Jul 2019 15:22:36 +0300 Subject: [PATCH 13/14] =?UTF-8?q?[#BIWEBSVODY-8848]=20=D0=94=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=BE=D0=BF=D1=83?= =?UTF-8?q?=D1=81=D0=BA=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D1=8F=D1=87=D0=B5=D0=B5=D0=BA=20=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B5=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=BD?= =?UTF-8?q?=D1=8B=D0=BC=20=D0=B0=D0=B4=D1=80=D0=B5=D1=81=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=B4=D0=B8=D0=B0=D0=BF=D0=BE=D0=B7=D0=BE=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPPlus/ExcelWorkbook.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/EPPlus/ExcelWorkbook.cs b/EPPlus/ExcelWorkbook.cs index 0887bd35..2c71087c 100644 --- a/EPPlus/ExcelWorkbook.cs +++ b/EPPlus/ExcelWorkbook.cs @@ -175,6 +175,11 @@ internal void GetDefinedNames() { string fullAddress = elem.InnerText; + if(fullAddress == "'#REF'!#REF!" || fullAddress.EndsWith("!#REF!")) + { + continue; + } + int localSheetID; ExcelWorksheet nameWorksheet; From 0b852503d044084f979f24357de543764abed009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A2=D0=B8=D0=BC=D1=83=D1=80=20=D0=98=D0=BB=D1=8C=D1=8F?= =?UTF-8?q?=D1=81=D0=BE=D0=B2?= Date: Mon, 22 Jul 2019 15:26:42 +0300 Subject: [PATCH 14/14] =?UTF-8?q?[#BIWEBSVODY-8848]=20=D0=9E=D0=B1=D1=8A?= =?UTF-8?q?=D0=B5=D0=B4=D0=B8=D0=BD=D0=B8=D0=BB=20=D1=83=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EPPlus/ExcelWorkbook.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EPPlus/ExcelWorkbook.cs b/EPPlus/ExcelWorkbook.cs index 2c71087c..f7880b24 100644 --- a/EPPlus/ExcelWorkbook.cs +++ b/EPPlus/ExcelWorkbook.cs @@ -175,7 +175,7 @@ internal void GetDefinedNames() { string fullAddress = elem.InnerText; - if(fullAddress == "'#REF'!#REF!" || fullAddress.EndsWith("!#REF!")) + if(fullAddress.EndsWith("!#REF!")) { continue; }