Mail merge is a process of merging or importing data from a .NET object, also known as data source, to a DocumentModel instance, also known as template document.

Binding between data source and template document is provided by Field class whose FieldType property is MergeField (usually called a merge field) and whose GetInstructionText()()()() method returns text that refers to the name of the property or column in data source (usually called a merge field name), and in mail merge process, that Field instance will be replaced by actual data returned from the data source for the given property or column name.

Introductory example

Following example gets you right-ahead on the mail merge code, so you can immediately figure out what mail merge is and how to use it.

CopyC#
// Create a new empty document.
var doc = new DocumentModel();

// Add document content.
doc.Sections.Add(new Section(doc, new Paragraph(doc, new Field(doc, FieldType.MergeField, "FullName"))));

// Save the document to a file.
doc.Save("TemplateDocument.docx", SaveOptions.DocxDefault);

// Initialize mail merge data source.
var dataSource = new { FullName = "John Doe" };

// Execute mail merge.
doc.MailMerge.Execute(dataSource);

// Save the document to a file.
doc.Save("Document.docx", SaveOptions.DocxDefault);
CopyVB.NET
' Create a new empty document.
Dim doc = New DocumentModel()

' Add document content.
doc.Sections.Add(New Section(doc, New Paragraph(doc, New Field(doc, FieldType.MergeField, "FullName"))))

' Save the document to a file.
doc.Save("TemplateDocument.docx", SaveOptions.DocxDefault)

' Initialize mail merge data source.
Dim dataSource = New With {.FullName = "John Doe"}

' Execute mail merge.
doc.MailMerge.Execute(dataSource)

' Save the document to a file.
doc.Save("Document.docx", SaveOptions.DocxDefault)

Here are the screenshots from TemplateDocument.docx and Document.docx files.

TemplateDocument.docx
Introductory Mail Merge Template Document
Document.docx
Introductory Mail Merge Document
Tip

If TemplateDocument.docx is empty when you open it with Microsoft Word, press Alt + F9 to toggle field codes.

As you can see, Field with field type MergeField and instruction text FullName has been replaced by the value from data source property named FullName.

In this example data source was instance of an anonymous type, but GemBox.Document supports almost any .NET object to be used as a mail merge data source. More details about mail merge data sources are presented in the next section.

Mail merge data sources

Mail merge supports following data source types:

Sequence of name and value pairs is used for the simplest mail merge. Names represent merge field names and values represent replacements for merge fields.

