# Manipulating Table Cells During the MailMerge Process in .NET C#

> This article shows how to manipulate table cells during the mail merge process in .NET C#. The FieldMerged event can be used to manipulate the table cells after they are merged.

- **Author:** Bjoern Meyer
- **Published:** 2024-12-03
- **Modified:** 2025-11-16
- **Description:** This article shows how to manipulate table cells during the mail merge process in .NET C#. The FieldMerged event can be used to manipulate the table cells after they are merged.
- **6 min read** (1016 words)
- **Tags:**
  - ASP.NET
  - ASP.NET Core
  - Merge Field
  - MailMerge
- **Web URL:** https://www.textcontrol.com/blog/2024/12/03/manipulating-table-cells-during-the-mailmerge-process-in-net-csharp/
- **LLMs URL:** https://www.textcontrol.com/blog/2024/12/03/manipulating-table-cells-during-the-mailmerge-process-in-net-csharp/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2024/12/03/manipulating-table-cells-during-the-mailmerge-process-in-net-csharp/llms-full.txt

---

The MailMerge class in TX Text Control is a robust library designed to automate document creation through the process of merging data into templates. It serves as a bridge between structured data (e.g., from databases, JSON, or XML) and dynamic document generation, making it invaluable for applications that require automated document workflows.

At its core, the MailMerge class simplifies the complex task of creating professional, data-driven documents by allowing developers to easily merge fields in templates with data sources. Templates are designed using the TX Text Control word processing interface, with merge fields representing dynamic content.

### Merge Blocks

Merge blocks are a key concept in TX Text Control's MailMerge class, which allows for the dynamic generation of structured, repeatable content in documents. Merge blocks allow developers to effectively handle repeating data structures such as lists, tables, or nested regions in templates.

At a high level, a merge block is a defined section within a template that corresponds to a collection or table of data. During the merge process, MailMerge iterates through the data source, dynamically creating content for each record. These merge blocks can be conditionally rendered, filtered, and sorted using the out-of-the-box functionality of the MailMerge class.

### Code-Level Manipulation

But the MailMerge class also allows very detailed, code-level manipulation during the merge process. This includes handling merge events, customizing the merge process, and programmatically controlling the output of the merge operation. This level of control is essential for complex document generation scenarios that require fine-grained control over the merge process.

This article describes how to use the FieldMerged event to manipulate a table cell that is returned by the event when the merged field is inside a table cell. For this example, we will use a very simple template consisting of two merge fields and a simple repeating block highlighted in red.

![MailMerge Template in TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2024/12/03/a/assets/template1.webp "MailMerge Template in TX Text Control")

To merge the template, we will use the following simplified JSON data.

```
[
  {
    "invoice-id": "1",
    "invoice-date": "2019-01-01",
    "line-items": [
      {
        "product-id": "1",
        "quantity": "1",
        "unit-price": "8"
      },
      {
        "product-id": "2",
        "quantity": "2",
        "unit-price": "200"
      },
      {
        "product-id": "3",
        "quantity": "1",
        "unit-price": "100"
      },
      {
        "product-id": "4",
        "quantity": "1",
        "unit-price": "3"
      }
    ]
  }
]
```

In order to merge this template, the following code will be used:

```
textControl1.Load("template.tx", TXTextControl.StreamType.InternalUnicodeFormat);

MailMerge mailMerge = new MailMerge();
mailMerge.TextComponent = textControl1;

string jsonData = File.ReadAllText("data.json");
mailMerge.MergeJsonData(jsonData);
```

This results in the following merged document:

![Merged Document in TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2024/12/03/a/assets/template2.webp "Merged Document in TX Text Control")

### FieldMerged Event

Now let's attach the FieldMerged event to manipulate the merge process.

```
textControl1.Load("template.tx", TXTextControl.StreamType.InternalUnicodeFormat);

MailMerge mailMerge = new MailMerge();
mailMerge.TextComponent = textControl1;
mailMerge.FieldMerged += MailMerge_FieldMerged;

string jsonData = File.ReadAllText("data.json");
mailMerge.MergeJsonData(jsonData);
```

Each time a merge field is merged (successfully or not), this event is invoked. A TableCell is returned if the field is located within a table cell.

In this event, we check that the *TableCell* property is not null. If it is not null, we set the background color of the cell.

```
private void MailMerge_FieldMerged(object sender, MailMerge.FieldMergedEventArgs e)
{
   if (e.TableCell != null)
   {
       e.TableCell.CellFormat.BackColor = Color.Red;
       e.TableCell.CellFormat.BottomBorderWidth = 60;
       e.TableCell.CellFormat.BottomBorderColor = Color.Blue;
   }
}
```

As a result, all merged cells are colored during the merge process.

![Merged Document with Colored Cells in TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2024/12/03/a/assets/template3.webp "Merged Document with Colored Cells in TX Text Control")

### Dynamic Cell Colors

