Merge Data Into Fields
With a template and data in place, MailMerge replaces every merge field with the value of the same name and produces the finished document. Here the invoice template from Create a Template is merged with invoice.json, the result is shown in the editor and saved as PDF, and your code finds out which fields received no data.
Prerequisites
- The application from Create a Template, with the template invoice.docx and the data invoice.json in the output folder.
- A
ButtonnamedmergeButtonon the form. Double-click it in the designer to create itsClickhandler.
Add these using directives to Form1.cs:
using System.Collections.Generic;
using TXTextControl.DocumentServer;
How a Merge Works
MailMerge holds no document itself. Its TextComponent property connects it to a ServerTextControl or a TextControl that contains the template. A merge method replaces the merge fields with the data, and afterward the connected component contains the merged document.
In this tutorial, the merge runs in a ServerTextControl, so that the template in the editor is not touched. The merged document is then shown in the editor.
Merge the Data
private void mergeButton_Click(object sender, EventArgs e)
{
List<string> fieldsWithoutData = new List<string>();
byte[] result;
using (ServerTextControl tx = new ServerTextControl())
{
// Initialize the new instance before using it
tx.Create();
// Import the MS Word merge fields and merge blocks of the DOCX template
LoadSettings loadSettings = new LoadSettings
{
ApplicationFieldFormat = ApplicationFieldFormat.MSWord,
LoadSubTextParts = true
};
tx.Load("invoice.docx", StreamType.WordprocessingML, loadSettings);
using (MailMerge mailMerge = new MailMerge { TextComponent = tx })
{
// Note every merge field that received no data
mailMerge.FieldMerged += (s, args) =>
{
if (!args.Merged && args.MailMergeFieldAdapter is MergeField mergeField)
{
fieldsWithoutData.Add(mergeField.Name);
}
};
// Replace the merge fields with the values of the JSON data
mailMerge.MergeJsonData(File.ReadAllText("invoice.json"));
}
// Save the result as PDF, and for the editor
tx.Save("invoice.pdf", StreamType.AdobePDF);
tx.Save(out result, BinaryStreamType.InternalUnicodeFormat);
}
// Show the merged invoice in the editor
textControl1.Load(result, BinaryStreamType.InternalUnicodeFormat);
if (fieldsWithoutData.Count > 0)
{
MessageBox.Show(this, "No data for: " + string.Join(", ", fieldsWithoutData));
}
}
The code works as follows:
- Loading the template. A DOCX template keeps its merge fields as MS Word fields. ApplicationFieldFormat set to
MSWordimports them as fields, and LoadSubTextParts imports the merge blocks of the next tutorial. Without these settings, the fields are not imported as fields. - Connecting.
TextComponent = txconnects theMailMergeto theServerTextControlthat holds the template. - Merging. MergeJsonData takes a JSON string with one object or an array of objects with the same structure. Each field is replaced with the value of the property of the same name. With several objects, the results are combined into one document.
- Fields without data. FieldMerged occurs for each merged field. Its Merged property is
falsewhen the field received no data. - The result. The
ServerTextControlnow contains the merged invoice. It is saved as invoice.pdf and handed to the editor as a byte array.
Press F5 and click mergeButton. The editor shows the invoice with Contoso Ltd., Jane Miller and INV-1001 in place of the fields, and invoice.pdf is in the output folder.
Control Empty Fields and Lines
Properties of MailMerge decide what happens when the data has no value for a field: RemoveEmptyFields, true by default, removes such fields, and RemoveEmptyLines, false by default, also removes lines that are empty after the merge. Set them before calling the merge method.
Other Kinds of Data
MailMerge has a merge method for each kind of data: Merge for a DataTable, MergeObject for a business object and MergeObjects for a collection of them. The field names match the column names or the public properties.
A MailMerge component from the toolbox can also be connected to textControl1 in the Properties window. Then Merge uses the document in the editor as the template and loads the result back into the editor. Where the Merge Runs describes this setup.
Next Steps
- Add Repeating Merge Blocks: repeat a table row for each invoice item.
- Data Sources: JSON, business objects, DataSets and configuration files in detail.
- Merge Events: change fields and blocks during the merge.