Whenever possible, mail merge engine will access data source property or column values without using reflection (for example, DataRow column values will be accessed through DataRow[string columnName] indexer. Reflection will be used if there is no any other mechanism available to retrieve property / column values based on their names.

If you are uncomfortable with reflection usage (security and performance issues), you can wrap your data source into your IMailMergeDataSource interface implementation and use it as a mail merge data source instead of the original data source. Mail merge engine will only use members from your IMailMergeDataSource implementation which can be implemented in a secure and efficient way - without using reflection.

Implementing IMailMergeDataSource interface is necessary when your original data source is not a standard .NET object (maybe object is implemented as a property bag, without standard .NET properties) or is not a standard .NET sequence (implemented without IEnumerable interface).

Mail merge process

To start the mail merge process, first mail merge range has to be found.

Mail merge range is a part of the document where mail merge algorithm searches for merge field instances and replaces them with actual data from the data source.

If the data source contains more than one item, original mail merge range (the one that contains merge field instances) will be cloned and appended to the document just after previously processed mail merge range and then mail merge algorithm merges this mail merge range with data from the next item in the data source. This process is repeated for every item in the data source.

Mail merge process can be initiated with two methods:

Note

Mail merge process is initiated on the DocumentModel..::..MailMerge property.

Execute method

When mail merge process is initiated with Execute method, mail merge range is the whole document content - all sections under the document.

This is best illustrated with the following example.

Let the data source be the following DataTable (this data source will also be used in the subsequent examples):

TableName: People

Name

Surname

John

Doe

Fred

Nurk

Hans

Meier

Following image shows the structure, in an XML-like format, of the template document and the structure of the document resulting from mail merging the data source into the template document with Execute method:

Structure of template document and mail merged document with Execute method
Mail Merge Execute

Oval black-lined rectangle shows mail merge range in the template document, and how it was expanded by cloning, appending it and filling it with the data in the mail merged document.

ExecuteRange method

When mail merge process is initiated with ExecuteRange method, mail merge range is determined by the merge field instances with names 'RangeStart:rangeName' and 'RangeEnd:rangeName'.

rangeName parameter should be equal to rangeName parameter when ExecuteRange(String, Object) method overload is used or it should be equal to the data source name when ExecuteRange(Object) method overload is used.

Note

When using ExecuteRange(Object) method overload, range name is determined from the data source in the following way:

Merge fields that represent mail merge range beginning and end are removed from the resulting mail merge range, but mail merge range does not necessary start and ends where these fields were positioned, as the following example shows.

Following image shows the structure, in an XML-like format, of the template document and the structure of the documents resulting from mail merging the data source into the template document with ExecuteRange method:

Structure of template document and mail merged documents with ExecuteRange method using common ancestor and sibling ancestors options
Mail Merge Execute Range

Oval black-lined rectangle shows mail merge range in the template document with common ancestor and sibling ancestors options, and how it was expanded by cloning, appending it and filling it with the data in the mail merged documents.

Notice how merge fields that represent mail merge range beginning and end have a rangeName parameter with value People, and it is equal to the name of the data source introduced in the previous section which is also used in this example.

Mail merge range depends on the value of the MailMerge..::..RangeResolution property.

If a value of the MailMerge..::..RangeResolution property is CommonAncestor, mail merge range will contain only one top-most element - a common ancestor of the merge field named RangeStart:rangeName and the merge field named RangeEnd:rangeName.

If a value of the MailMerge..::..RangeResolution property is SiblingAncestors, mail merge range top-most elements will be a collection of elements that start from an ancestor of the merge field named RangeStart:rangeName or itself, and ends with an ancestor of the merge field named RangeEnd:rangeName or itself, with both ancestors having the same parent - meaning that they are siblings.

Mail merge options

Mail merge functionality is exposed through MailMerge type and its flexibility allows further customizations and operations by changing or using the following properties and methods:

  • RangeResolution - as explained in the previous section, allows you to specify how named mail merge range will be resolved from the document content.

  • RemoveEmptyRanges - if set to true, removes mail merge ranges into which no data has been imported.

  • FieldMerging - event that allows you to intercept every mail merge operation and customize the data importation process.

  • FieldMappings - used if merge field name and data source property / column name are different, but they should be merged.

    Note

    Merge field names and data source property / column names comparisons in mail merging are case-insensitive, regardless wheter you use FieldMappings or not.

    So, for example, merge field named fULLnAME will be sucessfully replaced with a value of a data source property / column named FullName.

  • RangeStartPrefix and RangeEndPrefix - if you have already used some other document processing component for mail merge, and that component required that merge fields that represent mail merge range beginning and end start with some prefix other than RangeStart: and RangeEnd:, which are used by default in GemBox.Document, you can continue using those prefixes. You don't need to change your template document, just inform GemBox.Document mail merge engine about new prefixes, by changing these properties.

  • RemoveMergeFields - removes all merge fields or mail merge related fields from the document.

    Note

    Except MergeField field, GemBox.Document mail merge engine also supports following mail merge related fields:

    • Next - used to move to the next record in the data source.

    • MergeRec - used to print the number of the corresponding merged data record.

    • MergeSeq - used to print the number of data records that were successfully merged.

  • GetMergeFieldNames()()()() - used for diagnostics, to retrieve all field names in the document.