Let's make this process dynamic by adding some logic. The *CellFilterInstructions* class is used to compare a value with a given value to return a specific color.

```
using System;
using System.Drawing;
using System.Linq;

public class CellFilterInstructions
{
    public double? CompareValue { get; set; } = null;
    public RelationalOperator? Operator { get; set; } = null;
    public Color TrueColor { get; set; } = Color.White;
    public Color FalseColor { get; set; } = Color.White;

    public enum RelationalOperator
    {
        Equals = 0,
        NotEqual,
        LessThan,
        GreaterThan,
    }

    // evaluates the instruction and returns the proper color
    public Color? GetColor(string value)
    {
        if (Double.TryParse(ParseToNumber(value), out double dValue) == true)
        {
            switch (Operator)
            {
                case RelationalOperator.Equals:
                    return (dValue == CompareValue ? TrueColor : FalseColor);
                case RelationalOperator.NotEqual:
                    return (dValue != CompareValue ? TrueColor : FalseColor);
                case RelationalOperator.GreaterThan:
                    return (dValue > CompareValue ? TrueColor : FalseColor);
                case RelationalOperator.LessThan:
                    return (dValue < CompareValue ? TrueColor : FalseColor);
                default:
                    return null;
            }
        }
        else
            return null;

    }

    private string ParseToNumber(string text)
    {
        var numericChars = "0123456789,.".ToCharArray();
        return new String(text.Where(c => numericChars.Any(n => n == c)).ToArray());
    }
}
```

The following code creates a new rule that returns green if the value is greater than 10 and red if it is not. This rule is serialized and stored in the Name property of a table cell.

```
textControl1.Load("template.tx", TXTextControl.StreamType.InternalUnicodeFormat);

CellFilterInstructions cellFilterInstructions = new CellFilterInstructions() {
    CompareValue = 10,
    Operator = CellFilterInstructions.RelationalOperator.GreaterThan,
    TrueColor = Color.Green,
    FalseColor = Color.Red
};

textControl1.Tables[1].Cells[2,2].Name =
    JsonConvert.SerializeObject(cellFilterInstructions);

MailMerge mailMerge = new MailMerge();
mailMerge.TextComponent = textControl1;
mailMerge.FieldMerged += MailMerge_FieldMerged;

string jsonData = File.ReadAllText("data.json");
mailMerge.MergeJsonData(jsonData);
```

In the *FieldMerged* event, this rule is deserted and evaluated. The color returned is then applied to the TableCellFormat of the table cell.

```
private void MailMerge_FieldMerged(object sender, MailMerge.FieldMergedEventArgs e)
{
    // custom field handling
    if (e.TableCell == null)
        return;

    if (e.TableCell.Name != "")
    {
        CellFilterInstructions instructions =
            (CellFilterInstructions)JsonConvert.DeserializeObject(
                e.TableCell.Name,
                typeof(CellFilterInstructions));

        // retrieve the color
        Color? color = instructions.GetColor(e.MailMergeFieldAdapter.ApplicationField.Text);

        // apply the color
        if (color != null)
            e.TableCell.CellFormat.BackColor = (Color)color;
    }
}
```

The following screenshot shows the result of this merge process:

![Merged Document with Conditional Cell Colors in TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2024/12/03/a/assets/template4.webp "Merged Document with Conditional Cell Colors in TX Text Control")

### Conclusion

The MailMerge class in TX Text Control provides a powerful and flexible solution for automating document generation processes. Using merge blocks and code-level manipulation, developers can easily create dynamic, data-driven documents. The FieldMerged event provides fine-grained control over the merge process, allowing developers to customize output based on specific conditions. This level of control is essential for complex document generation scenarios that require precise handling of data and content.

---

## 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

