# Styling

> Style merged documents: formatting kept from templates, alternating row colors, cells and text formatted by value, number formats, formulas and page format.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > Mail Merge and Reporting > Styling
- **3183 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/styling/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/styling/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/styling/llms-full.txt

---

In a mail merge, a document gets its look from the template: fonts, colors, table borders and page breaks stay as designed while the data is merged. Formatting that depends on the data, such as alternating row colors or a highlighted amount, comes from rules in the template or from a few lines of code in the events of `MailMerge`.

Number and date formats of merge fields and formatted text from the data are covered in [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/fields/llms-full.txt). The formatting API itself is described in [Text](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/text/llms-full.txt), [Paragraphs](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/paragraphs/llms-full.txt) and [Tables](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/tables/llms-full.txt). Every program merges the invoice data of [Simple Mail Merge](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/mail-merge/simple/llms-full.txt), with the `LineItems` array of [Merge Blocks](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/mail-merge/blocks/#match-the-block-name-to-the-data) added, into a *template.docx* that also has a `LineItems` table.

### What the Merge Keeps

TX Text Control keeps formatting in the template and merges plain values into it:

- **Merge fields** keep their formatting, such as font, size and color. The merged value looks like the field in the template.
- **Merge blocks** are cloned with their formatting and styles for each record, including the paragraph settings. With `PageBreakBefore` set for the first paragraph of a block, each record starts on a new page.
- **IF fields** insert their text with the formatting of the field.
- **Table header rows** are repeated on each page when a merged table continues on the next page.

Design paragraph styles, table formats and page breaks in the template, and keep the data free of formatting. [Template Design](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/template-design/llms-full.txt) collects further advice for templates.

### Alternate Row Colors in the Template

Alternating row colors need no code. Make the merge block two table rows with the same merge fields and different background colors, and put a `NEXT` field at the end of the first row: the field advances to the next record, so the second row shows the following record in its own color. The online demo [Alternating row colors](https://demos.textcontrol.com/demos/server-side-mail-merge/reporting-structures/alternating-rows) shows such a template, and the colors stay editable like any other formatting of the template.

The blog article [Reporting: Removing Empty Table Rows](https://www.textcontrol.com/blog/2014/09/30/reporting-removing-empty-table-rows/) describes how the second row of the last block can stay empty when the number of records is odd, and how to remove it.

### Alternate Row Colors in Code

The [BlockRowMerged](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge/blockrowmerged-event/llms-full.txt) event occurs after each row of a merge block and gives access to the merged row as a document in the TX Text Control format. Load it into a second `ServerTextControl`, change its formatting and assign it back. The following program colors every second row of the `LineItems` block:

```csharp
using TXTextControl;
using TXTextControl.DocumentServer;

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

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

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

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

    int rowCount = 0;

    using (MailMerge mailMerge = new MailMerge { TextComponent = tx })
    {
        mailMerge.BlockRowMerged += (sender, e) =>
        {
            if (e.MergeBlockName != "LineItems")
            {
                return;
            }

            // Color every second row of the block
            rowCount++;

            if (rowCount % 2 != 0)
            {
                return;
            }

            using (ServerTextControl rowText = new ServerTextControl())
            {
                rowText.Create();
                rowText.Load(e.MergedBlockRow, BinaryStreamType.InternalUnicodeFormat);

                foreach (Table table in rowText.Tables)
                {
                    foreach (TableRow row in table.Rows)
                    {
                        TableCellFormat cellFormat = row.CellFormat;
                        cellFormat.BackColor = System.Drawing.Color.LightGray;
                        row.CellFormat = cellFormat;
                    }
                }

                byte[] data;
                rowText.Save(out data, BinaryStreamType.InternalUnicodeFormat);
                e.MergedBlockRow = data;
            }
        };

        mailMerge.MergeJsonData(jsonData);
    }

    tx.Save("alternating-rows.pdf", StreamType.AdobePDF);
}
```

The code works as follows:

- [MergeBlockName](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge-blockrowmergedeventargs/mergeblockname-property/llms-full.txt) tells which block the row belongs to, so other blocks stay unchanged.
- [MergedBlockRow](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge-blockrowmergedeventargs/mergedblockrow-property/llms-full.txt) contains the merged row as a byte array, which `rowText` loads.
- [TableRow.CellFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/tablerow/cellformat-property/llms-full.txt) is read, changed and assigned back, which sets the background color of all cells of the row.
- The changed row is saved and assigned to `MergedBlockRow`, which replaces the merged row in the document.
- The program counts the rows itself; with two line items in the data, the second row is gray.

### Highlight Cells Depending on Their Values

The [FieldMerged](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge/fieldmerged-event/llms-full.txt) event tells you in which table cell a merged field is. With [TableCell](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge-fieldmergedeventargs/tablecell-property/llms-full.txt) and the data of the record, your code formats a cell by its value. The following handler highlights prices above 150:

```csharp
mailMerge.FieldMerged += (sender, e) =>
{
    if (e.TableCell != null &&
        e.MailMergeFieldAdapter is MergeField mergeField &&
        mergeField.Name == "Price" &&
        Convert.ToDouble(e.DataRow["Price"], System.Globalization.CultureInfo.InvariantCulture) > 150)
    {
        TableCellFormat cellFormat = e.TableCell.CellFormat;
        cellFormat.BackColor = System.Drawing.Color.LightYellow;
        e.TableCell.CellFormat = cellFormat;
    }
};
```

`TableCell` is `null` for a field outside a table, and [DataRow](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge-fieldmergedeventargs/datarow-property/llms-full.txt) returns the value of a column of the current record. The handler needs `using TXTextControl.DocumentServer.Fields;` for `MergeField`. The blog article [Manipulating Table Cells During the MailMerge Process in .NET C#](https://www.textcontrol.com/blog/2024/12/03/manipulating-table-cells-during-the-mailmerge-process-in-net-csharp/) formats cells with rules like this.

### Color the Text of a Merged Field

To format the merged text of a field rather than its cell, replace the field's content in `FieldMerged`. [MergedField](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge-fieldmergedeventargs/mergedfield-property/llms-full.txt) contains the merged field with its formatting in the TX Text Control format. The following handler shows the amount due in red:

```csharp
mailMerge.FieldMerged += (sender, e) =>
{
    if (e.Merged && e.MailMergeFieldAdapter is MergeField mergeField && mergeField.Name == "AmountDue")
    {
        using (ServerTextControl fieldText = new ServerTextControl())
        {
            fieldText.Create();
            fieldText.Load(e.MergedField, BinaryStreamType.InternalUnicodeFormat);

            // Keep the text, remove the field, and color the text
            fieldText.ApplicationFields.Clear(true);
            fieldText.SelectAll();
            fieldText.Selection.ForeColor = System.Drawing.Color.Red;

            byte[] data;
            fieldText.Save(out data, BinaryStreamType.InternalUnicodeFormat);
            e.MergedField = data;
        }
    }
};
```

The font and size of the field in the template stay, because the merged field is loaded with its formatting. For negative numbers, a number format with sections, such as `#,##0.00;(#,##0.00)`, shows them in brackets without any code, as [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/fields/#format-numbers-and-dates) describes.

### Number Formats and Formulas in Merged Tables

Table cells have number formats of their own. [TableCellFormat.NumberFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/tablecellformat/numberformat-property/llms-full.txt) set on a cell in the template formats the numbers in that cell, including the values of merge fields in it.

Cells can also calculate values with formulas. In an invoice template, the line items come from the data, while formula cells calculate the line totals, the subtotal and the total from the merged values. The online demo [Mail Merge and Formulas](https://demos.textcontrol.com/demos/rich-text-editor/mail-merge-formulas) merges such a template, and [Tables](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/tables/#calculate-with-formulas) in Document Processing describes formulas and number formats.

### Page Format of the Merged Document

[MailMerge.UseTemplateFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge/usetemplateformat-property/llms-full.txt) decides whether the page size and margins of the template are used. The default is `false`, in which case the `PageSize`, `PageMargins` and `Landscape` properties of the `ServerTextControl` in [TextComponent](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge/textcomponent-property/llms-full.txt) are used.

### Next Steps

- [Merge Fields](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/fields/llms-full.txt): number and date formats and formatted text.
- [Template Design](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/template-design/llms-full.txt): design templates that look right with any data.
- [Tables](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/tables/llms-full.txt) in Document Processing: format tables and cells in code.

---

## Nearby

- **Previous:** [Sorting and Filtering](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/sorting-filtering/llms-full.txt)
- **Next:** [Template Design](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/template-design/llms-full.txt)
