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
Copy drawings
  • Loading branch information
AdrianEPPlus committed May 13, 2024
commit 91900a36648467b8646662119963ff478aafe0d9
33 changes: 19 additions & 14 deletions src/EPPlus/Core/Worksheet/WorksheetCopyHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,16 +383,7 @@ private static void CopyDrawingRels(ExcelDrawing sourceDraw, ExcelPackage pck, E
}
else if (sourceDraw is ExcelControl ctrl)
{
var UriCtrl = XmlHelper.GetNewUri(pck.ZipPackage, "/xl/ctrlProps/ctrlProp{0}.xml");
var ctrlPart = pck.ZipPackage.CreatePart(UriCtrl, ContentTypes.contentTypeControlProperties, pck.Compression);
StreamWriter streamChart = new StreamWriter(ctrlPart.GetStream(FileMode.Create, FileAccess.Write));
streamChart.Write(ctrl.ControlPropertiesXml.OuterXml);
streamChart.Flush();

var prevRelID = ctrl._control.RelationshipId;
var rel = target.Part.CreateRelationship(UriHelper.GetRelativeUri(target.WorksheetUri, UriCtrl), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/ctrlProp");
XmlAttribute relAtt = target.WorksheetXml.SelectSingleNode(string.Format("//d:control/@r:id[.='{0}']", prevRelID), target.NameSpaceManager) as XmlAttribute;
relAtt.Value = rel.Id;
CopyControl(pck, target, ctrl);
}
else if (sourceDraw is ExcelShape shp)
{
Expand Down Expand Up @@ -430,6 +421,20 @@ private static void CopyDrawingRels(ExcelDrawing sourceDraw, ExcelPackage pck, E
}
}

internal static void CopyControl(ExcelPackage pck, ExcelWorksheet target, ExcelControl ctrl)
{
var UriCtrl = XmlHelper.GetNewUri(pck.ZipPackage, "/xl/ctrlProps/ctrlProp{0}.xml");
var ctrlPart = pck.ZipPackage.CreatePart(UriCtrl, ContentTypes.contentTypeControlProperties, pck.Compression);
StreamWriter streamChart = new StreamWriter(ctrlPart.GetStream(FileMode.Create, FileAccess.Write));
streamChart.Write(ctrl.ControlPropertiesXml.OuterXml);
streamChart.Flush();

var prevRelID = ctrl._control.RelationshipId;
var rel = target.Part.CreateRelationship(UriHelper.GetRelativeUri(target.WorksheetUri, UriCtrl), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/ctrlProp");
XmlAttribute relAtt = target.WorksheetXml.SelectSingleNode(string.Format("//d:control/@r:id[.='{0}']", prevRelID), target.NameSpaceManager) as XmlAttribute;
relAtt.Value = rel.Id;
}

internal static void CopyChartRelations(ExcelChart chart, ExcelWorksheet target, ZipPackagePart partDraw, XmlDocument drawXml, ExcelWorksheet source)
{
var xml = chart.ChartXml.InnerXml;
Expand Down Expand Up @@ -524,21 +529,21 @@ internal static void CopyChartRelations(ExcelWorksheet copy, ExcelWorksheet adde
}
}

private static void CopyBlipFillDrawing(ExcelWorksheet added, ZipPackagePart part, XmlDocument drawXml, ExcelDrawing draw, ExcelDrawingFill fill, Uri uriDraw)
internal static void CopyBlipFillDrawing(ExcelWorksheet target, ZipPackagePart targetPart, XmlDocument drawXml, ExcelDrawing draw, ExcelDrawingFill fill, Uri uriDraw)
{
if (fill.Style == eFillStyle.BlipFill)
{
IPictureContainer container = fill.BlipFill;
var uri = container.UriPic;
var img = fill.BlipFill.Image.ImageBytes;
var ii = added.Workbook._package.PictureStore.AddImage(img, uri, null);
var ii = target.Workbook._package.PictureStore.AddImage(img, uri, null);

var rel = part.CreateRelationship(UriHelper.GetRelativeUri(uriDraw, ii.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
var rel = targetPart.CreateRelationship(UriHelper.GetRelativeUri(uriDraw, ii.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
//Fixes problem with invalid image when the same image is used more than once.
XmlNode relAtt =
drawXml.SelectSingleNode(
string.Format(
"//xdr:cNvPr/@name[.='{0}']/../../../xdr:spPr/xdr:blipFill/a:blip/@r:embed",
"//xdr:cNvPr/@name[.='{0}']/../../../xdr:spPr/a:blipFill/a:blip/@r:embed",
draw.Name), draw.NameSpaceManager);

if (relAtt != null)
Expand Down
21 changes: 18 additions & 3 deletions src/EPPlus/Drawing/ExcelDrawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1340,14 +1340,21 @@ public void Copy(ExcelWorksheet worksheet, int row, int col, int rowOffset = 0,
switch (DrawingType)
{
case eDrawingType.Shape:
//Check blip and stuff
break;
case eDrawingType.Picture:
CopyRelations(worksheet, drawNode);
break;
case eDrawingType.Chart:
CopyChart(worksheet, drawNode, row, col, rowOffset, colOffset);
return;
case eDrawingType.Slicer:
break;
case eDrawingType.Control:
//M�ste skapa xml p� n�tt s�tt som nuvarande drawnode inte g�r...
CopyControl(worksheet);
break;
case eDrawingType.GroupShape:
break;
}
}
var copy = GetDrawing(worksheet._drawings, drawNode);
Expand All @@ -1361,18 +1368,26 @@ public void Copy(ExcelWorksheet worksheet, int row, int col, int rowOffset = 0,
switch (DrawingType)
{
case eDrawingType.Shape:
var sourceShape = this as ExcelShape;
var targetShape = copy as ExcelShape;
WorksheetCopyHelper.CopyBlipFillDrawing(worksheet, worksheet._drawings.Part, worksheet._drawings.DrawingXml, targetShape, sourceShape.Fill, worksheet._drawings.Part.Uri);
copy._id = worksheet.Workbook._nextDrawingId++;
break;
case eDrawingType.Picture:
var pic = copy as ExcelPicture;
var pic = copy as ExcelPicture;
pic.SetNewId(worksheet.Workbook._nextDrawingId++);
break;
case eDrawingType.Chart:

break;
}
}

private void CopyControl(ExcelWorksheet worksheet)
{
var control = this as ExcelControl;
WorksheetCopyHelper.CopyControl(worksheet._package, worksheet, control);
}

private void CopyChart(ExcelWorksheet worksheet, XmlNode drawNode, int row, int col, int rowOffset, int colOffset)
{
var relNode = drawNode.SelectSingleNode("xdr:graphicFrame/a:graphic/a:graphicData/c:chart/@r:id", NameSpaceManager);
Expand Down
20 changes: 20 additions & 0 deletions src/EPPlusTest/Drawing/CopyDrawingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ public void CopyShapeTest()
SaveAndCleanup(p);
}

[TestMethod]
public void CopyShapeBlipFillTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws0 = p.Workbook.Worksheets[0];
var ws1 = p.Workbook.Worksheets[1];
ws0.Drawings[1].Copy(ws1, 10, 20);
SaveAndCleanup(p);
}

[TestMethod]
public void CopyPictureTest()
{
Expand All @@ -41,6 +51,16 @@ public void CopyPictureTestExternal()
SaveAndCleanup(p2);
}

[TestMethod]
public void CopyControlTest()
{
using var p = OpenTemplatePackage("CopyDrawings.xlsx");
var ws2 = p.Workbook.Worksheets[2];
var ws1 = p.Workbook.Worksheets[1];
ws1.Drawings[1].Copy(ws2, 20, 1);
SaveAndCleanup(p);
}

[TestMethod]
public void CopyChartTestExternal()
{
Expand Down