Aspose words insert a file at bookmark exact location and not after the paragraph containing the bookmark

hello, i’m trying to find a solution since 3 days on a really small problem …

i’m trying to insert a subdocument at a bookmark location, the problem is the document is insert AFTER the paragraph containing the bookmark and not at the exact bookmark location …

this problem break our documents layout.

do you have any solutions ?

Hi

Thanks for your request. I think you can find a solution of this issue in the following thread:
https://forum.aspose.com/t/114203
Best regards.

ok it’s not far from working

i got your code :

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

but i have tables and paragraphs and not only paragraphs in the children document to insert so it crash when trying to cast the table to a paragraph (Dim para As Paragraph = CType(srcNode, Paragraph))

so i modified the sub like this :

'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 = Nothing
        Dim table As Aspose.Words.Tables.Table = Nothing
        If (srcNode.NodeType = NodeType.Paragraph) Then
            para = CType(srcNode, Paragraph)
        ElseIf (srcNode.NodeType = NodeType.Table) Then
            table = CType(srcNode, Aspose.Words.Tables.Table)

        End If

        '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 IsNot Nothing AndAlso 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 IsNot Nothing AndAlso para.Equals(srcDoc.LastSection.Body.LastParagraph)) Then
            Dim previouseNode As Node = Nothing
            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

but now this code will never execute …

If (para IsNot Nothing AndAlso 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 IsNot Nothing AndAlso para.Equals(srcDoc.LastSection.Body.LastParagraph)) Then
    Dim previouseNode As Node = Nothing
    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)

is it the reason why i loose Titles formating when a title is the first paragraph of a document ?

Hi

Thanks for your request. Title style is lost because you append content of the first paragraph to the paragraph with bookmark, and Title style was applied to the paragraph in the source document, which actually is not copied into the destination document (only its content is copied).
Best regards.

thank you for your fast answers

do you have any solution to copy also the style ?

Thanks for your inquiry. I think you have two option here.

  1. If your destination document contains the same set of styles as source document, you can just specify name of style, which should be applied to the paragraph. You can do something like the following:
dstPar.ParagraphFormat.StyleName = srcPar.ParagraphFormat.StyleName;
  1. You can insert entire paragraph from the source document, copy content from the paragraph, which contain bookmark to this paragraph and remove paragraph with bookmark.

Hope this helps.
Best regards.

EDIT : A last question, is there a way to remove the empty line we added here :

builder.MoveToBookmark(bookmarkName)
builder.Writeln()

Styles are correctly applied with this code :

'Copy all non existing styles from the source to the destination document

For Each stl As Style In srcDoc.Styles

    If dstDoc.Styles.Item(stl.Name) Is Nothing And stl.Type <> StyleType.Table Then

        Dim stlcopy As Style = dstDoc.Styles.Add(stl.Type, stl.Name)


        FontCopy(stlcopy, stl)

    End If

Next

And in when processing the first paragraph

'Set the copied style to the first paragraph
insertAfterParagraph.ParagraphFormat.StyleName = para.ParagraphFormat.StyleName

my final sub is :

Sub InsertDocumentAtBookamrk(ByVal bookmarkName As String, ByVal dstDoc As Document, ByVal srcDoc As Document)

    Try

        For Each stl As Style In srcDoc.Styles

            If dstDoc.Styles.Item(stl.Name) Is Nothing And stl.Type <> StyleType.Table Then

                Dim stlcopy As Style = dstDoc.Styles.Add(stl.Type, stl.Name)


                FontCopy(stlcopy, stl)

            End If

        Next

        'Create DocumentBuilder

        Dim builder As DocumentBuilder = New DocumentBuilder(dstDoc)

        'Move cursor to bookmark and insert paragraph break

        builder.MoveToBookmark(bookmarkName)

        builder.Writeln()

        'builder.InsertParagraph()

        '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

        Dim isFirstPara As Boolean = True


        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 = Nothing

                Dim table As Aspose.Words.Tables.Table = Nothing

                If (srcNode.NodeType = NodeType.Paragraph) Then

                    para = CType(srcNode, Paragraph)

                ElseIf (srcNode.NodeType = NodeType.Table) Then

                    table = CType(srcNode, Aspose.Words.Tables.Table)


                End If

                If (para IsNot 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 IsNot Nothing AndAlso 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

                    'Set the copied style to the first paragraph

                    insertAfterParagraph.ParagraphFormat.StyleName = para.ParagraphFormat.StyleName

                    'If current paragraph is last paragraph of srcDoc

                    'then appent its content to insertBeforeParagraph

                ElseIf (para IsNot Nothing AndAlso para.Equals(srcDoc.LastSection.Body.LastParagraph)) Then

                    Dim previouseNode As Node = Nothing

                    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

    Catch ex As Exception

        Console.WriteLine("Crash")


    End Try

End Sub

Thanks for your inquiry. I think, in this case, you can just check whether current paragraph of DocuemntBuidler is empty and if so remove it. You can use code like the following:

if (!builder.CurrentParagraph.HasChildNodes)
    builder.CurrentParagraph.Remove();

In addition, you can check whether bookmark is the last child of the destination paragraph and if so, do not insert paragraph break at the bookmark.
Best regards.