Open-XML-SDK icon indicating copy to clipboard operation
Open-XML-SDK copied to clipboard

Copy pictures from one generated Word document to another one

Open sdudnic opened this issue 4 years ago • 0 comments

Before submitting an issue, please fill this out

Is this a:

  • [ ] Issue with the OpenXml library
  • [x] Question on library usage

I ask here, because I had any answer on StackOverflow for several weeks.

---------------- Remove this line and above before posting ----------------

Description

I generate an SSRS report that I save as a Word document. That document contain pictures (charts as plat images). I don't really save the Word document, I have it open in memory.

I use then OpenXML to create another word document, in witch I need to copy the pictures from the SSRS report.

I try to get the drawings from the ssrs report, and insert them in the new word document.

I tried to insert pictures from the disk to the generated document, that works well. What does not work, is copying one picture from one document to another. I don't need to copy all the content of a document to another. I need to copy just a picture.

Information

  • .NET Target: .NET 5
  • DocumentFormat.OpenXml Version: 2.12.3

Repro

MainDocumentPart ssrsMainPart = ssrsDoc.MainDocumentPart;
var drawings = ssrsMainPart.Document.Descendants<Drawing>().ToList();

and then insert it in the new document

MainDocumentPart mainPart = wordDoc.MainDocumentPart;
Body body = mainPart.Document.Body;
for (int i = 0; i < 10; i++)
{
    if (i < drawings.Count())
    {
        var myDrawing = drawings.Skip(i).First();
        myDrawing.Remove();
        body.Append(myDrawing); 
        body.Append(new Paragraph());
    }
}

As result I get in the resulting document only the picture placeholders, of the same size as in ssrs Word Document, but the pictures are empty.

I tried to copy the ImageData as well, using the following code:

foreach (var e in ssrsDoc.MainDocumentPart.Document.Body.Elements())
{
	var clonedElement = e.CloneNode(true);
	clonedElement.Descendants<DocumentFormat.OpenXml.Drawing.Blip>().ToList().ForEach(blip =>
	{
		var newRelation = wordDoc.CopyImage(blip.Embed, ssrsDoc);
		blip.Embed = newRelation;
	});
	clonedElement.Descendants<DocumentFormat.OpenXml.Vml.ImageData>().ToList().ForEach(imageData =>
	{
		var newRelation = wordDoc.CopyImage(imageData.RelationshipId, ssrsDoc);
		imageData.RelationshipId = newRelation;
	});
	wordDoc.MainDocumentPart.Document.Body.AppendChild(clonedElement);
}

with CopyImage defined like this:

public static string CopyImage(this WordprocessingDocument newDoc, string relId, WordprocessingDocument org)
{
	var p = org.MainDocumentPart.GetPartById(relId) as ImagePart;
	var newPart = newDoc.MainDocumentPart.AddPart(p);
	newPart.FeedData(p.GetStream());
	return newDoc.MainDocumentPart.GetIdOfPart(newPart);
}

but after that I wasn't able to open anymore the document with Word 365, word reporting the doc as a broken one...

sdudnic avatar Apr 12 '21 08:04 sdudnic