# An Ultimate Guide to Mail Merge with MS Word Documents in C#

> The MailMerge class provides very effective ways to merge data into MS Word compatible templates. This updated ultimate guide provides an overview of all the important features and functionalities of the mail merge process.

- **Author:** Bjoern Meyer
- **Published:** 2023-06-07
- **Modified:** 2026-07-17
- **Description:** The MailMerge class provides very effective ways to merge data into MS Word compatible templates. This updated ultimate guide provides an overview of all the important features and functionalities of the mail merge process.
- **9 min read** (1711 words)
- **Tags:**
  - ASP.NET
  - Mail Merge
  - Windows Forms
  - WPF
- **Web URL:** https://www.textcontrol.com/blog/2023/06/07/an-ultimate-guide-to-mail-merge-with-ms-word-documents-in-csharp/
- **LLMs URL:** https://www.textcontrol.com/blog/2023/06/07/an-ultimate-guide-to-mail-merge-with-ms-word-documents-in-csharp/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2023/06/07/an-ultimate-guide-to-mail-merge-with-ms-word-documents-in-csharp/llms-full.txt

---

The MailMerge class provides effective ways to merge data into merge field placeholders, repeating blocks, form fields, barcodes, images, and chart objects. Based on document templates, this engine handles dynamic document generation.

The MailMerge API is typically used to automate document generation. It's used to create letters, invoices, quotes, and other dynamic documents.

This article provides an overview of the typical functionality of a mail merge and the features and settings that are available.

### What is Mail Merge?

Mail merge describes the process of creating documents based on templates containing static content and variable elements that are merged from different data sources.

- **The template**  
    A template can be any document type that is supported by TX Text Control including DOC, DOCX, RTF and the internal TX Text Control format (TX). The template can contain static text and dynamic merge fields, image placeholders, repeating blocks and other merge elements.
    
    ![Creating documents with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/merge1.webp "Creating documents with TX Text Control")
- **The data source**  
    *MailMerge* provides several methods for merging data into templates. *MailMerge* interprets all public properties of an object as table columns and child tables. The object type is parsed using .NET reflection and used as the basis for the table structure. Nested object types are used for merge blocks and prefixed merge fields. Supported data types are:
    
    
    - DataSet
    - DataTable
    - JSON
    - XML
    - IEnumerable objects

### Mail Merge Process

In three simple steps, TX Text Control effortlessly merges data into MS Word compatible templates.

- Loading a template
- Merging with data
- Exporting the document

