Inserting one document into another at a bookmark

Received : 2007/12/05 09:50:12
Message : Hi, I’m having trouble coding a VB.NET moduule to insert one document into another at a specific bookmark.

I have searched the forums, blogs and downloads and have found several posts that describe my problem perfectly. However, I am unable to view any of the solution pages as the website tells me I’m not allowed to view because I need to log on even though I’m already logged on. Specifically I tried to access:
https://docs.aspose.com/words/net/insert-and-append-documents/

My basic problem is that VB.NET tells me that InsertDocument is not defined. I import the Aspose.Words namespace at the top of my module. Is there anything else I should be doing?

Thanks so much for your help!

This message was posted using Aspose.Live 2 Forum

Hi
Here is InsertDocument method in VB.

''' 
''' Inserts content of the external document after the specified node.
''' Section breaks and section formatting of the inserted document are ignored.
''' The insertion is going on the story child level, so the specified node
''' should be either a paragraph or table.
''' 
''' Node in the destination document after which the 
''' content should be inserted.
''' This node should be a story child level node (paragraph or table).
''' Document to insert.
Public Sub InsertDocument(ByVal insertAfterNode As Node, ByVal srcDoc As Document)
' We need to make sure that the specified node is either pargraph or table.
If Not((insertAfterNode.NodeType = NodeType.Paragraph) OrElse _
(insertAfterNode.NodeType = NodeType.Table)) Then
Throw New ArgumentException("The destination node should be either paragraph or table.")
End If
' We will be inserting into the parent of the destination paragraph.
Dim dstStory As CompositeNode = insertAfterNode.ParentNode
' This object will be translating styles and lists during the import.
Dim importer As NodeImporter = New NodeImporter(srcDoc, insertAfterNode.Document, _
ImportFormatMode.KeepSourceFormatting)
' Loop through all sections in the source document.
For Each srcSection As Section In srcDoc.Sections
' Loop through all block level nodes (paragraphs and tables) in the body of the section.
For Each srcNode As Node In srcSection.Body
' Do not insert node if it is a last empty paragarph in the section.
Dim para As Paragraph = TryCast(srcNode, Paragraph)
If (Not para Is Nothing) AndAlso para.IsEndOfSection AndAlso (Not para.HasChildNodes) Then
Exit For
End If
' This creates a clone of the node, suitable for insertion into the destination document.
Dim newNode As Node = importer.ImportNode(srcNode, True)
' Insert new node after the reference node.
dstStory.InsertAfter(newNode, insertAfterNode)
insertAfterNode = newNode
Next srcNode
Next srcSection
End Sub

Also you can find it in API reference.
Best regards.

Thanks so much, Alexey, for your quick response. I didn’t realize that InsertDocument is not an actual method within the object model, but instead it’s a subroutine. I will add this code to my module. I tried to find it in the API reference, but I couldn’t (I wasn’t sure what to look under), so thank you very much for sending it to me as part of your reply.
Kind regards,
Chris.

Hi Alexey,
The InsertDocument function works very well, but it will only insert a document after a paragraph or table. I need to be able to insert a document at a bookmark in the middle of a sentence. Is there any way to do this?
Thanks again for your help.
Kind regards,
Chris Severin

Hi
Thanks for your inquiry. You can try using the following code.

Document doc1 = new Document(@"434_105299_cseverin\in1.doc");
Document doc2 = new Document(@"434_105299_cseverin\in2.doc");
DocumentBuilder builder = new DocumentBuilder(doc1);
builder.MoveToBookmark("test");
builder.InsertBreak(BreakType.ParagraphBreak);
InsertDocument(builder.CurrentParagraph.PreviousSibling, doc2);
doc1.Save(@"434_105299_cseverin\out.doc");

I hope that this will help you.
Best regards.

Hi
Thanks for your inquiry. You can try using the following code.

Document doc1 = new Document(@"434_105299_cseverin\in1.doc");
Document doc2 = new Document(@"434_105299_cseverin\in2.doc");
DocumentBuilder builder = new DocumentBuilder(doc1);
builder.MoveToBookmark("test");
builder.InsertBreak(BreakType.ParagraphBreak);
InsertDocument(builder.CurrentParagraph.PreviousSibling, doc2);
doc1.Save(@"434_105299_cseverin\out.doc");

I hope that this will help you.
Best regards.

