From 49542872a35593d4fadeebfbc61464c63c792f9c Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Thu, 29 Dec 2022 10:21:46 +0700 Subject: [PATCH 1/4] Add TestRemoveOneOfTwoChartsAndAddNewOne --- .../ooxml/XSSF/UserModel/TestXSSFChart.cs | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs index ecd718e98..63a7a2123 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs @@ -21,6 +21,8 @@ limitations under the License. using NPOI.SS.UserModel.Charts; using NPOI.XSSF.UserModel; using NPOI.XSSF; +using NPOI.OpenXmlFormats.Dml.Spreadsheet; +using System.Linq; namespace TestCases.XSSF.UserModel { @@ -88,6 +90,55 @@ public void TestAddChartsToNewWorkbook() Assert.IsNotNull(XSSFTestDataSamples.WriteOutAndReadBack(wb)); } + [Test] + public void TestRemoveOneOfTwoChartsAndAddNewOne() + { + XSSFWorkbook workbook = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)workbook.CreateSheet(); + XSSFDrawing drawingPatriarch = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); + XSSFChart chart = (XSSFChart)drawingPatriarch.CreateChart(anchor1); + XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60); + _ = (XSSFChart)drawingPatriarch.CreateChart(anchor2); + + Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); + + RemoveChart(drawingPatriarch, chart); + + Assert.AreEqual(1, drawingPatriarch.GetCharts().Count); + + XSSFClientAnchor a3 = new XSSFClientAnchor(0, 0, 0, 0, 1, 111, 10, 90); + _ = (XSSFChart)drawingPatriarch.CreateChart(a3); + + Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); + } + + private static void RemoveChart(XSSFDrawing drawingPatriarch, XSSFChart chart) + { + CT_Drawing ctDrawing = drawingPatriarch.GetCTDrawing(); + XSSFGraphicFrame frame = chart.GetGraphicFrame(); + CT_GraphicalObjectFrame internalFrame = frame.GetCTGraphicalObjectFrame(); + int anchorIndex = ctDrawing.CellAnchors.FindIndex(anchor => anchor.graphicFrame == internalFrame); + + if (anchorIndex != -1) + { + ctDrawing.CellAnchors.RemoveAt(anchorIndex); + + foreach (var part in drawingPatriarch.GetRelations().Where(part => part is XSSFChart && part == chart)) + { + drawingPatriarch.RemoveRelation(part); + } + } + } + + private static void RemoveChartFromDrawing(XSSFDrawing xssfDrawing, XSSFChart chart) + { + foreach (var part in xssfDrawing.GetRelations().Where(part => part is XSSFChart && part == chart)) + { + xssfDrawing.RemoveRelation(part); + } + } + [Test] public void TestGetChartAxisBug57362() { From 668b919e836aa63509b24a7296718ef0786ba802 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Thu, 29 Dec 2022 10:57:50 +0700 Subject: [PATCH 2/4] Add private GetNewChartNumber to XSSFDrawing The method checks for existing chat names, and gets the firtst chart number that isnt in use yet. --- ooxml/XSSF/UserModel/XSSFDrawing.cs | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/ooxml/XSSF/UserModel/XSSFDrawing.cs b/ooxml/XSSF/UserModel/XSSFDrawing.cs index f7deaf970..0e4b22e8e 100644 --- a/ooxml/XSSF/UserModel/XSSFDrawing.cs +++ b/ooxml/XSSF/UserModel/XSSFDrawing.cs @@ -26,7 +26,8 @@ limitations under the License. using NPOI.OpenXmlFormats.Dml; using NPOI.SS.Util; using NPOI.Util; - +using System.Text.RegularExpressions; +using System.Linq; namespace NPOI.XSSF.UserModel { @@ -170,8 +171,7 @@ public IPicture CreatePicture(IClientAnchor anchor, int pictureIndex) /// the newly created chart public IChart CreateChart(IClientAnchor anchor) { - int chartNumber = GetPackagePart().Package. - GetPartsByContentType(XSSFRelation.CHART.ContentType).Count + 1; + int chartNumber = GetNewChartNumber(); RelationPart rp = CreateRelationship( XSSFRelation.CHART, XSSFFactory.GetInstance(), chartNumber, false); @@ -184,6 +184,32 @@ public IChart CreateChart(IClientAnchor anchor) return chart; } + private int GetNewChartNumber() + { + List existingCharts = GetPackagePart().Package. + GetPartsByContentType(XSSFRelation.CHART.ContentType); + HashSet numbers = new HashSet(); + + foreach (PackagePart chart in existingCharts) + { + var match = Regex.Match(chart.PartName.Name, @"\d+"); + + if (match.Success) + { + numbers.Add(int.Parse(match.Value)); + } + } + + var newChartNumber = 1; + + while (numbers.Contains(newChartNumber)) + { + newChartNumber++; + } + + return newChartNumber; + } + //public XSSFChart CreateChart(IClientAnchor anchor) //{ // return CreateChart((XSSFClientAnchor)anchor); From 8b23b0fda5ab3bf63fa83f6b75d86ad5b62c3df3 Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Thu, 29 Dec 2022 10:58:53 +0700 Subject: [PATCH 3/4] Add XSSFDrawing.RemoveChart method For ease of chart removal. --- ooxml/XSSF/UserModel/XSSFDrawing.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/ooxml/XSSF/UserModel/XSSFDrawing.cs b/ooxml/XSSF/UserModel/XSSFDrawing.cs index 0e4b22e8e..b0912c1dd 100644 --- a/ooxml/XSSF/UserModel/XSSFDrawing.cs +++ b/ooxml/XSSF/UserModel/XSSFDrawing.cs @@ -184,6 +184,28 @@ public IChart CreateChart(IClientAnchor anchor) return chart; } + /// + /// Removes chart. + /// + /// The chart to be removed. + public void RemoveChart(XSSFChart chart) + { + CT_Drawing ctDrawing = GetCTDrawing(); + XSSFGraphicFrame frame = chart.GetGraphicFrame(); + CT_GraphicalObjectFrame internalFrame = frame.GetCTGraphicalObjectFrame(); + int anchorIndex = ctDrawing.CellAnchors.FindIndex(anchor => anchor.graphicFrame == internalFrame); + + if (anchorIndex != -1) + { + ctDrawing.CellAnchors.RemoveAt(anchorIndex); + + foreach (var part in GetRelations().Where(part => part is XSSFChart && part == chart)) + { + RemoveRelation(part); + } + } + } + private int GetNewChartNumber() { List existingCharts = GetPackagePart().Package. From 312bc4fa8373738a051f34dc6b513e362ba36bea Mon Sep 17 00:00:00 2001 From: Artem Koloskov Date: Thu, 29 Dec 2022 10:59:40 +0700 Subject: [PATCH 4/4] Add TestRemoveChart test. Improve TestRemoveOneOfTwoChartsAndAddNewOne test. --- .../ooxml/XSSF/UserModel/TestXSSFChart.cs | 47 ++++++++----------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs index 63a7a2123..c54fc920b 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFChart.cs @@ -68,6 +68,7 @@ public void TestGetCharts() Assert.IsNotNull(XSSFTestDataSamples.WriteOutAndReadBack(wb)); } + [Test] public void TestAddChartsToNewWorkbook() { @@ -90,6 +91,24 @@ public void TestAddChartsToNewWorkbook() Assert.IsNotNull(XSSFTestDataSamples.WriteOutAndReadBack(wb)); } + [Test] + public void TestRemoveChart() + { + XSSFWorkbook workbook = new XSSFWorkbook(); + XSSFSheet sheet = (XSSFSheet)workbook.CreateSheet(); + XSSFDrawing drawingPatriarch = (XSSFDrawing)sheet.CreateDrawingPatriarch(); + XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30); + XSSFChart chart = (XSSFChart)drawingPatriarch.CreateChart(anchor1); + XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 1, 11, 10, 60); + _ = (XSSFChart)drawingPatriarch.CreateChart(anchor2); + + Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); + + drawingPatriarch.RemoveChart(chart); + + Assert.AreEqual(1, drawingPatriarch.GetCharts().Count); + } + [Test] public void TestRemoveOneOfTwoChartsAndAddNewOne() { @@ -103,7 +122,7 @@ public void TestRemoveOneOfTwoChartsAndAddNewOne() Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); - RemoveChart(drawingPatriarch, chart); + drawingPatriarch.RemoveChart(chart); Assert.AreEqual(1, drawingPatriarch.GetCharts().Count); @@ -113,32 +132,6 @@ public void TestRemoveOneOfTwoChartsAndAddNewOne() Assert.AreEqual(2, drawingPatriarch.GetCharts().Count); } - private static void RemoveChart(XSSFDrawing drawingPatriarch, XSSFChart chart) - { - CT_Drawing ctDrawing = drawingPatriarch.GetCTDrawing(); - XSSFGraphicFrame frame = chart.GetGraphicFrame(); - CT_GraphicalObjectFrame internalFrame = frame.GetCTGraphicalObjectFrame(); - int anchorIndex = ctDrawing.CellAnchors.FindIndex(anchor => anchor.graphicFrame == internalFrame); - - if (anchorIndex != -1) - { - ctDrawing.CellAnchors.RemoveAt(anchorIndex); - - foreach (var part in drawingPatriarch.GetRelations().Where(part => part is XSSFChart && part == chart)) - { - drawingPatriarch.RemoveRelation(part); - } - } - } - - private static void RemoveChartFromDrawing(XSSFDrawing xssfDrawing, XSSFChart chart) - { - foreach (var part in xssfDrawing.GetRelations().Where(part => part is XSSFChart && part == chart)) - { - xssfDrawing.RemoveRelation(part); - } - } - [Test] public void TestGetChartAxisBug57362() {