The MailMerge class merges the data from different data sources into documents. It can be connected to any Text Control (TXTextControl.ServerTextControl, TXTextControl.TextControl and TXTextControl.WPF.TextControl. The document that is loaded into the connected *Text Control* is automatically used as the mail merge template.

The following code shows how to create a *Mailmerge* instance and how to connect it to a *ServerTextControl*:

```
using (MailMerge mailMerge = new MailMerge()) {
  mailMerge.TextComponent = textControl1;
}
```

The next code snippet loads an Office Open XML (DOCX) template into a new *ServerTextControl* instance that is then connected to *MailMerge*:

```
TXTextControl.LoadSettings ls = new TXTextControl.LoadSettings() {
  ApplicationFieldFormat = TXTextControl.ApplicationFieldFormat.MSWord,
  LoadSubTextParts = true };

using (TXTextControl.ServerTextControl serverTextControl =
       new TXTextControl.ServerTextControl()) {
  serverTextControl.Create();
  serverTextControl.Load("template.docx", TXTextControl.StreamType.WordprocessingML, ls);

  using (MailMerge mailMerge = new MailMerge()) {
    mailMerge.TextComponent = serverTextControl;
  }
}
```

The template can be any MS Word document with merge fields that can be added using the predefined *Reporting* ribbon tab of the TX Text Control visual editor or using MS Word. The sample template is shown in the next screenshot:

![Creating documents with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/merge1.webp "Creating documents with TX Text Control")

### Merging with Data

For the sake of simplicity, the following JSON string will be used as the data source:

```
[
  {
    "company_name": "Text Control, LLC",
    "address":
    {
      "street": "1111 Text Control Way",
      "zip": "28226",
      "city": "Charlotte",
      "country": "United States"
    }
  }
]
```

In the next snippet of code, we use the MergeJsonData method to merge the template with the JSON data that we provide.

```
// enable MS Word merge fields
TXTextControl.LoadSettings ls = new TXTextControl.LoadSettings() {
  ApplicationFieldFormat = TXTextControl.ApplicationFieldFormat.MSWord };

// load JSON data
string jsonData = System.IO.File.ReadAllText("data.json");

// create a temporary ServerTextControl
using (TXTextControl.ServerTextControl serverTextControl = 
       new TXTextControl.ServerTextControl()) {
  serverTextControl.Create();
  
  // load the template
  serverTextControl.Load("template.docx", TXTextControl.StreamType.WordprocessingML, ls);

  // create the mail merge engine
  using (MailMerge mailMerge = new MailMerge()) {
    // connect to ServerTextControl
    mailMerge.TextComponent = serverTextControl;
    // merge data into template
    mailMerge.MergeJsonData(jsonData);
  }
}
```

The resulting document is shown in the screenshot:

![Creating documents with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/merge2.webp "Creating documents with TX Text Control")

### Exporting the Document

After a successful merge process, the resulting document is loaded into the connected *Text Control* instance and can be exported to any supported document format. The following code shows how the resulting document is getting exported as an Adobe PDF document.

```
TXTextControl.LoadSettings ls = new TXTextControl.LoadSettings() {
  ApplicationFieldFormat = TXTextControl.ApplicationFieldFormat.MSWord };

string jsonData = System.IO.File.ReadAllText("data.json");

using (TXTextControl.ServerTextControl serverTextControl =
       new TXTextControl.ServerTextControl()) {
  serverTextControl.Create();
  serverTextControl.Load("template.docx", TXTextControl.StreamType.WordprocessingML, ls);

  using (MailMerge mailMerge = new MailMerge()) {
    mailMerge.TextComponent = serverTextControl;
    mailMerge.MergeJsonData(jsonData);
  }

  // export document as PDF
  serverTextControl.Save("results.pdf", TXTextControl.StreamType.AdobePDF);
}
```

### Data Structures

This chapter explains the data structure using a sample JSON object that contains hierarchical data and allows you to demonstrate various mail merge features, including accessing data from child tables and nested, repeating merge blocks:

```
[
  {
    "company_name": "Text Control, LLC",
    "address":
    {
      "street": "1111 Text Control Way",
      "zip": "28226",
      "city": "Charlotte",
      "country": "United States"
    },
    "contacts": [
      {
        "name": "Tim Typer",
        "email": "tim@textcontrol.com"
      },
      {
        "name": "Karl Keyboard",
        "email": "karl@textcontrol.com"
      },
      {
        "name": "Petra Paragraph",
        "email": "petra@textcontrol.com"
      }
    ],
    "orders": [
      {
        "id": 123,
        "articles": [
          {
            "id": 1,
            "product": {
              "name": "Product A",
              "description": "Description of product A",
              "price": 200
            },
            "qty": 5,
            "discount": 0.2
          },
          {
            "id": 2,
            "product": {
              "name": "Product B",
              "description": "Description of product B",
              "price": 244
            },
            "qty": 50,
            "discount": 0.0
          },
          {
            "id": 3,
            "product": {
              "name": "Product C",
              "description": "Description of product C",
              "price": 677
            },
            "qty": 2,
            "discount": 0.5
          }
        ]
      },
      {
        "id": 321,
        "articles": [
          {
            "id": 1,
            "product": {
              "name": "Product B",
              "description": "Description of product B",
              "price": 123
            },
            "qty": 12,
            "discount": 0.0
          },
          {
            "id": 2,
            "product": {
              "name": "Product D",
              "description": "Description of product D",
              "price": 556
            },
            "qty": 2,
            "discount": 0.7
          },
          {
            "id": 3,
            "product": {
              "name": "Product C",
              "description": "Description of product C",
              "price": 677
            },
            "qty": 20,
            "discount": 0.3
          }
        ]
      }
    ]
  }
]
```

Internally, the hierarchical structure is converted to tables. The following diagram shows these tables and their child tables:

![Sample data](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/classes.webp "Sample data")

### The Sample Template

The [sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/sample.zip) used in this article is very simple, containing static data, simple merge fields, and a nested repeating block. The merge block lists all the "orders" from the sample data:

![Sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/template.webp "Sample template")

First, let us look at the address part of the template. This part uses three tables that are accessed in different ways.

![Sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/structure_header.webp "Sample template")

### Accessing Child Tables

*company\_name* comes directly from the root table, while the address comes from a child table. These fields can be accessed using dot notation. For example, to access the street, the merge field name is *address.street*.

The *Contacts* part contains a merge block (shown in red below) to list all contacts. A merge block repeats all elements that are part of the block based on the data for that block. In this case, the block includes a soft break and the tab character so that all contacts are listed at the same indent position:

![Sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/block.webp "Sample template")

The following animation shows the header section before the merge process and after the merge process:

![Sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/header_animation.webp "Sample template")

### Repeating Blocks

The detail section lists all orders and their articles. Therefore, two nested merge blocks are inserted. The outer block repeats the *orders* objects and the inner block lists all *articles*:

![Sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/details.webp "Sample template")

As can be seen in the following animation, the outer block is getting repeated 2 times based on the actual data in the given JSON. The inner table row is defined as the nested block *articles* and contains all line items:

![Sample template](https://s1-www.textcontrol.com/assets/dist/blog/2023/06/07/a/assets/details_animation.webp "Sample template")

### Mail Merge Article Collection

In addition, *MailMerge* provides several events and settings that can be used to implement complex reporting scenarios. The following list contains detailed articles on specific mail merge features and most typical applications.

### Conditional Data Shaping

> **Conditional Data Shaping in Merge Blocks**
> 
> Rows of data in merge blocks can be sorted, filtered, and rendered conditionally. This example shows how to set the required JSON data on a merge block to conditionally render child blocks.
> 
> [Read article ](https://www.textcontrol.com/blog/2023/05/03/mail-merge-conditional-data-shaping-in-merge-blocks/llms-full.txt)

### Field Mapping

> **MailMerge: Field Mapping and Handling of Unmerged Fields**
> 
> Text Control's MailMerge API maps merge fields in templates with columns in supported data sources. This article explains the structure and how to handle unmerged fields.
> 
> [Read article ](https://www.textcontrol.com/blog/2022/05/04/mailmerge-field-mapping-and-handling-of-unmerged-fields/llms-full.txt)

### Conditional Table Rows

> **MailMerge: Field Mapping and Handling of Unmerged Fields**
> 
> The MailMerge class supports repeating merge blocks that are repeated based on the given data rows. Sub-blocks can be rendered conditionally based on value comparisons of the parent data table. This article shows how to add such a condition.
> 
> [Read article ](https://www.textcontrol.com/blog/2022/02/17/mailmerge-rendering-conditional-table-rows/llms-full.txt)

### Form Fields

> **Merging Form Fields using the MailMerge Class**
> 
> Usually, the MailMerge class is used to merge data into document templates to replace merge fields. Since version 30.0, it is possible to merge data into form fields.
> 
> [Read article ](https://www.textcontrol.com/blog/2022/02/21/merging-form-fields-using-the-mailmerge-class/llms-full.txt)

### Merging Charts

> **Using MailMerge with Chart Objects and JSON Data**
> 
> This article explains how to merge JSON data into chart objects using the MailMerge class.
> 
> [Read article ](https://www.textcontrol.com/blog/2022/02/21/merging-form-fields-using-the-mailmerge-class/llms-full.txt)

### Conditional Formatting

> **Implementing Conditional Table Cell Colors with MailMerge**
> 
> The MailMerge class provides an extensible framework to inject custom logic to the merge process. This ASP.NET MVC sample shows how to implement conditional table cell colors using the online document editor and an ASP.NET backend.
> 
> [Read article ](https://www.textcontrol.com/blog/2020/10/08/implementing-conditional-table-cell-colors-with-mailmerge/llms-full.txt)

### String Formatter

> **Format Numeric String Values with MailMerge**
> 
> Numeric format strings are used to format common numeric types. This article gives an overview of supported format strings and how to apply them to merge fields.
> 
> [Read article ](https://www.textcontrol.com/blog/2020/10/22/format-numeric-string-values-with-mailmerge/llms-full.txt)

### Merge Blocks Sorting

> **Adding Sorting and Filter Instructions to Existing MergeBlocks**
> 
> Merge blocks can be filtered and sorted with linked instructions that help to shape the used data in each merge block. This article shows how to add sorting and filter instructions to existing merge blocks.
> 
> [Read article ](https://www.textcontrol.com/blog/2021/07/16/adding-sorting-and-filter-instructions-to-existing-mergeblocks/llms-full.txt)

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [Mail Merge with MS Word Documents in C# - An Ultimate Guide](https://www.textcontrol.com/blog/2022/05/25/mail-merge-with-ms-word-documents-in-csharp-an-ultimate-guide/llms.txt)
- [Combining MailMerge and Table of Contents](https://www.textcontrol.com/blog/2022/03/22/combining-mailmerge-and-table-of-contents/llms.txt)
- [Merging Form Fields using the MailMerge Class](https://www.textcontrol.com/blog/2022/02/21/merging-form-fields-using-the-mailmerge-class/llms.txt)
- [MailMerge: Rendering Conditional Table Rows](https://www.textcontrol.com/blog/2022/02/17/mailmerge-rendering-conditional-table-rows/llms.txt)
- [MailMerge: Conditional Table Cell Colors using Filter Instructions](https://www.textcontrol.com/blog/2019/06/06/mailmerge-conditional-table-cell-colors-using-filter-instructions/llms.txt)
- [MailMerge: Using Filters to Remove Unwanted Rows](https://www.textcontrol.com/blog/2019/06/04/mailmerge-using-filters-to-remove-unwanted-rows/llms.txt)
- [Different Ways to Create Documents using Text Control Products](https://www.textcontrol.com/blog/2017/10/17/ways-to-create-documents-using-text-control-products/llms.txt)
- [TX Text Control 34.0 SP4 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/05/20/tx-text-control-34-0-sp4-is-now-available/llms.txt)
- [TXTextControl.Markdown.Core 34.1.0-beta: Work with Full Documents, Selection, and SubTextParts](https://www.textcontrol.com/blog/2026/04/14/txtextcontrol-markdown-core-34-1-0-beta-work-with-full-documents-selection-and-subtextparts/llms.txt)
- [TX Spell .NET 11.0 SP1 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/04/08/tx-spell-net-11-0-sp1-is-now-available/llms.txt)
- [TX Text Control 34.0 SP2 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/02/18/tx-text-control-34-0-sp2-is-now-available/llms.txt)
- [TX Text Control 34.0 SP1 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/12/03/tx-text-control-34-0-sp1-is-now-available/llms.txt)
- [Introducing TX Text Control 34.0: Your Next Leap in Document Processing](https://www.textcontrol.com/blog/2025/11/10/introducing-tx-text-control-34-0-your-next-leap-in-document-processing/llms.txt)
- [Sneak Peek: TX Text Control 34.0 Coming November 2025](https://www.textcontrol.com/blog/2025/10/02/sneak-peek-tx-text-control-34-0-coming-november-2025/llms.txt)
- [TX Text Control 33.0 SP3 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/08/14/tx-text-control-33-0-sp3-is-now-available/llms.txt)
- [TX Text Control 33.0 SP2 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/06/18/tx-text-control-33-0-sp2-is-now-available/llms.txt)
- [Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format](https://www.textcontrol.com/blog/2025/05/16/document-lifecycle-optimization-leveraging-tx-text-controls-internal-format/llms.txt)
- [Expert Implementation Services for Legacy System Modernization](https://www.textcontrol.com/blog/2025/05/07/expert-implementation-services-for-legacy-system-modernization/llms.txt)
- [Service Pack Releases: What's New in TX Text Control 33.0 SP1 and 32.0 SP5](https://www.textcontrol.com/blog/2025/05/07/service-pack-releases-whats-new-in-tx-text-control-33-0-sp1-and-32-0-sp5/llms.txt)
- [Top 5 Real-World Applications for TX Text Control Document Processing Libraries](https://www.textcontrol.com/blog/2025/04/01/top-5-real-world-applications-for-tx-text-control-document-processing-libraries/llms.txt)
- [DWX Developer Week Moves to Mannheim - And Text Control Is on Board!](https://www.textcontrol.com/blog/2025/03/19/dwx-developer-week-moves-to-mannheim-and-tx-text-control-is-on-board/llms.txt)
- [The Wait is Over: TX Text Control for Linux is Officially Here](https://www.textcontrol.com/blog/2025/03/12/the-wait-is-over-tx-text-control-for-linux-is-officially-here/llms.txt)
- [Full .NET 9 Support in Text Control .NET Components for ASP.NET Core, Windows Forms, and WPF](https://www.textcontrol.com/blog/2024/11/11/full-net-9-support-in-text-control-net-components-for-asp-net-core-windows-forms-and-wpf/llms.txt)
- [Toggle Field Codes in TX Text Control](https://www.textcontrol.com/blog/2024/11/07/toggle-field-codes-in-tx-text-control/llms.txt)
- [TX Text Control 32.0 Service Pack 4 Released](https://www.textcontrol.com/blog/2024/09/02/tx-text-control-32-0-service-pack-4-released/llms.txt)
