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

Feature/copy drawings #1472

Merged
merged 18 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fixed settings new name to copied drawings and tests
  • Loading branch information
AdrianEPPlus committed May 30, 2024
commit 715899669fe9ea5424e6327311a7edf89ceb61d9
25 changes: 14 additions & 11 deletions src/EPPlus/Drawing/ExcelDrawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1420,7 +1420,7 @@ private XmlNode CopySlicer(ExcelWorksheet worksheet, bool isGroupShape = false,
//can't copy to another workbook unless we also copy the table. (Need to check for table somehow...)
if (worksheet.Workbook != _drawings.Worksheet.Workbook)
{
throw new Exception("Table slicers can't be copied from one workbook to another.");
throw new InvalidOperationException("Table slicers can't be copied from one workbook to another.");
}

//Create node in drawing.xml
Expand Down Expand Up @@ -1453,7 +1453,7 @@ private XmlNode CopySlicer(ExcelWorksheet worksheet, bool isGroupShape = false,
{
drawNodeName = drawNode.SelectSingleNode("mc:Choice/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr", worksheet._drawings.NameSpaceManager);
}
var drawNodeNameValue = drawNodeName.Attributes["name"].Value + " " + worksheet.Workbook._nextDrawingId++;
var drawNodeNameValue = worksheet._drawings.GetUniqueDrawingName(drawNodeName.Attributes["name"].Value);
drawNodeName.Attributes["name"].Value = drawNodeNameValue;
var drawNodeSlicerName = drawNode.SelectSingleNode("mc:AlternateContent/mc:Choice/xdr:graphicFrame/a:graphic/a:graphicData/sle:slicer", worksheet._drawings.NameSpaceManager);
if (drawNodeSlicerName == null && isGroupShape)
Expand Down Expand Up @@ -1562,14 +1562,14 @@ private XmlNode CopyControl(ExcelWorksheet worksheet, int row, int col, int rowO
if (!isGroupShape)
{
//Create the copy
var copy = GetDrawing(worksheet._drawings, drawNode); //Finds the wrong drawing...
var copy = GetDrawing(worksheet._drawings, drawNode);
copy.EditAs = ExcelControl.GetControlEditAs(control.ControlType);
var width = GetPixelWidth();
var height = GetPixelHeight();
copy.SetPixelWidth(width);
copy.SetPixelHeight(height);
copy.SetPosition(row, rowOffset, col, colOffset);
worksheet._drawings.AddDrawingInternal(copy);
//var width = GetPixelWidth();
//var height = GetPixelHeight();
//copy.SetPixelWidth(width);
//copy.SetPixelHeight(height);
//copy.SetPosition(row, rowOffset, col, colOffset);
//worksheet._drawings.AddDrawingInternal(copy);

//Update position in worksheet xml
var fromCol = controlNode.SelectSingleNode("d:control/d:controlPr/d:anchor/d:from/xdr:col", worksheet.NameSpaceManager);
Expand Down Expand Up @@ -1624,13 +1624,13 @@ private XmlNode CopyChart(ExcelWorksheet worksheet, bool isGroupShape = false, X
if(isGroupShape)
{
var chartAttr = groupDrawNode.SelectSingleNode("xdr:nvGraphicFramePr/xdr:cNvPr", worksheet._drawings.NameSpaceManager);
chartAttr.Attributes["name"].Value = origialChart.Name + " " + worksheet._drawings._drawingNames.Count;
chartAttr.Attributes["name"].Value = worksheet._drawings.GetUniqueDrawingName(origialChart.Name);
chartAttr.Attributes["id"].Value = (++origialChart._id).ToString();
}
else
{
var chartcopy = ExcelChart.GetChart(worksheet._drawings, drawNode);
chartcopy.Name = chartcopy.Name + " " + worksheet._drawings._drawingNames.Count;
chartcopy.Name = worksheet._drawings.GetUniqueDrawingName(origialChart.Name);
chartcopy._id = ++origialChart._id;
}

Expand Down Expand Up @@ -1704,6 +1704,7 @@ private XmlNode CopyPicture(ExcelWorksheet worksheet, bool isGroupShape = false,
//Set New id on copied picture.
var pic = GetDrawing(worksheet._drawings, drawNode) as ExcelPicture;
pic.SetNewId(++worksheet.Workbook._nextDrawingId);
pic.Name = worksheet._drawings.GetUniqueDrawingName(this.Name);
}
return drawNode;
}
Expand All @@ -1716,6 +1717,7 @@ private XmlNode CopyShape(ExcelWorksheet worksheet, bool isGroupShape = false, X
{
drawNode = groupDrawNode;
groupDrawNode.SelectSingleNode("xdr:nvSpPr/xdr:cNvPr", worksheet._drawings.NameSpaceManager).Attributes["id"].Value = (++worksheet.Workbook._nextDrawingId).ToString();
groupDrawNode.SelectSingleNode("xdr:nvSpPr/xdr:cNvPr", worksheet._drawings.NameSpaceManager).Attributes["name"].Value = worksheet._drawings.GetUniqueDrawingName(sourceShape.Name);
}
else
{
Expand All @@ -1725,6 +1727,7 @@ private XmlNode CopyShape(ExcelWorksheet worksheet, bool isGroupShape = false, X
//Asign new id
var targetShape = GetDrawing(worksheet._drawings, drawNode) as ExcelShape;
targetShape._id = ++worksheet.Workbook._nextDrawingId;
targetShape.Name = worksheet._drawings.GetUniqueDrawingName(sourceShape.Name);
}
//Copy Blip Fill
WorksheetCopyHelper.CopyBlipFillDrawing(worksheet, worksheet._drawings.Part, worksheet._drawings.DrawingXml, this, sourceShape.Fill, worksheet._drawings.Part.Uri);
Expand Down
19 changes: 19 additions & 0 deletions src/EPPlus/Drawing/ExcelDrawings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,25 @@ internal void AddDrawingInternal(ExcelDrawing dr)
}
}

internal string GetUniqueDrawingName(string name)
{
var newName = name;
var index = 1;
while (_drawingNames.ContainsKey(newName))
{
var split = newName.Split(' ');
if( int.TryParse(split[split.Length - 1], out int number))
{
split[split.Length - 1] = (++number).ToString();
newName = string.Join(" ", split);
}
else
{
newName = name + index++;
}
}
return newName;
}

#region NamespaceManager
/// <summary>
Expand Down
138 changes: 93 additions & 45 deletions src/EPPlusTest/Drawing/CopyDrawingTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Information;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -9,13 +10,19 @@ namespace EPPlusTest.Drawing
[TestClass]
public class CopyDrawingTests : TestBase
{
//Sheet 1: 4, 0-3
//Sheet 2: 9, 0-8
//Sheet 4: 7, 0-6

//Copy Shape Tests
[TestMethod]
public void CopyShapeSameWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[0];
Assert.IsTrue(ws0.Drawings.Count < 5);
ws0.Drawings[0].Copy(ws0, 25, 1);
Assert.AreEqual(5, ws0._drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
Expand All @@ -24,7 +31,9 @@ public void CopyShapeOtherWorksheetTest()
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[0];
var ws1 = p.Workbook.Worksheets[1];
Assert.IsTrue(ws1.Drawings.Count < 10);
ws0.Drawings[0].Copy(ws1, 10, 10);
Assert.AreEqual(10, ws1.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
Expand All @@ -33,8 +42,9 @@ public void CopyShapeOtherWorkbookTest()
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[0];
using var p2 = OpenPackage("Target.xlsx", true);
var ws1 = p2.Workbook.Worksheets.Add("Sheet1");
ws0.Drawings[0].Copy(ws1, 10, 10);
var ws = p2.Workbook.Worksheets.Add("Sheet1");
ws0.Drawings[0].Copy(ws, 10, 10);
Assert.AreEqual(1, ws.Drawings.Count);
SaveAndCleanup(p2);
}
[TestMethod]
Expand All @@ -43,7 +53,9 @@ public void CopyShapeBlipFillTest()
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[0];
var ws1 = p.Workbook.Worksheets[1];
Assert.IsTrue(ws1.Drawings.Count < 10);
ws0.Drawings[1].Copy(ws1, 10, 20);
Assert.AreEqual(10, ws1.Drawings.Count);
SaveAndCleanup(p);
}

Expand All @@ -53,7 +65,9 @@ public void CopyPictureSameWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws1 = p.Workbook.Worksheets[1];
Assert.IsTrue(ws1.Drawings.Count < 10);
ws1.Drawings[0].Copy(ws1, 0, 15);
Assert.AreEqual(10, ws1.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
Expand All @@ -62,17 +76,20 @@ public void CopyPictureOtherWorksheetTest()
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[0];
var ws1 = p.Workbook.Worksheets[1];
Assert.IsTrue(ws0.Drawings.Count < 5);
ws1.Drawings[0].Copy(ws0, 20, 1);
Assert.AreEqual(5, ws0.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopyPictureOtherWorkbookTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[1];
var ws1 = p.Workbook.Worksheets[1];
using var p2 = OpenPackage("Target.xlsx", true);
var ws1 = p2.Workbook.Worksheets.Add("Sheet1");
ws0.Drawings[0].Copy(ws1, 1, 1);
var ws0 = p2.Workbook.Worksheets.Add("Sheet1");
ws1.Drawings[0].Copy(ws0, 1, 1);
Assert.AreEqual(1, ws0.Drawings.Count);
SaveAndCleanup(p2);
}

Expand All @@ -82,7 +99,9 @@ public void CopyControlSameWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws1 = p.Workbook.Worksheets[1];
Assert.IsTrue(ws1.Drawings.Count < 10);
ws1.Drawings[1].Copy(ws1, 25, 20);
Assert.AreEqual(10, ws1.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
Expand All @@ -91,9 +110,12 @@ public void CopyControlOtherWorksheetTest()
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws2 = p.Workbook.Worksheets[2];
var ws1 = p.Workbook.Worksheets[1];
Assert.IsTrue(ws2.Drawings.Count < 8);
ws1.Drawings[1].Copy(ws2, 20, 1);
Assert.AreEqual(8, ws2.Drawings.Count);
ws1.Drawings[2].Copy(ws2, 40, 1);
ws1.Drawings[1].Copy(ws2, 50, 1);
Assert.AreEqual(10, ws2.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
Expand All @@ -102,10 +124,11 @@ public void CopyControlOtherWorkbookTest()
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws1 = p.Workbook.Worksheets[1];
using var p2 = OpenPackage("Target.xlsx", true);
var ws2 = p2.Workbook.Worksheets.Add("Sheet1");
ws1.Drawings[1].Copy(ws2, 20, 1);
ws1.Drawings[2].Copy(ws2, 40, 1);
ws1.Drawings[1].Copy(ws2, 50, 1);
var ws = p2.Workbook.Worksheets.Add("Sheet1");
ws1.Drawings[1].Copy(ws, 20, 1);
ws1.Drawings[2].Copy(ws, 40, 1);
ws1.Drawings[1].Copy(ws, 50, 1);
Assert.AreEqual(3, ws.Drawings.Count);
SaveAndCleanup(p2);
}

Expand All @@ -114,56 +137,65 @@ public void CopyControlOtherWorkbookTest()
public void CopySlicerSameWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws1 = p.Workbook.Worksheets[0];
ws1.Drawings[2].Copy(ws1, 1, 25, 0, 0);
var ws0 = p.Workbook.Worksheets[0];
Assert.IsTrue(ws0.Drawings.Count < 5);
ws0.Drawings[2].Copy(ws0, 1, 25, 0, 0);
Assert.AreEqual(5, ws0.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopySlicerOtherWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws1 = p.Workbook.Worksheets[0];
var ws3 = p.Workbook.Worksheets[2];
ws1.Drawings[2].Copy(ws3, 1, 15, 0, 0);
var ws0 = p.Workbook.Worksheets[0];
var ws2 = p.Workbook.Worksheets[2];
Assert.IsTrue(ws2.Drawings.Count < 8);
ws0.Drawings[2].Copy(ws2, 1, 15, 0, 0);
Assert.AreEqual(8, ws2.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopySlicerOtherWorkbookTest() //Fungerar! Ska slänga ett exception.
public void CopySlicerOtherWorkbookTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws1 = p.Workbook.Worksheets[0];
var ws0 = p.Workbook.Worksheets[0];
using var p2 = OpenPackage("Target.xlsx", true);
var ws2 = p2.Workbook.Worksheets.Add("Sheet1");
ws1.Drawings[2].Copy(ws2, 1, 15, 0, 0);
SaveAndCleanup(p2);
var ws = p2.Workbook.Worksheets.Add("Sheet1");
var ex = Assert.ThrowsException<InvalidOperationException>(() => ws0.Drawings[2].Copy(ws, 1, 15, 0, 0));
Assert.AreEqual("Table slicers can't be copied from one workbook to another.", ex.Message);
}

//Copy Chart Tests
[TestMethod]
public void CopyChartSameWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var sourceWs = p.Workbook.Worksheets[2];
sourceWs.Drawings[0].Copy(sourceWs, 20, 1);
var ws2 = p.Workbook.Worksheets[2];
Assert.IsTrue(ws2.Drawings.Count < 8);
ws2.Drawings[0].Copy(ws2, 20, 1);
Assert.AreEqual(8, ws2.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopyChartOtherWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var sourceWs = p.Workbook.Worksheets[2];
var ws2 = p.Workbook.Worksheets[2];
var ws1 = p.Workbook.Worksheets[1];
sourceWs.Drawings[0].Copy(ws1, 20, 20);
Assert.IsTrue(ws1.Drawings.Count < 10);
ws2.Drawings[0].Copy(ws1, 20, 20);
Assert.AreEqual(10, ws1.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopyChartOtherWorkbookTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var sourceWs = p.Workbook.Worksheets[2];
var ws2 = p.Workbook.Worksheets[2];
using var p2 = OpenPackage("Target.xlsx", true);
var targetWs = p2.Workbook.Worksheets.Add("Sheet1");
sourceWs.Drawings[0].Copy(targetWs, 20, 1);
var ws = p2.Workbook.Worksheets.Add("Sheet1");
ws2.Drawings[0].Copy(ws, 20, 1);
Assert.AreEqual(1, ws.Drawings.Count);
SaveAndCleanup(p2);
}

Expand All @@ -172,40 +204,56 @@ public void CopyChartOtherWorkbookTest()
public void CopyGroupShapeSameWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws = p.Workbook.Worksheets[2];
ws.Drawings[1].Copy(ws, 5, 20);
ws.Drawings[2].Copy(ws, 5, 25);
ws.Drawings[4].Copy(ws, 5, 30);
ws.Drawings[5].Copy(ws, 5, 35);
ws.Drawings[6].Copy(ws, 5, 40);
var ws2 = p.Workbook.Worksheets[2];
Assert.IsTrue(ws2.Drawings.Count < 8);
ws2.Drawings[1].Copy(ws2, 5, 20);
Assert.AreEqual(8, ws2.Drawings.Count);
ws2.Drawings[2].Copy(ws2, 5, 25);
ws2.Drawings[4].Copy(ws2, 5, 30);
ws2.Drawings[5].Copy(ws2, 5, 35);
ws2.Drawings[6].Copy(ws2, 5, 40);
Assert.AreEqual(12, ws2.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopyGroupShapeOtherWorksheetTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws = p.Workbook.Worksheets[2];
var ws2 = p.Workbook.Worksheets[2];
var ws1 = p.Workbook.Worksheets[1];
ws.Drawings[1].Copy(ws1, 5, 20);
ws.Drawings[2].Copy(ws1, 5, 25);
ws.Drawings[4].Copy(ws1, 5, 30);
ws.Drawings[5].Copy(ws1, 5, 35);
ws.Drawings[6].Copy(ws1, 5, 40);
Assert.IsTrue(ws1.Drawings.Count < 10);
ws2.Drawings[1].Copy(ws1, 5, 20);
Assert.AreEqual(10, ws1.Drawings.Count);
ws2.Drawings[2].Copy(ws1, 5, 25);
ws2.Drawings[4].Copy(ws1, 5, 30);
ws2.Drawings[5].Copy(ws1, 5, 35);
ws2.Drawings[6].Copy(ws1, 5, 40);
Assert.AreEqual(14, ws1.Drawings.Count);
SaveAndCleanup(p);
}
[TestMethod]
public void CopyGroupShapeOtherWorkbookTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws = p.Workbook.Worksheets[2];
var ws2 = p.Workbook.Worksheets[2];
using var p2 = OpenPackage("Target.xlsx", true);
var targetWs = p2.Workbook.Worksheets.Add("Sheet1");
ws.Drawings[1].Copy(targetWs, 1, 1);
ws.Drawings[2].Copy(targetWs, 1, 5);
ws.Drawings[4].Copy(targetWs, 5, 10);
ws.Drawings[5].Copy(targetWs, 5, 15);
ws.Drawings[6].Copy(targetWs, 5, 20);
var ws = p2.Workbook.Worksheets.Add("Sheet1");
ws2.Drawings[1].Copy(ws, 1, 1);
ws2.Drawings[2].Copy(ws, 1, 5);
ws2.Drawings[4].Copy(ws, 5, 10);
ws2.Drawings[5].Copy(ws, 5, 15);
Assert.AreEqual(4, ws.Drawings.Count);
SaveAndCleanup(p2);
}
[TestMethod]
public void CopySlicerInGroupShapeOtherWorkbookTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws2 = p.Workbook.Worksheets[2];
using var p2 = OpenPackage("Target.xlsx", true);
var ws = p2.Workbook.Worksheets.Add("Sheet1");
var ex = Assert.ThrowsException<InvalidOperationException>(() => ws2.Drawings[6].Copy(ws, 5, 40));
Assert.AreEqual("Table slicers can't be copied from one workbook to another.", ex.Message);
}
}
}