IRONSOFTWAREHOME

How to Mail Merge Word Documents in C#

Curtis Chau
Curtis Chau
Updated: July 21, 2026

IronWord performs mail merge in C# by populating MERGEFIELD placeholders in a Word template with your data, drawn from dictionaries, DataTable/DataRow/DataSet objects, or repeating-region tables, all without Microsoft Office Interop. Merge fields created in Microsoft Word, or any compatible tool, are detected automatically.

Mail merge is the standard way to generate personalized documents at scale: form letters, invoices, certificates, contracts, and reports that share one template but differ per recipient. Instead of editing each document by hand, you author a single .docx template with merge fields and let IronWord fill them from your data source. Every operation is reached through the WordDocument.MailMerge entry point.

Quickstart: Mail Merge a Word Document

Load a template that contains MERGEFIELD placeholders, pass a dictionary of field names and values to Execute, and save the result.

  1. 1Install IronWord with NuGet Package Manager

    PM > Install-Package IronWord

  2. 2Copy and run this code snippet.

    WordDocument doc = new WordDocument("template.docx");
    doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" }, { "Company", "Acme Corp" } });
    doc.SaveAs("output.docx");
    C#
  3. 3Deploy to test on your live environment

    Start using IronWord in your project today with a free trial
    arrow pointer

How Do I Mail Merge from a Dictionary?

The simplest data source is an IDictionary<string, string> keyed by merge-field name. Execute replaces every field whose name matches a key.

using IronWord;
using System.Collections.Generic;

// Load a template containing MERGEFIELD placeholders
WordDocument doc = new WordDocument("template.docx");

// Replace each field whose name matches a dictionary key
doc.MailMerge.Execute(new Dictionary<string, string>
{
    { "FirstName", "Jane" },
    { "LastName",  "Smith" },
    { "Company",   "Acme Corp" }
});

doc.SaveAs("output.docx");
C#
Tips: Field-name lookups are case-insensitive by default, matching Microsoft Word. Set MailMerge.Options.CaseInsensitiveFieldNames = false to require an exact-case match.

You can also supply two parallel sequences of field names and values:

using IronWord;

WordDocument doc = new WordDocument("template.docx");

// Merge from two parallel sequences of field names and values
doc.MailMerge.Execute(
    new[] { "FirstName", "LastName" },
    new[] { "Jane", "Smith" });

doc.SaveAs("output.docx");
C#
Warning: Execute(fieldNames, values) throws an ArgumentException when the two sequences have different lengths.

How Do I Mail Merge from a DataTable or DataRow?

When data comes from a database or an existing DataSet, pass a DataTable or DataRow straight to Execute. Merge-field names are matched to column names. Execute(DataTable) uses the values from the table's first row, while Execute(DataRow) uses the column names of the row's parent table.

using IronWord;
using System.Data;

// Build a DataTable, for example from a database query
DataTable table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "Jane";
row["LastName"]  = "Smith";
table.Rows.Add(row);

WordDocument doc = new WordDocument("template.docx");

// Merge-field names are matched to the row's column names
doc.MailMerge.Execute(row);

doc.SaveAs("output.docx");
C#

How Do I Fill Repeating Table Regions?

Repeating regions turn one template row into many, which is ideal for invoice line items or order lists. In the template, wrap the repeating content between two marker fields named TableStart:RegionName and TableEnd:RegionName. Then call ExecuteWithRegions, which repeats the region's content once per row of the matching table.

ExecuteWithRegions accepts a full DataSet (expanding every region whose name matches a table), a single DataTable (expanding the region whose name matches dataTable.TableName), or a region name together with a DataTable.

using IronWord;
using System.Collections.Generic;
using System.Data;

// One DataTable per repeating region, named to match the TableStart/TableEnd markers
DataTable orders = new DataTable("Orders");
orders.Columns.Add("Item");
orders.Columns.Add("Qty");
orders.Rows.Add("Widget A", "3");
orders.Rows.Add("Widget B", "1");

DataSet ds = new DataSet();
ds.Tables.Add(orders);

WordDocument doc = new WordDocument("invoice-template.docx");

// Expand the repeating region once per row, then fill standard fields
doc.MailMerge.ExecuteWithRegions(ds);
doc.MailMerge.Execute(new Dictionary<string, string> { { "CustomerName", "Jane Smith" } });

doc.SaveAs("invoice.docx");
C#
Please note: ExecuteWithRegions only populates repeating regions. To also fill standard merge fields outside the regions, call Execute(...) after expanding the regions, as shown above.

How Do I Inspect a Template's Merge Fields?

Before merging, you can discover what a template contains, which is useful for validating templates or building the data source dynamically.

  • GetFieldNames() returns the names of all value-style merge fields, in document order and deduplicated.
  • GetRegionNames() returns the names of all TableStart regions declared in the document.
  • GetFields() returns every field, including TableStart/TableEnd markers, as MergeField objects.
using IronWord;
using System.Collections.Generic;

WordDocument doc = new WordDocument("template.docx");