Thanks Alexey,
This works very well and is very close to what I need. I modified your code slightly to not insert the paragraph break before inserting the second document and the result is that second document is placed directly in front of the bookmark, which is exactly what I want.
However, I do have another formatting issue and it’s due to the fact that all Word documents contain at least one paragraph break by default. Even an empty document contains a paragraph break. Naturally, what happens when I insert the second document into the first one is that the paragraph break at the end of the second document gets copied into the first document and this is sometimes not wanted.
I have many occasions where I want to insert a document that contains only a phrase or a part of a sentence into another document at a specific bookmark in the middle of a sentence, so I don’t want the paragraph break at the end of the document. Doing this in VBA code in Microsoft Word allowed me to code “SELECTION.TYPEBACKSPACE” immediately after inserting the second document into the first one which effectively deleted the paragraph mark that was at the end of the second document.
Is there any way of acheiving this in Aspose.Words?
Thanks again for all your help with this truly excellent product.
Chris Severin

Hi
Thanks for your inquiry. I think that you can try using the following code.

Document doc = new Document(@"443_105299_cseverin\in.doc");
Document doc1 = new Document(@"443_105299_cseverin\in1.doc");
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToBookmark("test");
NodeCollection nodes = doc1.GetChildNodes(NodeType.Paragraph, true);
if (nodes.Count == 1)
{
    foreach (Run run in (nodes[0] as Paragraph).Runs)
    {
        builder.InsertNode(doc.ImportNode(run, true, ImportFormatMode.KeepSourceFormatting));
    }
}
doc.Save(@"443_105299_cseverin\out.doc");

I hope that this will help you.
Best regards.

Hi Alexey!
Thank you so, SO much for all your help. This is exactly what I was looking for! I’m not sure what it’s doing, but it works perfectly and I can’t thank you enough.
All the best!
C.

Hello again!
I have been successfully inserting one document into another using the above code for the past few months, however I have just hit another situation that I don’t know how to handle. I need to be able to insert a document that contains several paragraphs and bookmarks into an existing document at a specified bookmark in the middle of a paragraph so that the bookmarks from the document being inserted are retained in their original positions after the insertion.
For example, a portion of my “master” document might look like this:
sdf awesatg dfg asg adga dfg aga asdg ag asdgf ag dh asg ahgdfg asd asdg dry rwdvgsdh erw asdgsdfh asdg dh ady hgsad asdfasdg asdg sg hn dhstdh ryh shsd ewsdfshdaa asdgfadg sdag dghh dfh.
The document I want to insert into the above “master” document at might look like this:
dfghs hgj esr fgh sdfh sdty fn sdfh sdr dfh sdfg sdh sdhg sdfg sdg sdsdh dy sdfgh sdg sdfg sdg.
Vnfg sdfy sfgh sdtsdsdsdhs sdfh fsgjh ssdsf eyfgh edrty dh sfh sdh asdsa dg asg gayerdfhe dh te hdh wt dg yt dhg hsd sdh
After the insertion, I want the “master” document to look like this:
sdf awesatg dfg asg adga dfg aga asdg ag asdgf ag dh asg ahgdfg asd asdg dry rwdvgsdh erw asdgsdfh asdg dh ady hgsad dfghs hgj esr fgh sdfh sdty fn sdfh sdr dfh sdfg sdh sdhg sdfg sdg sdsdh dy sdfgh sdg sdfg sdg.
Vnfg sdfy sfgh sdtsdsdsdhs sdfh fsgjh ssdsf eyfgh edrty dh sfh sdh asdsa dg asg gayerdfhe dh te hdh wt dg yt dhg hsd sdh asdfasdg asdg sg hn dhstdh ryh shsd ewsdfshdaa asdgfadg sdag dghh dfh.
After the insertion is complete, I will insert text in the remaining bookmarks. How might I do this?
Thanks, as always for your assistance.
Chris.

Hi
Thanks for your request. I think that you can find solution here.
https://docs.aspose.com/words/java/insert-and-append-documents/
I hope this could help you.
Best regards.

