# Overview

> How MailMerge works in Windows Forms: pre-shaped data, merging in the TextControl or a ServerTextControl, one PDF per record, LoadTemplate and Print.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Mail Merge and Reporting > Overview
- **4056 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/overview/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/overview/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/overview/llms-full.txt

---

Reporting in TX Text Control .NET for Windows Forms joins a word processor and a merge engine in one form: users design a template in the `TextControl` with the **Reporting** ribbon tab, and the `MailMerge` component fills it with data, either in the visible editor or in the background. The concepts below apply to every template, whatever the data: how the layout grows with the data, how the data is shaped, where the merge runs and how many documents it produces.

The [Mail Merge](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/mail-merge/llms-full.txt) tutorials in Getting Started build a first invoice template and merge it, and the [MailMerge](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/overview/components/mailmerge/llms-full.txt) page of the Overview introduces the component. The examples here use the same files: the template *invoice.docx* and the data *invoice.json* with the fields `Company`, `Name` and `InvoiceNumber` and the list `Items`.

### The Reporting Model

A template is an ordinary document. There are no fixed report bands: users design it with the features of a word processor, such as tables, page columns, images and headers and footers, and the placeholders keep the formatting they are given.

- **The text flows.** When merged content makes a table or a paragraph longer, the lines and pages break again, and the table continues on the next page.
- **Templates hold names, not connections.** A template contains the names of merge fields and merge blocks. The data comes from your code or, for databases, from a separate [data source configuration file](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/data-sources/configuration-files/llms-full.txt), so one template works with any data of the same structure.
- **Merge fields keep their formatting.** The font, size and color of a field in the template are those of the merged value.

The following picture shows an invoice merged from such a template in the TX Words *Reporting* sample: the table of items has grown by one row per product.

![A merged invoice in TX Words with a table of six products, their quantities, prices and images](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/merged-invoice-result.cb2fb699.webp)

### Pre-Shaped Data

`MailMerge` doesn't query a database while it merges data that your code passes. You prepare the data in the hierarchy the document needs and pass it to a merge method; Text Control calls this *pre-shaped data*. The data can come from any number of sources, as long as your code brings it into this shape first. The one exception is a [data source configuration file](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/data-sources/configuration-files/llms-full.txt): with it, `Merge()` connects to the database the file names and reads the master table and its related tables itself.

Internally, the hierarchy becomes tables:

| In the data | In the template |
|---|---|
| A property of the root object, a column of the master table | A merge field of the same name, such as `Company` |
| A nested object, a related table with one row | A merge field with dot notation, such as `Customer.City` |
| An array, a collection or a related table | A merge block of the same name, such as `Items`, repeated for each record |

The records you pass form the *master table*. The template is merged once for each record, so an array of 100 invoices creates 100 invoices. [Data Sources](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/data-sources/llms-full.txt) lists the kinds of data `MailMerge` accepts.

### Where the Merge Runs

`MailMerge` holds no document. Its [TextComponent](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/textcomponent-property/llms-full.txt) property connects it to the control that holds the template and, after the merge, the result:

| Connected to | The template is | The result |
|---|---|---|
| The `TextControl` of the form | The document in the editor | Replaces the template in the editor, where the user sees it |
| A `ServerTextControl` | Loaded by your code, not visible | Stays in the `ServerTextControl` until your code saves or shows it |

Merging in the editor is the natural choice for a preview or for a user who edits the merged letter. Merging in a [ServerTextControl](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/servertextcontrol/llms-full.txt) leaves the template in the editor untouched and suits batches of documents.

In the Windows Forms designer, `MailMerge` is a component of the **TX Text Control 34.0** toolbox tab. Dropped on a form, it appears in the component tray below the form:

![The Visual Studio designer with a TextControl on Form1, the Toolbox open at the TX Text Control components and mailMerge1 in the component tray](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/mailmerge-component-tray.19bb508a.webp)

Select the component and choose the `TextControl` in the drop-down of its `TextComponent` property in the **Properties** window:

