I have an application that loads a List and would like to use it along with a ExecuteWithRegions to include a MailMerge through, as I do that? Using IMailMergeDataSource? How would I do that?
I already have a class called Product, with the fields idProduct, Name.
To load this List do as follows:
NGProduct objNGProduct = new NGProduct();
List objProduct = new List();
objProdut = objNGProduct.List();
Let me make quick review how to work with Mail Merge with Region.
Using mail merge you can merge data from your datasource into existing tables in your template. These tables will dynamically grow with each row of data from the datasource. You do not need to create tables manually and insert them. But before you should prepare your template in the following way:
To specify a mail merge region in the document you need to insert two mail merge fields to mark the beginning and end of the mail merge region. All document content that is included inside a mail merge region automatically will be repeated for every record in the data source (in most cases this is a table).
To mark the beginning of a mail merge region, insert a MERGEFIELD with the name TableStart:MyTable, where MyTable corresponds to the name of the table. To mark the end of the mail merge region insert another MERGEFIELD with the name TableEnd:MyTable. Between these marking fields, place merge fields that correspond to the fields of your data source (table columns). These merge fields will be populated with data from the first row of the data source, then the whole region will be repeated, and the new fields will be populated with data from the second row, and so on.
Your data can come from a source in a variety of formats supported by ADO.NET. It can be DataTable, DataView, DataSet, IDataReader or an array of values. If you have your data in XML format, then you can load it into a DataSet and merge with the DataSet.
Aspose.Words also accepts ADO Recordset objects and exposes COM classes and interfaces so you can use it from within COM and scripting applications such as ASP applications.
Finally, you can implement the IMailMergeDataSourcehttps://reference.aspose.com/words/net/aspose.words.mailmerging/imailmergedatasource/and sometimes IMailMergeDataSourceRoot interfaces to merge data from any data source including a LINQ query, XML file or business objects.
You can find an example how to execute Mail Merge with Regions on the Demo pages here. If you installed Aspose.Words using the MSI installer you can find the full code and templates in the folder where Aspose.Words is installed to.
I hope you find all needed information.
Please feel free to ask more question.
Thank you for your attention.
But I still have doubts. I did as you said in the model. doc, but as shown above the data of my table populate a List , how do I use it as a data source in ExecuteWithRegions? For it always shows an error saying it’s not possible to use ExecuteWithRegions that way.
Thanks
Thanks for your request. I created a simple code example that demonstrated how you can use IMailMergeDatasource to achieve what you need:
[Test]
public void Test001()
{
// Create a list of objects.
List<Product> products = new List<Product>();
// Add few items to the list.
products.Add(new Product("Milk", "Tasty milk", 2));
products.Add(new Product("Juice", "Orange juice", 3));
products.Add(new Product("Bread", "White bread", 1));
// etc...
// Now lets create a datasource that can be used for mail merge.
// see the implementation of MailMergeDataSource below.
MailMergeDataSource dataSource = new MailMergeDataSource(products, "Products");
// Now we can open template and execute mail merge with regions or simple mail merge using out datasource.
Document doc = new Document(@"Test001\in.doc");
doc.MailMerge.ExecuteWithRegions(dataSource);
doc.Save(@"Test001\out.doc");
}
///
/// This is class that we will use as data item.
///
private class Product
{
public Product(string name, string description, double price)
{
mName = name;
mPrice = price;
mDescription = description;
}
public double Price
{
get { return mPrice; }
}
public string Name
{
get { return mName; }
}
public string Description
{
get { return mDescription; }
}
private string mName;
private string mDescription;
private double mPrice;
}
///
/// A custom mail merge data source that you implement to allow Aspose.Words
/// to mail merge data from LINQ query results into Microsoft Word documents.
///
private class MailMergeDataSource : IMailMergeDataSource
{
///
/// Creates new instance of a custom mail merge data source
///
/// Collection of objects used for mail merge.
public MailMergeDataSource(IEnumerable data)
{
mEnumerator = data.GetEnumerator();
}
///
/// Creates new instance of a custom mail merge data source
///
/// Collection of objects used for mail merge.
/// Name of the data source is only used when you perform mail merge with regions.
/// If you would like to use simple mail merge then use constructor with one parameter.
public MailMergeDataSource(IEnumerable data, string tableName)
{
mEnumerator = data.GetEnumerator();
// Name of the data source is needed when you perform mail merge with regions
mTableName = tableName;
}
///
/// Aspose.Words call this to get a value for every data field.
///
public bool GetValue(string fieldName, out object fieldValue)
{
// Get type of current record
Type curentRecordType = mCurrentObject.GetType();
// Use reflection to get property by name and its value
PropertyInfo property = curentRecordType.GetProperty(fieldName);
if (property != null)
{
fieldValue = property.GetValue(mCurrentObject, null).ToString();
return true;
}
else
{
// A field with this name was not found,
// return false to the Aspose.Words mail merge engine.
fieldValue = null;
return false;
}
}
public IMailMergeDataSource GetChildDataSource(string tableName)
{
return null;
}
///
/// Moves to the next record in the collection.
///
public bool MoveNext()
{
// Move enumerator to next record
bool hasNexeRecord = mEnumerator.MoveNext();
if (hasNexeRecord)
{
mCurrentObject = mEnumerator.Current;
}
return hasNexeRecord;
}
///
/// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions.
///
public string TableName
{
get { return mTableName; }
}
private IEnumerator mEnumerator;
private object mCurrentObject;
private string mTableName = string.Empty;
}
Absolutely perfect, it worked.
Now I have a new doubt, have a field true/false to enter another field ExecuteWithRegions, how do I place these values appear in fields as practice/no practice?
More like a doubt put an image within a field ExecuteWithRegions as follows:
Text field
image1
image2
Remembering all these fields comes from a database, and can I have none, one or more images from the database
Once again I thank everyone’s attention
Hi Wesley,
Thanks for your inquiry.
You can learn to how to insert an image during mail merge in the article here.
Regarding how to insert custom text for a boolean column please see the code below which uses the IFieldMergingCallback as shown in the first link.
private class HandleMergeFieldBooleanField : IFieldMergingCallback
{
///
/// This is called when merge field is actually merged with data in the document.
///
void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
{
// This is the name of the field to handle specially.
if (e.DocumentFieldName.StartsWith("HasPratice"))
{
// Insert the text for this merge field as HTML data, using DocumentBuilder.
string textToInsert = (bool)e.FieldValue ? "Pratice" : "No Practice";
// Insert the custom text instead.
e.Text = textToInsert;
}
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs e)
{
// Do nothing.
}
}