I need to paste content of one docx file into another docx file.
Here's my document merger class:
public class DocumentMerger
{
private readonly WordprocessingDocument _targetDocument;
public DocumentMerger(WordprocessingDocument targetDocument)
{
_targetDocument = targetDocument;
}
public void Merge(WordprocessingDocument mergingDocument)
{
var toPlace = _targetDocument.MainDocumentPart.Document.Body.FirstChild;
foreach (var element in mergingDocument.MainDocumentPart.Document.Body.Elements())
{
CopyRelativeElements(element, _targetDocument.MainDocumentPart, mergingDocument.MainDocumentPart);
toPlace.InsertAfterSelf(element.CloneNode(true));
}
}
private void CopyRelativeElements(OpenXmlElement element, MainDocumentPart docPartTo, MainDocumentPart docPartFrom)
{
//images
element.Descendants<DocumentFormat.OpenXml.Drawing.Blip>().ToList()
.ForEach(blip =>
{
var newRelation = CopyImagePart(docPartTo, blip.Embed, docPartFrom);
blip.Embed = newRelation;
});
}
private string CopyImagePart(MainDocumentPart docPartTo, string relId, MainDocumentPart docPartFrom)
{
var p = docPartFrom.GetPartById(relId) as ImagePart;
var newPart = docPartTo.AddPart(p);
newPart.FeedData(p.GetStream(FileMode.Open, FileAccess.Read));
return docPartTo.GetIdOfPart(newPart);
}
}
There's a program, that uses this class:
class Program
{
static void Main(string[] args)
{
var firstDoc = WordprocessingDocument.Open("File1.docx", true);
var secondDoc = WordprocessingDocument.Open("File2.docx", false);
var merger = new DocumentMerger(firstDoc);
merger.Merge(secondDoc);
firstDoc.Close();
secondDoc.Close();
}
}
If mergingDocument
doesn't contain images, everything works fine. But I cannot correctly perform it with images. While opening the result file, MS Office alerts that file is correpted. MS Office repairs result and everything looks how it should be.
But I can't understand what exactly repairs MS Office. Manually looking in unzipped result file I see only renaming Id of relationship.
For example, before repairing in /word/document.xml there is such <w:drawing>
element:
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0" wp14:anchorId="34AA245D" wp14:editId="2ED47BBF">
<wp:extent cx="189865" cy="189865"/>
<wp:effectExtent l="0" t="0" r="635" b="635"/>
<wp:docPr id="1" name="Picture 1"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture 1"/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="Rfa237844834a44c5">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="189865" cy="189865"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
File /word/_rels/document.xml.rels contains such a relationship:
<Relationship Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="/word/media/image12.png" Id="Rfa237844834a44c5" />
After repairing <w:drawing>
changes only r:embed
value:
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0" wp14:anchorId="34AA245D" wp14:editId="2ED47BBF">
<wp:extent cx="189865" cy="189865"/>
<wp:effectExtent l="0" t="0" r="635" b="635"/>
<wp:docPr id="1" name="Picture 1"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture 1"/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId7">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="189865" cy="189865"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
In the file /word/_rels/document.xml.rels relationship changes Id. Target is correct (MS Office renames image file):
<Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image2.png"/>
If I manually remove in word/document.xml <w:drawing>
element in unzipped docx file, MS Office opens result file without alerts.
I saw these questions 1, 2 but it didn't helped me. Maybe I missed something. Please, can you help me?