Thanks again for your quick response, Alexey! Unfortunately, the format of my example in my last post was such that it looked like I was trying to insert a document after a paragraph, when in fact I am trying to insert the document at a bookmark in the middle of a pargraph. I have reformatted my example below:
sdf awesatg dfg asg adga dfg aga asdg ag asdgf ag dh asg ahgdfg asd asdg dry rwdvgsdh erw asdgsdfh asdg dh ady erweygs hgsad asdfasdg asdg sg hn dhstdh ryh shsd ewsdfshdaa asdgfadg sdag dghh dfh.
The document I want to insert into the above “master” document at might look like this:
dfghs hgj esr fgh sdfh sdty fn sdfh sdr dfh sdfg sdh sdhg sdfg sdg sdsdh dy sdfgh sdg sdfg sdg.
Vnfg sdfy sfgh sdtsdsdsdhs sdfh fsgjh ssdsf eyfgh edrty dh sfh sdh asdsa dg asg gayerdfhe dh te hdh wt dg yt dhg hsd sdh
After the insertion, I want the “master” document to look like this:
sdf awesatg dfg asg adga dfg aga asdg ag asdgf ag dh asg ahgdfg asd asdg dry rwdvgsdh erw asdgsdfh asdg dh ady erweygs hgsad dfghs hgj esr fgh sdfh sdty fn sdfh sdr dfh sdfg sdh sdhg sdfg sdg sdsdh dy sdfgh sdg sdfg sdg.
Vnfg sdfy sfgh sdtsdsdsdhs sdfh fsgjh ssdsf eyfgh edrty dh sfh sdh asdsa dg asg gayerdfhe dh te hdh wt dg yt dhg hsd sdh asdfasdg asdg sg hn dhstdh ryh shsd ewsdfshdaa asdgfadg sdag dghh dfh.
I have been using your InsertDocument subroutine for the past few months now and it works wonderfully as long as I want to insert a document after a paragraph. What I need to do now is to insert a document at a bookmark in the middle of a paragraph and the InsertDocument subroutine expects to be passed a paragraph node that the document will be inserted after. I need the insert point to be at the bookmark, not after the paragraph. Is this possible?
Thanks again for all your help.
C.

Hi
Thanks for your request. I modified InsertDocument method a little. Please see the following code.

public void InsertDocumentAtBookmark(string bookmarkName, Document dstDoc, Document srcDoc)
{
    // Create DocumentBuilder
    DocumentBuilder builder = new DocumentBuilder(dstDoc);
    // Move cursor to bookmark and insert paragraph break
    builder.MoveToBookmark(bookmarkName);
    builder.Writeln();
    // Content of srcdoc will be inserted after this node
    Node insertAfterNode = builder.CurrentParagraph.PreviousSibling;
    // Content of first paragraph of srcDoc will be apended to this parafraph
    Paragraph insertAfterParagraph = (Paragraph)insertAfterNode;
    // Content of last paragraph of srcDoc will be apended to this parafraph
    Paragraph insertBeforeParagraph = builder.CurrentParagraph;
    // We will be inserting into the parent of the destination paragraph.
    CompositeNode dstStory = insertAfterNode.ParentNode;
    // Loop through all sections in the source document.
    foreach (Section srcSection in srcDoc.Sections)
    {
        // Loop through all block level nodes (paragraphs and tables) in the body of the section.
        foreach (Node srcNode in srcSection.Body)
        {
            // Do not insert node if it is a last empty paragarph in the section.
            Paragraph para = srcNode as Paragraph;
            if ((para != null) && para.IsEndOfSection && !para.HasChildNodes)
                break;
            // If current paragraph is first paragraph of srcDoc 
            // then append its content to insertAfterParagraph
            if (para.Equals(srcDoc.FirstSection.Body.FirstParagraph))
            {
                foreach (Node node in para.ChildNodes)
                {
                    Node dstNode = dstDoc.ImportNode(node, true, ImportFormatMode.KeepSourceFormatting);
                    insertAfterParagraph.AppendChild(dstNode);
                }
            }
            // If current paragraph is last paragraph of srcDoc 
            // then append its content to insertBeforeParagraph
            else if (para.Equals(srcDoc.LastSection.Body.LastParagraph))
            {
                Node previouseNode = null;
                foreach (Node node in para.ChildNodes)
                {
                    Node dstNode = dstDoc.ImportNode(node, true, ImportFormatMode.KeepSourceFormatting);
                    if (previouseNode == null)
                        insertBeforeParagraph.InsertBefore(dstNode, insertBeforeParagraph.FirstChild);
                    else
                        insertBeforeParagraph.InsertAfter(dstNode, previouseNode);
                    previouseNode = dstNode;
                }
            }
            else
            {
                // This creates a clone of the node, suitable for insertion into the destination document.
                Node newNode = dstDoc.ImportNode(srcNode, true, ImportFormatMode.KeepSourceFormatting);
                // Insert new node after the reference node.
                dstStory.InsertAfter(newNode, insertAfterNode);
                insertAfterNode = newNode;
            }
        }
    }
}