![The Properties window of mailMerge1 with the TextComponent drop-down open and textControl1 selected](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/mailmerge-properties.b4ee21da.webp)

The page size and margins of the `TextControl` or `ServerTextControl` connected through `TextComponent` are used for the merged document. Set [UseTemplateFormat](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/usetemplateformat-property/llms-full.txt) to `true` to keep those of the template instead; the default is `false`.

### What a Merge Processes

A merge fills more than merge fields:

| Element | What happens | Described in |
|---|---|---|
| `MERGEFIELD` fields | Replaced with the value of the same name | [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/llms-full.txt) |
| `DATE` fields | Filled with the current date in the field's format | [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/llms-full.txt) |
| `IF` fields | Insert one of two texts, depending on a comparison with the data | [Conditional Content](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/conditional-content/llms-full.txt) |
| `NEXT` and `NEXTIF` fields | Continue with the next record in the same document, always or on a condition, for example on a sheet of labels | [NEXT and NEXTIF Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/content-controls/#next-and-nextif-fields), the blog article [Sneak Peek Reporting X10: Creating Labels with NEXT Fields](https://www.textcontrol.com/blog/2013/09/17/sneak-peek-reporting-x10-creating-labels-with-next-fields/) |
| `INCLUDETEXT` fields | Replaced with another document, a subtemplate | [Subtemplates](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/subtemplates/llms-full.txt) |
| Merge blocks | Repeated for each record of a list, also nested | [Merge Blocks](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/blocks/llms-full.txt), [Nested Blocks and Master-Detail Reports](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/nested-blocks/llms-full.txt) |
| Image and barcode placeholders | Filled with an image or encode a value | [Images and Barcodes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/images-barcodes/llms-full.txt) |
| Form fields | Left alone, preselected or replaced, depending on `FormFieldMergeType` | [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/#merge-form-fields) |

Fields in headers and footers are merged as well.

### Create One Document or One per Record

[MergeJsonData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/mergejsondata-method/llms-full.txt), [MergeObjects](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/mergeobjects-method/llms-full.txt) and [Merge](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/merge-method/llms-full.txt) have a second parameter, `append`. With `true`, the default, all records are merged into one document. With `false`, each record becomes a document of its own, and the connected control holds only the last one when the merge ends.

To keep every document, handle the [DataRowMerged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/datarowmerged-event/llms-full.txt) event: its [MergedRow](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge-datarowmergedeventargs/mergedrow-property/llms-full.txt) property holds the document of the record in the internal TX Text Control format. The following `Click` handler of a button named `splitButton` saves one PDF per invoice of *invoice.json*:

```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using TXTextControl;
using TXTextControl.DocumentServer;
```

```csharp
private void splitButton_Click(object sender, EventArgs e)
{
    List<byte[]> documents = new List<byte[]>();

    using (ServerTextControl tx = new ServerTextControl())
    {
        tx.Create();

        LoadSettings loadSettings = new LoadSettings
        {
            ApplicationFieldFormat = ApplicationFieldFormat.MSWord,
            LoadSubTextParts = true
        };

        tx.Load("invoice.docx", StreamType.WordprocessingML, loadSettings);

        using (MailMerge mailMerge = new MailMerge { TextComponent = tx })
        {
            // Collect the document of each record
            mailMerge.DataRowMerged += (s, args) => documents.Add(args.MergedRow);

            // false: a separate document for each record
            mailMerge.MergeJsonData(File.ReadAllText("invoice.json"), false);
        }
    }

    for (int i = 0; i < documents.Count; i++)
    {
        using (ServerTextControl document = new ServerTextControl())
        {
            document.Create();
            document.Load(documents[i], BinaryStreamType.InternalUnicodeFormat);
            document.Save($"invoice-{i + 1}.pdf", StreamType.AdobePDF);
        }
    }

    MessageBox.Show(this, $"{documents.Count} invoices created");
}
```

The code works as follows:

- The `LoadSettings` import the MS Word fields and the merge blocks of the DOCX template, as in [Merge Data into Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/mail-merge/fields/llms-full.txt).
- `DataRowMerged` occurs once per record, and the handler keeps each byte array.
- Each byte array is loaded into a new `ServerTextControl` and saved as *invoice-1.pdf*, *invoice-2.pdf* and so on.

*invoice.json* holds one invoice, so the handler creates one PDF. Add a second object with the same properties to its array to see a second file.

### Load, Save and Print With MailMerge

`MailMerge` can also load the template and save or print the result itself. The following handler merges *invoice.docx* in a `ServerTextControl`, saves the result as PDF and prints it on the printer the user chooses:

```csharp
using System;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using TXTextControl;
using TXTextControl.DocumentServer;
```

```csharp
private void printButton_Click(object sender, EventArgs e)
{
    using (ServerTextControl tx = new ServerTextControl())
    {
        tx.Create();

        using (MailMerge mailMerge = new MailMerge { TextComponent = tx })
        {
            if (!mailMerge.LoadTemplate("invoice.docx", FileFormat.WordprocessingML))
            {
                MessageBox.Show(this, "The template could not be loaded.");
                return;
            }

            mailMerge.MergeJsonData(File.ReadAllText("invoice.json"));
            mailMerge.SaveDocument("invoice.pdf", StreamType.AdobePDF, new SaveSettings());

            // Let the user choose the printer
            using (PrintDialog printDialog = new PrintDialog { Document = new PrintDocument() })
            {
                if (printDialog.ShowDialog(this) == DialogResult.OK)
                {
                    mailMerge.Print(printDialog.Document);
                }
            }
        }
    }
}
```

- [LoadTemplate](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/loadtemplate-method/llms-full.txt) returns `false` when the template can't be loaded. Its format is a value of [FileFormat](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/fileformat/enumeration/llms-full.txt): `MSWord`, `RichTextFormat`, `WordprocessingML` or `InternalUnicodeFormat`. [LoadTemplateFromMemory](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/loadtemplatefrommemory-method/llms-full.txt) loads a template from memory, and the [TemplateFile](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/templatefile-property/llms-full.txt) property, which you can also set in the **Properties** window, names a file whose format is deduced from its extension.
- [SaveDocument](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/savedocument-method/llms-full.txt) saves the merged document to a file, and [SaveDocumentToMemory](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/savedocumenttomemory-method/llms-full.txt) to a byte array or a string.
- [Print](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/print-method/llms-full.txt) prints the merged document with the settings of a `PrintDocument`, such as the printer, the page range and the number of copies. A second overload takes the document name, the printer name, the number of copies and whether to collate.

`LoadTemplate` takes no `LoadSettings`. To decide how the fields and blocks of a DOCX template are imported, load it with `Load` and `LoadSettings`, as in the previous example.

### Follow the Merge With Events

`MailMerge` raises events while it merges, for example [FieldMerged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/fieldmerged-event/llms-full.txt) for each field, [BlockRowMerged](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/blockrowmerged-event/llms-full.txt) for each row of a merge block and `DataRowMerged` for each record. Your handlers can check the data, change the merged content or collect the results. [Merge Events](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/events/llms-full.txt) describes them all.

### Next Steps

- [Data Sources](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/data-sources/llms-full.txt): JSON, business objects, DataSets and configuration files.
- [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/fields/llms-full.txt): formats, date fields, fields without data and form fields.
- [Merge Blocks](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/blocks/llms-full.txt): repeat parts of a template for each record of a list.
- [Reporting Ribbon and Dialog Boxes](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/ribbon-dialogs/llms-full.txt): the Reporting tab your users design templates with.
- [Template Preview](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/template-preview/llms-full.txt): show users the merged result while they design.

---

## Nearby

- **Previous:** [Mail Merge and Reporting](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/llms-full.txt)
- **Next:** [Data Sources](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/data-sources/llms-full.txt)
