''
'' This code is part of Document Solutions for Word demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports System.Linq
Imports GrapeCity.Documents.Word
'' This sample shows how to insert the whole body of an existing DOCX into
'' another document at a location where an arbitrary search string is found.
'' One interesting point in this sample is that the code ensures that the
'' insert position is valid, i.e. the source content (all paragraphs of
'' the source document) can be inserted at the found point. If necessary,
'' the target is split so that there is a content object of a valid type
'' at the point where the source is to be inserted.
'' In this sample, the target document is JsFrameworkExcerpt.
'' The source document inserted is SampleParagraphs, and it is inserted
'' on page 2 of the source document, immediately before the string
'' "software design principles".
Public Class InsertAtFound
Public Function CreateDocx() As GcWordDocument
'' The string to find. The source document will be inserted before this string
Const findPattern = "software design principles"
'' Target document where the source document will be inserted:
Dim doc = New GcWordDocument()
doc.Load(Path.Combine("Resources", "WordDocs", "JsFrameworkExcerpt.docx"))
'' Source document that will be inserted into the target:
Dim sourceDoc = New GcWordDocument()
sourceDoc.Load(Path.Combine("Resources", "WordDocs", "SampleParagraphs.docx"))
'' Note: the inserted document starts with a 'Heading 1', which adds a page break.
'' We change it to 'Heading 2' to avoid this so that the result is more clear:
sourceDoc.Body.Paragraphs.First.Style = sourceDoc.Styles(BuiltInStyleId.Heading2)
'' Find the first occurrence of the search string:
Dim findResult = doc.Body.Find(findPattern, New FindOptions(doc) With {.IgnoreCase = True}).FirstOrDefault()
If findResult Is Nothing Then
Throw New Exception("Unexpected: search string not found.")
End If
'' Find a valid insertion point near the found string:
Dim insertObject = CreateInsertPoint(findResult)
'' Copy the source document to the target at insertion point
sourceDoc.Body.CopyTo(insertObject.GetRange(), InsertLocation.Before)
'' Done
Return doc
End Function
'' Walk up the parent chain And determine where we are - inside body, cell Or contentcontrol.
'' Return the original object if we are inside body Or cell.
'' Return contentcontrol if we are inside contentcontrol.
Private Shared Function GetAnchorObject(testedObject As ContentObject) As ContentObject
Dim originalObject = testedObject
While True
If testedObject.ParentContent Is Nothing Then
Return originalObject
ElseIf TypeOf testedObject Is Cell Then
Return originalObject
ElseIf TypeOf testedObject Is ContentControl Then
Return testedObject
Else
testedObject = testedObject.ParentContent
End If
End While
Return Nothing
End Function
'' This method assumes that testObject Is always an entity inside a paragraph.
Private Shared Function GetParentParagraph(testObject As ContentObject) As Paragraph
While testObject IsNot Nothing
If TypeOf testObject Is Paragraph Then
Return CType(testObject, Paragraph)
End If
testObject = testObject.ParentContent
End While
Throw New ArgumentException("testObject is not inside a paragraph.")
End Function
Private Shared Function CreateInsertPoint(fr As FindResult) As ContentObject
Dim anchorObject = GetAnchorObject(fr.Range.First())
Dim foundParagraph = GetParentParagraph(anchorObject)
If fr.StartIndex > 0 AndAlso TypeOf anchorObject Is Text Then
anchorObject = CType(anchorObject, Text).Split(fr.StartIndex)
End If
If foundParagraph Is anchorObject Then
anchorObject = foundParagraph.Split(anchorObject, InsertLocation.End)
Else
anchorObject = foundParagraph.Split(anchorObject, InsertLocation.Before)
End If
Return anchorObject
End Function
End Class