One of the important Aspose.Words features is the reporting (mail merge) engine. The mail merge engine takes a document on input, looks for MERGEFIELD fields in it and replaces them with data it obtains from the data source. Normally, simple text is inserted, but a customer asked if it is possible to generate a document where boolean data values are output as check box form fields.
The answer is yes - it is possible and it is very easy, thanks to the ability to extend the mail merge process using event handlers. The MailMerge object provides the MergeField and MergeImageField event handlers.
Other interesting examples of extending standard mail merge using event handlers are:
- Insert HTML into merge fields (sample code in the documentation for the MergeField event).
- Insert images from any custom storage (files, BLOB fields etc).
- Insert text with formatting (font, size, style etc).
This screenshot of Microsoft Word shows the template document with the merge fields:
This screenshot of Microsoft Word shows the generated document. Note some fields were replaced with simple text, some fields were replaced with check box form fields and the Subject field was replaced with a text input form field.
Example MailMergeFormFields
Complete source code of a program that inserts checkboxes and text input form fields into a document during mail merge.
[C#]
using System;
using System.IO;
using System.Reflection;
using Aspose.Words;
using Aspose.Words.Fields;
using Aspose.Words.Reporting;
namespace MailMergeFormFields
{
/// <summary>
/// This sample shows how to insert check boxes and text input form fields during mail merge into a document.
/// </summary>
class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
Program program = new Program();
program.Execute();
}
private void Execute()
{
string exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string docsDir = Path.GetFullPath(Path.Combine(exeDir, @"..\..\..\Common"));
// Load the template document.
Document doc = new Document(Path.Combine(docsDir, "Template.doc"));
// Setup mail merge event handler to do the custom work.
doc.MailMerge.MergeField += new MergeFieldEventHandler(HandleMergeField);
// The mail merge event handler will use this document builder object to do its work.
mBuilder = new DocumentBuilder(doc);
// This is the data for mail merge.
String[] fieldNames = new String[] {"RecipientName", "SenderName", "FaxNumber", "PhoneNumber",
"Subject", "Body", "Urgent", "ForReview", "PleaseComment"};
Object[] fieldValues = new Object[] {"Josh", "Jenny", "123456789", "", "Hello",
"Test message 1", true, false, true};
// Execute the mail merge.
doc.MailMerge.Execute(fieldNames, fieldValues);
// Save the finished document.
doc.Save(Path.Combine(docsDir, "Template Out.doc"));
}
/// <summary>
/// This handler is called for every mail merge field found in the document,
/// for every record found in the data source.
/// </summary>
private void HandleMergeField(object sender, MergeFieldEventArgs e)
{
// We decided that we want all boolean values to be output as check box form fields.
if (e.FieldValue is bool)
{
// Move the "cursor" to the current merge field.
mBuilder.MoveToMergeField(e.FieldName);
// It is nice to give names to check boxes. Lets generate a name such as MyField21 or so.
string checkBoxName = string.Format("{0}{1}", e.FieldName, e.RecordIndex);
// Insert a check box.
mBuilder.InsertCheckBox(checkBoxName, (bool)e.FieldValue, 0);
// Nothing else to do for this field.
return;
}
// Another example, we want the Subject field to come out as text input form field.
if (e.FieldName == "Subject")
{
mBuilder.MoveToMergeField(e.FieldName);
string textInputName = string.Format("{0}{1}", e.FieldName, e.RecordIndex);
mBuilder.InsertTextInput(textInputName, TextFormFieldType.RegularText, "", (string)e.FieldValue, 0);
}
}
private DocumentBuilder mBuilder;
}
}
[Visual Basic]
Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Reflection
Imports Aspose.Words
Imports Aspose.Words.Fields
Imports Aspose.Words.Reporting
Namespace MailMergeFormFields
''' <summary>
''' This sample shows how to insert check boxes and text input form fields during mail merge into a document.
''' </summary>
Friend Class Program
''' <summary>
''' The main entry point for the application.
''' </summary>
<STAThread> _
Shared Sub Main(ByVal args As String())
Dim program As Program = New Program()
program.Execute()
End Sub
Private Sub Execute()
Dim exeDir As String = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
Dim docsDir As String = Path.GetFullPath(Path.Combine(exeDir, "..\..\..\Common"))
' Load the template document.
Dim doc As Document = New Document(Path.Combine(docsDir, "Template.doc"))
' Setup mail merge event handler to do the custom work.
AddHandler doc.MailMerge.MergeField, AddressOf HandleMergeField
' The mail merge event handler will use this document builder object to do its work.
mBuilder = New DocumentBuilder(doc)
' This is the data for mail merge.
Dim fieldNames As String() = New String() {"RecipientName", "SenderName", "FaxNumber", "PhoneNumber", "Subject", "Body", "Urgent", "ForReview", "PleaseComment"}
Dim fieldValues As Object() = New Object() {"Josh", "Jenny", "123456789", "", "Hello", "Test message 1", True, False, True}
' Execute the mail merge.
doc.MailMerge.Execute(fieldNames, fieldValues)
' Save the finished document.
doc.Save(Path.Combine(docsDir, "Template Out.doc"))
End Sub
''' <summary>
''' This handler is called for every mail merge field found in the document,
''' for every record found in the data source.
''' </summary>
Private Sub HandleMergeField(ByVal sender As Object, ByVal e As MergeFieldEventArgs)
' We decided that we want all boolean values to be output as check box form fields.
If TypeOf e.FieldValue Is Boolean Then
' Move the "cursor" to the current merge field.
mBuilder.MoveToMergeField(e.FieldName)
' It is nice to give names to check boxes. Lets generate a name such as MyField21 or so.
Dim checkBoxName As String = String.Format("{0}{1}", e.FieldName, e.RecordIndex)
' Insert a check box.
mBuilder.InsertCheckBox(checkBoxName, CBool(e.FieldValue), 0)
' Nothing else to do for this field.
Return
End If
' Another example, we want the Subject field to come out as text input form field.
If e.FieldName = "Subject" Then
mBuilder.MoveToMergeField(e.FieldName)
Dim textInputName As String = String.Format("{0}{1}", e.FieldName, e.RecordIndex)
mBuilder.InsertTextInput(textInputName, TextFormFieldType.RegularText, "", CStr(e.FieldValue), 0)
End If
End Sub
Private mBuilder As DocumentBuilder
End Class
End Namespace
[Java]
import com.aspose.words.*;
import java.text.MessageFormat;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/// <summary>
/// This sample shows how to insert check boxes and text input form fields during mail merge into a document.
/// </summary>
public class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
public static void main(String[] args) throws Exception
{
Program program = new Program();
program.Execute();
}
private void Execute() throws Exception
{
String projectDir = System.getProperty("user.dir");
String docsDir = projectDir + "/../Common/";
// Load the template document.
Document doc = new Document(docsDir + "Template.doc");
// Setup mail merge event handler to do the custom work.
doc.getMailMerge().addMergeFieldEventHandler(new HandleMergeField());
// The mail merge event handler will use this document builder object to do its work.
mBuilder = new DocumentBuilder(doc);
// This is the data for mail merge.
String[] fieldNames = new String[] {"RecipientName", "SenderName", "FaxNumber", "PhoneNumber",
"Subject", "Body", "Urgent", "ForReview", "PleaseComment"};