This project has moved and is read-only. For the latest updates, please go here.

insert one document to another

May 27, 2014 at 9:59 AM
Edited May 27, 2014 at 10:00 AM
I have 2 documents. I need copy data from one document and paste it to another into a special place. How can i do it?
If i use
document2.InsertDocument(document1) 
  • everything works well. but all data from document2 are in the end of document1.
If i use something this:
foreach (Paragraph p in document1.Paragraphs)
{
        paragraph.InsertParagraphBeforeSelf(p);
}
  • paragraphs paste into right place, but all tables from document1 become paragraphs.
    Help me, please!
May 27, 2014 at 1:56 PM
I think something like this should work: using the second method, insert the table as a whole and only insert paragraphs if they're not part of a table.

To make sure you're not inserting the paragraphs from the table twice, check the ParentContainer, if it's not "Cell" then just insert the paragraph:
if (!p.ParentContainer.ToString().Equals("Cell"))
     paragraph.InsertParagraphBeforeSelf(p);
To insert the table following the current paragraph, if it exists, use InsertTableBeforeSelf with the FollowingTable:
if (p.FollowingTable != null)
     paragraph.InsertTableBeforeSelf(p.FollowingTable);
May 27, 2014 at 2:18 PM
Thanks Annika!! I tried these methods before, but they are not working correctly. ParentContainer is none and FollowingTable is null always.
I decided this problem as follows:
using (DocX docH = DocX.Load(strH))
    {
        XElement docHxml = docH.Xml;
        foreach (XElement xel in docHxml.Elements())
        {
            string ln = xel.Name.LocalName;
            if (ln == "tbl")
            {
                Table t = new Table(docH, xel);
                paragraph.InsertTableBeforeSelf(t);
            }
            else
            {
                Paragraph p = new Paragraph(docH, xel, 0);
                paragraph.InsertParagraphBeforeSelf(p);
            }
        }
    }
If someone knows a better solution, I'll be grateful for the help!
May 28, 2014 at 9:02 AM
The only alternate method I could think of, is splitting your destination document in two halves, 'before' and 'after' and using the second document as 'middle'. Then use before.InsertDocument(middle) and before.InsertDocument(after). Though I'm sure if that were a possibility, you'd have already tried/used that ;-)

It's a shame my method didn't work, it did when I tested it. Just to be sure, this is the code I used to test my method:
        public static void TestInsert(string doc, string insertDoc)
        {
            DocX insert = DocX.Load(insertDoc);         
            Paragraph beforeMe = insert.Paragraphs[5]; //I just picked a random paragraph here
            
            using (DocX document = DocX.Load(doc))
            {
                foreach (Paragraph p in document.Paragraphs)
                {
                    if(!p.ParentContainer.ToString().Equals("Cell"))
                    {
                        beforeMe.InsertParagraphBeforeSelf(p);
                    }
                    if (p.FollowingTable != null)
                    {
                        beforeMe.InsertTableBeforeSelf(p.FollowingTable);
                    }
                        
                }
            }
            
            insert.SaveAs(@"C:\Temp\NewDoc.docx");
        }
Oct 22, 2014 at 4:12 PM
Out of the box, public void InsertDocument(DocX remote_document) works as expected, everything is inserted where it should be. There are two issues with the implementation:
  1. The document settings are overridden, i.e. page size in the original document
  2. You can't merge a document into a cell in a table
Issue one I could have worked around, but to solve issue two I leveraged @torchpcdnua solution. @Annika89's solution was working great for a while, but then I ran into a document that had a table within a table, producing really odd output. One caution, @torchpcdnua solution is not a complete solution, you still need to do a good bit of legwork to fix up the document you want to insert. i.e. fix all of the ids on pictures, hyperlinks, oleObjects etc.

A full solution would be to leverage public void InsertDocument(DocX remote_document) and replace
// 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());
with
XElement docHxml = remote_Document.Xml;
foreach (XElement xel in docHxml.Elements())
{
    string ln = xel.Name.LocalName;
    if (ln == "tbl")
    {
        var t = new Table(remoteDocument, xel);
        Paragraphs.Last().InsertTableBeforeSelf(t);
    }
    else
    {
        var p = new Paragraph(remoteDocument, xel, 0);
        Paragraphs.Last().InsertParagraphBeforeSelf(p);
    }
}
To insert into a table replace Paragraphs with Tables