//public Picture InsertPicture(Picture picture) //{ // Picture newPicture = picture; // newPicture.i = new XElement(picture.i); // xml.Add(newPicture.i); // pictures.Add(newPicture); // return newPicture; //} // <summary> // Insert a Picture at the end of this paragraph. // </summary> // <param name="description">A string to describe this Picture.</param> // <param name="imageID">The unique id that identifies the Image this Picture represents.</param> // <param name="name">The name of this image.</param> // <returns>A Picture.</returns> // <example> // <code> // // Create a document using a relative filename. // using (DocX document = DocX.Create(@"Test.docx")) // { // // Add a new Paragraph to this document. // Paragraph p = document.InsertParagraph("Here is Picture 1", false); // // // Add an Image to this document. // Novacode.Image img = document.AddImage(@"Image.jpg"); // // // Insert pic at the end of Paragraph p. // Picture pic = p.InsertPicture(img.Id, "Photo 31415", "A pie I baked."); // // // Rotate the Picture clockwise by 30 degrees. // pic.Rotation = 30; // // // Resize the Picture. // pic.Width = 400; // pic.Height = 300; // // // Set the shape of this Picture to be a cube. // pic.SetPictureShape(BasicShapes.cube); // // // Flip the Picture Horizontally. // pic.FlipHorizontal = true; // // // Save all changes made to this document. // document.Save(); // }// Release this document from memory. // </code> // </example> // Removed to simplify the API. //public Picture InsertPicture(string imageID, string name, string description) //{ // Picture p = CreatePicture(Document, imageID, name, description); // Xml.Add(p.Xml); // return p; //} // Removed because it confusses the API. //public Picture InsertPicture(string imageID) //{ // return InsertPicture(imageID, string.Empty, string.Empty); //} //public Picture InsertPicture(int index, Picture picture) //{ // Picture p = picture; // p.i = new XElement(picture.i); // Run run = GetFirstRunEffectedByEdit(index); // if (run == null) // xml.Add(p.i); // else // { // // Split this run at the point you want to insert // XElement[] splitRun = Run.SplitRun(run, index); // // Replace the origional run // run.Xml.ReplaceWith // ( // splitRun[0], // p.i, // splitRun[1] // ); // } // // Rebuild the run lookup for this paragraph // runLookup.Clear(); // BuildRunLookup(xml); // DocX.RenumberIDs(document); // return p; //} // <summary> // Insert a Picture into this Paragraph at a specified index. // </summary> // <param name="description">A string to describe this Picture.</param> // <param name="imageID">The unique id that identifies the Image this Picture represents.</param> // <param name="name">The name of this image.</param> // <param name="index">The index to insert this Picture at.</param> // <returns>A Picture.</returns> // <example> // <code> // // Create a document using a relative filename. // using (DocX document = DocX.Create(@"Test.docx")) // { // // Add a new Paragraph to this document. // Paragraph p = document.InsertParagraph("Here is Picture 1", false); // // // Add an Image to this document. // Novacode.Image img = document.AddImage(@"Image.jpg"); // // // Insert pic at the start of Paragraph p. // Picture pic = p.InsertPicture(0, img.Id, "Photo 31415", "A pie I baked."); // // // Rotate the Picture clockwise by 30 degrees. // pic.Rotation = 30; // // // Resize the Picture. // pic.Width = 400; // pic.Height = 300; // // // Set the shape of this Picture to be a cube. // pic.SetPictureShape(BasicShapes.cube); // // // Flip the Picture Horizontally. // pic.FlipHorizontal = true; // // // Save all changes made to this document. // document.Save(); // }// Release this document from memory. // </code> // </example> // Removed to simplify API. //public Picture InsertPicture(int index, string imageID, string name, string description) //{ // Picture picture = CreatePicture(Document, imageID, name, description); // Run run = GetFirstRunEffectedByEdit(index); // if (run == null) // Xml.Add(picture.Xml); // else // { // // Split this run at the point you want to insert // XElement[] splitRun = Run.SplitRun(run, index); // // Replace the origional run // run.Xml.ReplaceWith // ( // splitRun[0], // picture.Xml, // splitRun[1] // ); // } // HelperFunctions.RenumberIDs(Document); // return picture; //} /// <summary> /// Create a new Picture. /// </summary> /// <param name="document"></param> /// <param name="id">A unique id that identifies an Image embedded in this document.</param> /// <param name="name">The name of this Picture.</param> /// <param name="descr">The description of this Picture.</param> internal static Picture CreatePicture(DocX document, string id, string name, string descr) { PackagePart part = document.package.GetPart(document.mainPart.GetRelationship(id).TargetUri); int newDocPrId = 1; List<string> existingIds = new List<string>(); foreach (var bookmarkId in document.Xml.Descendants(XName.Get("bookmarkStart", DocX.w.NamespaceName))) { var idAtt = bookmarkId.Attributes().FirstOrDefault(x => x.Name.LocalName == "id"); if (idAtt != null) existingIds.Add(idAtt.Value); } while (existingIds.Contains(newDocPrId.ToString())) newDocPrId++; int cx, cy; using (System.Drawing.Image img = System.Drawing.Image.FromStream(part.GetStream())) { cx = img.Width * 9526; cy = img.Height * 9526; } XElement e = new XElement(DocX.w + "drawing"); XElement xml = XElement.Parse (string.Format(@"<w:r xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main""> <w:drawing xmlns = ""http://schemas.openxmlformats.org/wordprocessingml/2006/main""> <wp:inline distT=""0"" distB=""0"" distL=""0"" distR=""0"" xmlns:wp=""http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing""> <wp:extent cx=""{0}"" cy=""{1}"" /> <wp:effectExtent l=""0"" t=""0"" r=""0"" b=""0"" /> <wp:docPr id=""{5}"" name=""{3}"" descr=""{4}"" /> <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=""{3}"" /> <pic:cNvPicPr /> </pic:nvPicPr> <pic:blipFill> <a:blip r:embed=""{2}"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships""/> <a:stretch> <a:fillRect /> </a:stretch> </pic:blipFill> <pic:spPr> <a:xfrm> <a:off x=""0"" y=""0"" /> <a:ext cx=""{0}"" cy=""{1}"" /> </a:xfrm> <a:prstGeom prst=""rect""> <a:avLst /> </a:prstGeom> </pic:spPr> </pic:pic> </a:graphicData> </a:graphic> </wp:inline> </w:drawing></w:r> ", cx, cy, id, name, descr, newDocPrId.ToString())); return new Picture(document, xml, new Image(document, document.mainPart.GetRelationship(id))); }
/// <summary> /// Insert the contents of another document at the end of this document. /// </summary> /// <param name="remote_document">The document to insert at the end of this document.</param> /// <example> /// Create a new document and insert an old document into it. /// <code> /// // Create a new document. /// using (DocX newDocument = DocX.Create(@"NewDocument.docx")) /// { /// // Load an old document. /// using (DocX oldDocument = DocX.Load(@"OldDocument.docx")) /// { /// // Insert the old document into the new document. /// newDocument.InsertDocument(oldDocument); /// /// // Save the new document. /// newDocument.Save(); /// }// Release the old document from memory. /// }// Release the new document from memory. /// </code> /// <remarks> /// If the document being inserted contains Images, CustomProperties and or custom styles, these will be correctly inserted into the new document. In the case of Images, new ID's are generated for the Images being inserted to avoid ID conflicts. CustomProperties with the same name will be ignored not replaced. /// </remarks> /// </example> public void InsertDocument(DocX remote_document) { // We don't want to effect the origional XDocument, so create a new one from the old one. XDocument remote_mainDoc = new XDocument(remote_document.mainDoc); XDocument remote_footnotes = null; if (remote_document.footnotes != null) remote_footnotes = new XDocument(remote_document.footnotes); XDocument remote_endnotes = null; if (remote_document.endnotes != null) remote_endnotes = new XDocument(remote_document.endnotes); // Remove all header and footer references. remote_mainDoc.Descendants(XName.Get("headerReference", DocX.w.NamespaceName)).Remove(); remote_mainDoc.Descendants(XName.Get("footerReference", DocX.w.NamespaceName)).Remove(); // Get the body of the remote document. XElement remote_body = remote_mainDoc.Root.Element(XName.Get("body", DocX.w.NamespaceName)); // Every file that is missing from the local document will have to be copied, every file that already exists will have to be merged. PackagePartCollection ppc = remote_document.package.GetParts(); List<String> ignoreContentTypes = new List<string> { "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", "application/vnd.openxmlformats-package.core-properties+xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml", "application/vnd.openxmlformats-package.relationships+xml", }; List<String> imageContentTypes = new List<string> { "image/jpeg", "image/jpg", "image/png", "image/bmp", "image/gif", "image/tiff", "image/icon", "image/pcx", "image/emf", "image/wmf" }; // Check if each PackagePart pp exists in this document. foreach (PackagePart remote_pp in ppc) { if (ignoreContentTypes.Contains(remote_pp.ContentType) || imageContentTypes.Contains(remote_pp.ContentType)) continue; // If this external PackagePart already exits then we must merge them. if (package.PartExists(remote_pp.Uri)) { PackagePart local_pp = package.GetPart(remote_pp.Uri); switch (remote_pp.ContentType) { case "application/vnd.openxmlformats-officedocument.custom-properties+xml": merge_customs(remote_pp, local_pp, remote_mainDoc); break; // Merge footnotes (and endnotes) before merging styles, then set the remote_footnotes to the just updated footnotes case "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": merge_footnotes(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes); remote_footnotes = footnotes; break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": merge_endnotes(remote_pp, local_pp, remote_mainDoc, remote_document, remote_endnotes); remote_endnotes = endnotes; break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": merge_styles(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes, remote_endnotes); break; // Merge styles after merging the footnotes, so the changes will be applied to the correct document/footnotes case "application/vnd.ms-word.stylesWithEffects+xml": merge_styles(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes, remote_endnotes); break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml": merge_fonts(remote_pp, local_pp, remote_mainDoc, remote_document); break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": merge_numbering(remote_pp, local_pp, remote_mainDoc, remote_document); break; default: break; } } // If this external PackagePart does not exits in the internal document then we can simply copy it. else { var packagePart = clonePackagePart(remote_pp); switch (remote_pp.ContentType) { case "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": endnotesPart = packagePart; endnotes = remote_endnotes; break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": footnotesPart = packagePart; footnotes = remote_footnotes; break; case "application/vnd.openxmlformats-officedocument.custom-properties+xml": break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": stylesPart = packagePart; using (TextReader tr = new StreamReader(stylesPart.GetStream())) styles = XDocument.Load(tr); break; case "application/vnd.ms-word.stylesWithEffects+xml": stylesWithEffectsPart = packagePart; using (TextReader tr = new StreamReader(stylesWithEffectsPart.GetStream())) stylesWithEffects = XDocument.Load(tr); break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml": fontTablePart = packagePart; using (TextReader tr = new StreamReader(fontTablePart.GetStream())) fontTable = XDocument.Load(tr); break; case "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": numberingPart = packagePart; using (TextReader tr = new StreamReader(numberingPart.GetStream())) numbering = XDocument.Load(tr); break; } clonePackageRelationship(remote_document, remote_pp, remote_mainDoc); } } foreach (var hyperlink_rel in remote_document.mainPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")) { var old_rel_Id = hyperlink_rel.Id; var new_rel_Id = mainPart.CreateRelationship(hyperlink_rel.TargetUri, hyperlink_rel.TargetMode, hyperlink_rel.RelationshipType).Id; var hyperlink_refs = remote_mainDoc.Descendants(XName.Get("hyperlink", DocX.w.NamespaceName)); foreach (var hyperlink_ref in hyperlink_refs) { XAttribute a0 = hyperlink_ref.Attribute(XName.Get("id", DocX.r.NamespaceName)); if (a0 != null && a0.Value == old_rel_Id) { a0.SetValue(new_rel_Id); } } } ////ole object links foreach (var oleObject_rel in remote_document.mainPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject")) { var old_rel_Id = oleObject_rel.Id; var new_rel_Id = mainPart.CreateRelationship(oleObject_rel.TargetUri, oleObject_rel.TargetMode, oleObject_rel.RelationshipType).Id; var oleObject_refs = remote_mainDoc.Descendants(XName.Get("OLEObject", "urn:schemas-microsoft-com:office:office")); foreach (var oleObject_ref in oleObject_refs) { XAttribute a0 = oleObject_ref.Attribute(XName.Get("id", DocX.r.NamespaceName)); if (a0 != null && a0.Value == old_rel_Id) { a0.SetValue(new_rel_Id); } } } foreach (PackagePart remote_pp in ppc) { if (imageContentTypes.Contains(remote_pp.ContentType)) { merge_images(remote_pp, remote_document, remote_mainDoc, remote_pp.ContentType); } } int id = 0; var local_docPrs = mainDoc.Root.Descendants(XName.Get("docPr", DocX.wp.NamespaceName)); foreach (var local_docPr in local_docPrs) { XAttribute a_id = local_docPr.Attribute(XName.Get("id")); int a_id_value; if (a_id != null && int.TryParse(a_id.Value, out a_id_value)) if (a_id_value > id) id = a_id_value; } id++; // docPr must be sequential var docPrs = remote_body.Descendants(XName.Get("docPr", DocX.wp.NamespaceName)); foreach (var docPr in docPrs) { docPr.SetAttributeValue(XName.Get("id"), id); id++; } // Add the remote documents contents to this document. XElement local_body = mainDoc.Root.Element(XName.Get("body", DocX.w.NamespaceName)); local_body.Add(remote_body.Elements()); // Copy any missing root attributes to the local document. foreach (XAttribute a in remote_mainDoc.Root.Attributes()) { if (mainDoc.Root.Attribute(a.Name) == null) { mainDoc.Root.SetAttributeValue(a.Name, a.Value); } } }