Merging Several Word Documents

Hi. I have a template that in various places has text in the following format: [INTRODUCTION], [CONCLUSION] and so forth. I want to replace where it says [INTRODUCTION] with text from Introduct.doc.

How do I go about this using ASPOSE Words. I know I should change it to a mailmerge field so I can easily select it, but how do I go about opening the second word document, selecting all the text and pictures and tables, and pasting it into the file I want to send to the browser.

Any suggestions?

In fact, it is not necessary to mark the insertion places with bookmarks or merge fields. Plain text can also be replaced with the content of the external document.

I have added the code example matching your task to one of our technical articles:

https://docs.aspose.com/words/net/insert-and-append-documents/

Please give it a try and let me know if it does the job.

Best regards,

Does this method also work with the same marked text in headers and footers? Or should I then convert to a merge field so I can select it instantly?

The example looks exactly like what I need.

If I was to convert to merge fields, had would that change? The only example of merge fields is if the replacing document is the same name as the field name. That is not the case in my example…

Thanks a bunch!

Yes, this example should work with all occurences of the specified text in the document. It can even be put inside the table cell or textbox.

In case of using merge fields you can work out your own method of recognizing merge fields corresponding to the external documents and maintaining a relationship between field name and document file name. Just use the provide code example as a base an modify it to your needs. Please let me know if you need any assistance with it.

Best regards,

Why do you use

TestUtil.Open

In fact… TestUtil.Open is undefined, and so is InsertDocEvaluator

Also, the InsertDocument routine has the following near the top:

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

Will that mess up any header/footer replacements?

Any ideas?

Thanks for pointing this out. TestUtil call seem to make its way from my test environment. You should use New Document of course. I have corrected this in the article.

InsertDocEvaluator seem to be defined in the article. Please check again.

I have also tested the replacement in headers/footers. It seem to work fine. If you have any problems with it please attach the template document for me to reproduce and fix.

Best regards,

This line is causing the build error:
mainDoc.Range.Replace(New Regex(text), New ReplaceEvaluator(InsertDocEvaluator), False)

And here is the error:
Error 12 ‘Aspose.Words.ReplaceEvaluator’ is a delegate type and requires a single ‘addressof’ expression as the only argument to the constructor.

Here is my entire code segment:

Public Sub TestReplaceTextWithDoc()

Dim licenseFile As String = MapPath("bin") & "\Aspose.Words.lic"
If System.IO.File.Exists(licenseFile) Then
Dim license As Aspose.Words.License = New Aspose.Words.License
license.SetLicense(licenseFile)
End If

Dim mainDoc As Document = New Document(Server.MapPath("report\Template_DOC.doc"))
Dim subDoc As Document

subDoc = New Document(Server.MapPath("report\components\I_A_A.doc"))
ReplaceTextWithDoc(mainDoc, subDoc, "[INTRODUCTION]")

subDoc = New Document(Server.MapPath("report\components\C_A_A.doc"))
ReplaceTextWithDoc(mainDoc, subDoc, "[CONCLUSION]")

SendToBrowser(mainDoc, "DOC")

Response.End()
End Sub

‘’’ 

‘’’ Replaces specified string in the main document with the contents of the external document.
‘’’ 

Private Sub ReplaceTextWithDoc(ByVal mainDoc As Document, ByVal insertedDoc As Document, ByVal text As String)
’ Assign the reference to the inserted document to the private member of the container class
’ to let InsertDocEvaluator could get a hold of it.
Me.insertDoc = insertedDoc
mainDoc.Range.Replace(New Regex(text), New ReplaceEvaluator(InsertDocEvaluator), False)
End Sub

‘’’ 

‘’’ InsertDocEvaluator takes reference to the inserted document from here.
‘’’ 

Private insertDoc As Document

Private Function InsertDocEvaluator(ByVal sender As Object, ByVal e As ReplaceEvaluatorArgs) As ReplaceAction
Dim para As Paragraph = CType(e.MatchNode.ParentNode, Paragraph)

’ Insert document after the paragraph, containing match text.
InsertDocument(para, insertDoc)

’ Remove the paragraph with the match text.
para.Remove()

Return (ReplaceAction.Skip)
End Function

Private 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

Yes, in Visual Basic you need to use AddressOf in this declaration.

mainDoc.Range.Replace(New Regex(text), New ReplaceEvaluator(AddressOf InsertDocEvaluator), False)

We use special tool for converting C# code to VB.NET and it does not always make it correctly.

I have fixed the code in the article.

Best regards,

Not able to view the below link page. Please help me.

https://docs.aspose.com/words/net/insert-and-append-documents/

Hi

Thanks for your inquiry. If you need just merge several word document, you sould use Document.AppendDocument method. Please see the following code example:

// Open documents
Document doc1 = new Document("C:\\Temp\\in1.doc");
Document doc2 = new Document("C:\\Temp\\in2.doc");
Document doc3 = new Document("C:\\Temp\\in3.doc");
// Create an empty document
Document mainDoc = new Document();
mainDoc.RemoveAllChildren();
// Append document to the main document
mainDoc.AppendDocument(doc1, ImportFormatMode.KeepSourceFormatting);
mainDoc.AppendDocument(doc2, ImportFormatMode.KeepSourceFormatting);
mainDoc.AppendDocument(doc3, ImportFormatMode.KeepSourceFormatting);
// Save output document
mainDoc.Save("C:\\Temp\\out.doc")

Hope this helps.

Best regards.

I know this is an old post but how would you convert this to use with the new DLLs?

mainDoc.Range.Replace(New Regex(text), New ReplaceEvaluator(AddressOf InsertDocEvaluator), False)

We get this error:

Type ‘ReplaceEvaluator’ is not defined.

So we changed it to MatchEvaluator:

mainDoc.Range.Replace(New Regex(text), New MatchEvaluator(AddressOf InsertDocEvaluator), False)

and get the error attached.

Any ideas?

Hi Mokumax,

Thanks for your inquiry and sorry for the delayed response.

You can use the following overload of Range.Replace method to find all occurrences of a character pattern specified by a regular expression and call a user defined replace evaluator method:

public int Replace(Regex, IReplacingCallback, bool);

https://reference.aspose.com/words/net/aspose.words.range/replace/methods/3

Best Regards,