- [Use MailMerge in .NET on Linux to Generate Pixel-Perfect PDFs from DOCX Templates](https://www.textcontrol.com/blog/2025/05/27/use-mailmerge-in-dotnet-on-linux-to-generate-pixel-perfect-pdfs-from-docx-templates/llms.txt)
- [Generating Dynamic NDAs Using TX Text Control MailMerge in C# .NET](https://www.textcontrol.com/blog/2025/04/08/generating-dynamic-ndas-using-tx-text-control-mailmerge-in-csharp-dotnet/llms.txt)
- [Designing a Maintainable PDF Generation Web API in ASP.NET Core (Linux) C# with Clean Architecture and TX Text Control](https://www.textcontrol.com/blog/2025/03/27/designing-a-maintainable-pdf-generation-web-api-in-asp-net-core-linux-c-sharp-with-clean-architecture-and-tx-text-control/llms.txt)
- [When to Generate Documents Server-Side Instead of Client-Side: A Focus on Data Security](https://www.textcontrol.com/blog/2024/10/04/when-to-generate-documents-server-side-instead-of-client-side-a-focus-on-data-security/llms.txt)
- [Mail Merge: Inserting Merge Blocks using the DataSourceManager in C#](https://www.textcontrol.com/blog/2024/10/02/mail-merge-inserting-merge-blocks-using-the-datasourcemanager-in-csharp/llms.txt)
- [Creating Advanced Tables in PDF and DOCX Documents with C#](https://www.textcontrol.com/blog/2024/09/30/creating-advanced-tables-in-pdf-and-docx-documents-with-csharp/llms.txt)
- [Designing the Perfect Contract Template for MailMerge in C#](https://www.textcontrol.com/blog/2024/09/26/designing-the-perfect-contract-template-for-mailmerge-in-csharp/llms.txt)
- [Video Tutorial: Creating a MailMerge Template and JSON Data Structure](https://www.textcontrol.com/blog/2024/08/16/video-tutorial-creating-a-mailmerge-template-and-json-data-structure/llms.txt)
- [Getting Started Video Tutorial: How to use the MailMerge and ServerTextControl Classes in ASP.NET Core C#](https://www.textcontrol.com/blog/2024/08/05/getting-started-video-tutorial-how-to-use-the-mailmerge-and-servertextcontrol-classes-in-asp-net-core-c/llms.txt)
- [Getting Started Videos: New Text Control YouTube Channel](https://www.textcontrol.com/blog/2024/08/02/getting-started-videos-new-text-control-youtube-channel/llms.txt)
- [Best Practices for Mail Merge and Form Field Processing in ASP.NET Core C# Applications](https://www.textcontrol.com/blog/2024/07/30/best-practices-for-mail-merge-and-form-field-processing-in-asp-net-core-csharp-applications/llms.txt)
- [Advantages of Flow Type Layout Reporting vs. Banded Reporting or PDF Template Engines in .NET C#](https://www.textcontrol.com/blog/2024/07/29/advantages-of-flow-type-layout-reporting-vs-banded-reporting-or-pdf-template-engines-in-net-c-sharp/llms.txt)
- [Designing a MailMerge Web API Endpoint with ASP.NET Core in C#](https://www.textcontrol.com/blog/2024/07/12/designing-a-mailmerge-web-api-endpoint-with-asp-net-core-in-c-sharp/llms.txt)
- [Enhancing Documents with QR Codes and Barcodes in .NET C#: A Comprehensive Guide](https://www.textcontrol.com/blog/2024/07/11/enhancing-documents-with-qr-codes-and-barcodes-in-net-csharp-a-comprehensive-guide/llms.txt)
- [Document Automation 101: Leveraging TX Text Control for Business Efficiency in .NET C# Applications](https://www.textcontrol.com/blog/2024/07/09/document-automation-101-leveraging-tx-text-control-for-business-efficiency-in-net-c-applications/llms.txt)
- [Merging Templates with MailMerge with Different Merge Field Settings in C#](https://www.textcontrol.com/blog/2023/12/16/merging-templates-with-mailmerge-with-different-merge-field-settings/llms.txt)
- [How to Mail Merge MS Word DOCX Documents in ASP.NET Core C#](https://www.textcontrol.com/blog/2023/10/16/how-to-mail-merge-ms-word-docx-documents-in-aspnet-core-csharp/llms.txt)
- [MailMerge: Working with Image Placeholders](https://www.textcontrol.com/blog/2022/12/22/mailmerge-working-with-image-placeholders/llms.txt)
- [Getting Started: ServerTextControl and MailMerge with ASP.NET Core](https://www.textcontrol.com/blog/2022/09/01/getting-started-servertextcontrol-and-mailmerge-with-aspnet-core/llms.txt)
- [Adding SVG Watermarks to Documents](https://www.textcontrol.com/blog/2022/01/28/adding-svg-watermarks-to-documents/llms.txt)
- [Using MailMerge in ASP.NET Core 6 Web Applications](https://www.textcontrol.com/blog/2022/01/27/using-mailmerge-in-aspnet-core-6-web-applications/llms.txt)
- [5 Layout Patterns for Integrating the TX Text Control Document Editor in ASP.NET Core C#](https://www.textcontrol.com/blog/2026/04/09/5-layout-patterns-for-integrating-the-tx-text-control-document-editor-in-aspnet-core-csharp/llms.txt)
- [Extracting Structured Table Data from DOCX Word Documents in C# .NET with Domain-Aware Table Detection](https://www.textcontrol.com/blog/2026/04/03/extracting-structured-table-data-from-docx-word-documents-in-csharp-dotnet-with-domain-aware-table-detection/llms.txt)
- [Introducing Text Control Agent Skills](https://www.textcontrol.com/blog/2026/03/27/introducing-text-control-agent-skills/llms.txt)
- [Deploying the TX Text Control Document Editor from the Private NuGet Feed to Azure App Services (Linux and Windows)](https://www.textcontrol.com/blog/2026/03/25/deploying-the-tx-text-control-document-editor-from-the-private-nuget-feed-to-azure-app-services-linux-and-windows/llms.txt)