I hope this could help you.
Best regards.

Hi Alexey,
Thanks so very much for this! I am trying to follow your logic through and I think it will work for me although I am working in VB and my C# is not very good, so I am having trouble translating some of the code.
I hate to be a bother, but would it be possible to re-create your InsertDocumentAtBookmark method in VB so I am sure it is correct?
Much appreciated!
Thanks!
C.

Hi
Thanks for your request. Here is code in VB.

Sub InsertDocumentAtBookamrk(ByVal bookmarkName As String, ByVal dstDoc As Document, ByVal srcDoc As Document)
'Create DocumentBuilder
Dim builder As DocumentBuilder = New DocumentBuilder(dstDoc)
'Move cursor to bookmark and insert paragraph break
builder.MoveToBookmark(bookmarkName)
builder.Writeln()
'Content of srcdoc will be inserted after this node
Dim insertAfterNode As Node = builder.CurrentParagraph.PreviousSibling
'Content of first paragraph of srcDoc will be apended to this parafraph
Dim insertAfterParagraph As Paragraph = CType(insertAfterNode, Paragraph)
'Content of last paragraph of srcDoc will be apended to this parafraph
Dim insertBeforeParagraph As Paragraph = builder.CurrentParagraph
'We will be inserting into the parent of the destination paragraph.
Dim dstStory As CompositeNode = insertAfterNode.ParentNode
'Loop through all sections in the source document.
Dim srcSection As Section
For Each srcSection In srcDoc.Sections
'Loop through all block level nodes (paragraphs and tables) in the body of the section.
Dim srcNode As Node
For Each srcNode In srcSection.Body
'Do not insert node if it is a last empty paragarph in the section.
Dim para As Paragraph = CType(srcNode, Paragraph)
If (Not para Is Nothing) AndAlso para.IsEndOfSection AndAlso (Not para.HasChildNodes) Then
Exit For
End If
'If current paragraph is first paragraph of srcDoc 
'then appent its content to insertAfterParagraph
If (para.Equals(srcDoc.FirstSection.Body.FirstParagraph)) Then
Dim node As Node
For Each node In para.ChildNodes
Dim dstNode As Node = dstDoc.ImportNode(node, True, ImportFormatMode.KeepSourceFormatting)
insertAfterParagraph.AppendChild(dstNode)
Next
'If current paragraph is last paragraph of srcDoc 
'then appent its content to insertBeforeParagraph
ElseIf (para.Equals(srcDoc.LastSection.Body.LastParagraph)) Then
Dim previouseNode As Node
Dim node As Node
For Each node In para.ChildNodes
Dim dstNode As Node = dstDoc.ImportNode(node, True, ImportFormatMode.KeepSourceFormatting)
If (previouseNode Is Nothing) Then
insertBeforeParagraph.InsertBefore(dstNode, insertBeforeParagraph.FirstChild)
Else
insertBeforeParagraph.InsertAfter(dstNode, previouseNode)
End If
previouseNode = dstNode
Next
Else
'This creates a clone of the node, suitable for insertion into the destination document.
Dim newNode As Node = dstDoc.ImportNode(srcNode, True, ImportFormatMode.KeepSourceFormatting)
'Insert new node after the reference node.
dstStory.InsertAfter(newNode, insertAfterNode)
insertAfterNode = newNode
End If
Next
Next
End Sub

Best regards.

Alexey, you rock!!! This is terrific. Thanks SO much. It’s just about perfect. The only problem I have now is the final paragraph break in the subdocument is also being inserted into the main document, so if the bookmark I’m inserting at is in the middle of a paragraph in the main document, it ends up with a break in it after the insertion.
Is there any way to either a) not include the last paragraph break in the inserted text or b) remove it from the main document after the insertion?
If this is possible, then this InsertDocumentAtBookmark subroutine you’ve created will be absolutely perfect for me and I’ll be able to use it in place of the InsertDocument subroutine.
You guys are absolutely brilliant! I can’t thank you enough for a wonderful product and your amazing technical support!
Cheers!

Hi
I think that you can just remove empty paragraphs for the end of source document. You can do this using the following code snippet.