// Discover the merge fields and regions before merging
IReadOnlyList<string> fieldNames = doc.MailMerge.GetFieldNames();
IReadOnlyList<string> regionNames = doc.MailMerge.GetRegionNames();

// fieldNames:  ["FirstName", "LastName", "Company"]
// regionNames: ["Orders", "LineItems"]
C#

Each MergeField exposes its Name, the full Instruction text as stored in the document (for example MERGEFIELD FirstName \* MERGEFORMAT), a RegionName that is set only for region markers (for example "Orders" from "TableStart:Orders"), and a Kind that classifies the field as Value (text replaced with a data value), TableStart or TableEnd (the bounds of a repeating region), or NextRecord (a NEXT field that advances to the next data record within the same template body).

How Do I Control Unmatched Fields and Null Values?

Merge behavior is configured through MailMerge.Options:

OptionDefaultBehavior
RemoveUnusedFieldstrueRemoves merge fields that have no matching key in the data source. Set to false to leave them in place.
RemoveUnusedRegionstrueRemoves TableStart/TableEnd regions with no matching table in the data source.
NullValueReplacement""Text substituted when the data source supplies a null value for a field.
CaseInsensitiveFieldNamestrueIgnores case when matching field names, matching Microsoft Word behavior.
using IronWord;
using System.Collections.Generic;

WordDocument doc = new WordDocument("template.docx");

// Keep unmatched fields in the output instead of removing them
doc.MailMerge.Options.RemoveUnusedFields = false;
doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" } });

doc.SaveAs("partial-output.docx");
C#

For straightforward value substitution without a data source, see how to replace text in a Word document.

Frequently Asked Questions

What is mail merge in C# using IronWord?

Mail merge in C# with IronWord allows you to populate MERGEFIELD placeholders in Word templates with data from dictionaries, DataTable, DataRow, or DataSet objects, enabling the creation of personalized documents like invoices and reports.

How does IronWord perform mail merge without Microsoft Office?

IronWord enables mail merge without Microsoft Office by loading Word templates and executing the merging through the WordDocument.MailMerge entry point, replacing placeholders with data.

Can I use a dictionary for mail merging with IronWord?

Yes, IronWord allows mail merging using a dictionary by matching field names with dictionary keys in the Execute method.

How can I perform mail merge with a DataTable using IronWord?

You can perform mail merge with a DataTable in IronWord by passing the DataTable to the Execute method, which uses the first row's column names to match merge fields in the template.

What are repeating regions in mail merge, and how are they handled in IronWord?

Repeating regions in mail merge are sections that can expand based on data rows, perfect for items like invoice lines. IronWord handles them through the ExecuteWithRegions method, using TableStart and TableEnd markers in the template.

How can I inspect a template's merge fields using IronWord?

You can use IronWord's GetFieldNames and GetRegionNames methods to inspect merge fields and region names in a template, helping to validate templates or create data sources dynamically.

How does IronWord handle unmatched fields and null values in mail merge?

IronWord offers options such as RemoveUnusedFields, RemoveUnusedRegions, and NullValueReplacement in MailMerge.Options to control the behavior for unmatched fields and null values.

What is the minimal workflow to mail merge a Word document using IronWord?

The minimal workflow involves downloading the IronWord library, authoring a Word template, loading it with WordDocument, executing the merge with your data, and saving the populated document.

How does case sensitivity affect field name matching in IronWord mail merge?

In IronWord, field name lookups in the mail merge are case-insensitive by default, similar to Microsoft Word. You can adjust this behavior using MailMerge.Options.CaseInsensitiveFieldNames.

How does IronWord support mail merging multiple documents or templates?

IronWord allows you to quickly fill multiple documents by reusing the same template with different data or by using the ExecuteWithRegions method for repeating data entries.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...
Read More

Ready to Get Started?

Nuget Downloads 56,401Version:2026.9just released

Get your free 30-day Trial Key instantly.
No credit card or account creation required
C# NuGet Library for PDF
Install with NuGet

Version: 2026.9

PM > Install-Package IronWord
nuget.org/packages/IronWord/
  1. In Solution Explorer, right-click References, Manage NuGet Packages
  2. Select Browse and search "IronWord"
  3. Select the package and install
C# PDF DLL
Download DLL

Version: 2026.9

  1. Download and unzip IronWord to a location such as ~/Libs within your Solution directory
  2. In Visual Studio Solution Explorer, right click References. Select Browse, "IronWord.dll"

Licenses from $999

Key in blue circle

Get your free 30-day Trial Key instantly.

Your trial license will be sent to your email address

No limitations. 100% unlocked. No credit card.

bullet_checkedNo credit card or account creation requiredNo limitations. 100% unlocked. No credit card.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Book your free Live Demo
Booking Badge

Trusted by Millions of Engineers Worldwide

Iron Software's customer logos
Get Your No-Obligation Consult
Complete the form below or email sales@ironsoftware.com
Your details will always be kept confidential.
Trusted by Millions of Engineers Worldwide
Iron Software's customer logos
Get your free 30-day Trial Key instantly.
No credit card or account creation required