Products Technologies Demo Docs Blog Support Company

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.

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

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

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

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

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

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.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

Related Posts

ASP.NETASP.NET CoreDOCX

Use MailMerge in .NET on Linux to Generate Pixel-Perfect PDFs from DOCX…

This article explores how to use the TX Text Control MailMerge feature in .NET applications on Linux to generate pixel-perfect PDFs from DOCX templates. This powerful combination enables…


ASP.NETASP.NET CoreContract

Generating Dynamic NDAs Using TX Text Control MailMerge in C# .NET

This article demonstrates how to generate dynamic NDAs using TX Text Control MailMerge in C# .NET. It covers the process of creating a template, binding data, and generating the final document.


ASP.NETASP.NET CoreBackend

Designing a Maintainable PDF Generation Web API in ASP.NET Core (Linux) C#…

This article shows how to create a PDF generation Web API in ASP.NET Core on Linux using TX Text Control .NET Server. The clean architecture is used to create a maintainable and testable solution.


ASP.NETASP.NET CoreMailMerge

When to Generate Documents Server-Side Instead of Client-Side: A Focus on…

When it comes to document generation, deciding whether to handle the task server-side or client-side is a key architectural decision for any organization. This article discusses the benefits of…


ASP.NETASP.NET CoreMailMerge

Mail Merge: Inserting Merge Blocks using the DataSourceManager in C#

This article shows how to insert merge blocks into a document using the DataSourceManager class in C#. Merge blocks are used to repeat a block of content for each data record in a data source. The…