While (Not srcDoc.LastSection.Body.LastParagraph.HasChildNodes)
srcDoc.LastSection.Body.LastParagraph.Remove()
End While
Also please see modified InsertDocumentAtBookamrk
Sub InsertDocumentAtBookamrk(ByVal bookmarkName As String, ByVal dstDoc As Document, ByVal srcDoc As Document)
'Create DocumentBuilder
Dim builder As DocumentBuilder = New DocumentBuilder(dstDoc)
'Move cursor to bookmark and insert paragraph break
builder.MoveToBookmark(bookmarkName)
builder.Writeln()
'Content of srcdoc will be inserted after this node
Dim insertAfterNode As Node = builder.CurrentParagraph.PreviousSibling
'Content of first paragraph of srcDoc will be apended to this parafraph
Dim insertAfterParagraph As Paragraph = CType(insertAfterNode, Paragraph)
'Content of last paragraph of srcDoc will be apended to this parafraph
Dim insertBeforeParagraph As Paragraph = builder.CurrentParagraph
'We will be inserting into the parent of the destination paragraph.
Dim dstStory As CompositeNode = insertAfterNode.ParentNode
'Remove empty paragraphs from the end of document
While (Not srcDoc.LastSection.Body.LastParagraph.HasChildNodes)
srcDoc.LastSection.Body.LastParagraph.Remove()
End While
'Loop through all sections in the source document.
Dim srcSection As Section
For Each srcSection In srcDoc.Sections
'Loop through all block level nodes (paragraphs and tables) in the body of the section.
Dim srcNode As Node
For Each srcNode In srcSection.Body
'Do not insert node if it is a last empty paragarph in the section.
Dim para As Paragraph = CType(srcNode, Paragraph)
If (Not para Is Nothing) AndAlso para.IsEndOfSection AndAlso (Not para.HasChildNodes) Then
Exit For
End If
'If current paragraph is first paragraph of srcDoc 
'then appent its content to insertAfterParagraph
If (para.Equals(srcDoc.FirstSection.Body.FirstParagraph)) Then
Dim node As Node
For Each node In para.ChildNodes
Dim dstNode As Node = dstDoc.ImportNode(node, True, ImportFormatMode.KeepSourceFormatting)
insertAfterParagraph.AppendChild(dstNode)
Next
'If current paragraph is last paragraph of srcDoc 
'then appent its content to insertBeforeParagraph
ElseIf (para.Equals(srcDoc.LastSection.Body.LastParagraph)) Then
Dim previouseNode As Node
Dim node As Node
For Each node In para.ChildNodes
Dim dstNode As Node = dstDoc.ImportNode(node, True, ImportFormatMode.KeepSourceFormatting)
If (previouseNode Is Nothing) Then
insertBeforeParagraph.InsertBefore(dstNode, insertBeforeParagraph.FirstChild)
Else
insertBeforeParagraph.InsertAfter(dstNode, previouseNode)
End If
previouseNode = dstNode
Next
Else
'This creates a clone of the node, suitable for insertion into the destination document.
Dim newNode As Node = dstDoc.ImportNode(srcNode, True, ImportFormatMode.KeepSourceFormatting)
'Insert new node after the reference node.
dstStory.InsertAfter(newNode, insertAfterNode)
insertAfterNode = newNode
End If
Next
Next
End Sub

Best regards.

Hi Alexey,
I can’t seem to get the empty paragraph removal to work. What seems to be happening is the very last paragraph marker in the MS Word source document that I am inserting gets inserted into my destination document along with the rest of the text, which then causes a paragraph break to occur at that point in the destination document. And because the bookmark in the destination document that I am inserting the source document at is in the middle of a sentence, I don’t want that paragraph break to happen.
There’s always at least one paragraph marker, even in a blank MS Word document and I’m thinking that maybe the paragraph removal method doesn’t work on the very last paragraph marker in a document. It can’t be deleted from an a MS Word document either.
What I think needs to happen is the paragraph marker needs to be removed from the destination document AFTER the insertion. After the insertion happens, the paragraph marker that marked the end of the source document has been inserted into the destination document (along with the rest of the source document text), but now, in the destination document, it is no longer the final paragraph marker (and hopefully can be removed!).
Is it possible to find that paragraph marker in the destination document and remove it from there?
Thanks, as always, for all your help.
Cheers!
Chris.

Hi
Thanks for your request. This code works fine on my side. So could you please attach your documents for testing? I will investigate this problem and try to help you.
Best regards.

Hi Alexey,
Here are two sample documents: destination.doc and subdoc1.doc. I insert subdoc1.doc into destination.doc at a bookmark called Subdocument. It seems that I can only upload one file per post, so I’ll send destination.doc with this reply and I’ll send subdoc1.doc with another.
Thanks for looking into this for me.
Cheers!
C.