Define list of mail merge fields available in template

Hi,

I am in the process of evaluating Aspose.Words for generating Word/PDF docs from templates, using the mail merge facility.

One of my key requirements is to allow the end user to edit the Word templates (and create new templates). In doing so, the user will need to be able to add/remove mail merge fields at various places in the template.

In the online documentation for preparing a Word template (https://docs.aspose.com/words/net/mail-merge-template/), it shows that the user needs to type in the name of the field (Step 5).

Is it possible to have a pre-defined list of the mail merge fields available for the template, so that the user can select the field (with a friendly name) from a dropdown list instead of having to type it in? My application will store the list of available fields for each template in a SqlServer DB - I just need to know if there is any way of getting this list to the template when the end user is editing the template.

Thanks in advance,

Andy

Hi

Thanks for your request. To achieve this You should specify mail merge data source. Please see the following link for more information:

https://reference.aspose.com/words/net/aspose.words/document/mailmergesettings/

For example, see the following code:

string dataSource = @"C:\Temp\test.csv";
Document doc = new Document();
doc.MailMergeSettings.DataType = MailMergeDataType.TextFile;
doc.MailMergeSettings.MainDocumentType = MailMergeMainDocumentType.FormLetters;
doc.MailMergeSettings.DataSource = dataSource;
doc.MailMergeSettings.Query = string.Format(@"SELECT * FROM {0}", dataSource);
Regex whiteSpaceRegex = new Regex(@"\s+");
using (StreamReader reader = new StreamReader(dataSource, Encoding.UTF8))
{
    string firstLine = reader.ReadLine();
    string[] fieldNames = firstLine.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    for (int i = 0; i < fieldNames.Length; i++)
    {
        OdsoFieldMapData mapData = new OdsoFieldMapData();
        mapData = new OdsoFieldMapData();
        mapData.Column = i;
        mapData.MappedName = fieldNames[i];
        mapData.Name = whiteSpaceRegex.Replace(fieldNames[i], "_");
        mapData.Type = OdsoFieldMappingType.Column;
        doc.MailMergeSettings.Odso.FieldMapDatas.Add(mapData);
    }
}
doc.Save(@"Test001\out.doc");

Datasouce is txt file, which contains data in the following format:

Field1,Field2,Field3,Field4,
, , , ,

In this case you will be able to insert predefined merge field into your template. Please see the attached screenshot.

Best regards.

Hi,

I have a similar requirement in that I want to present an existing document to an end-user with a pre-populated list of available mail merge fields. Whilst your example above works, it is not really suitable for me as the Word document will be delivered to the end-user via an ASP.NET web site and writing a text file to disk for it to then be re-read is not ideal in such an environment.

Therefore, is it possible to attach the list of fields from, for example, a DataTable instead of a text file?

Thanks,

Mike.

Hi Mike,

Thanks for your inquiry. I am afraid it is possible only if you attach your document to external data source. Otherwise, “Insert Merge Field” button on “Mailings” tab in Ms Word will be inactive.

Best regards,

Ah, apologies. The penny has dropped now. Word queries the data source at the point when it opens the document…

Thanks,

Mike.

Hi Mike,

Yes, unfortunately, there is no way to store data source inside document.

Maybe as a workaround, you can try storing both template and data source into ZIP archive and send this archive to the end user. In this case data source will be available on client side. You can use SharpZipLib to create a ZIP archive programmatically. You can download the most recent version of SharpZipLib from here:

http://www.sharpziplib.com/

Best regards,

Thanks, I’d sort of come to that conclusion, although it is a bit messy.

I have tried specifying a data source on a web server such as "http://localhost:1923/WebSite/Test.csv" instead of to a local or mapped network drive but Word doesn’t seem to like this either. My thinking was that I could have a HttpHandler that generated the csv file from the merge fields held in the database, but unfortunately not.

If you know of a way to do this that would be great, otherwise it seems the zip file approach is the only alternative.

Thanks again,

Mike.

Hi

Thank you for additional information. Unfortunately, I did not find any way to attach template to the data source stored in web. MS Word seems to allow only loading data from files stored on local PC or in network.

Best regards,

I know this is a bit late in this thread, but I have the same issue. Just to let you know, I may have a better solution that I am about to try. I am about to create a blank MS Word document and edit the Open method. Inside the open method the code will do the following:

  1. See if the document type is a Form Letter.

  2. If so, it will assign a data source that resides in the same directory as the letter (if it exists), and it’ll have an appropriate naming convention. For instance, if the name of the letter is Test.doc, perhaps the data source file will be Test.csv.

This document will be used as the starting point for all template documents that my users create. So, in theory the user won’t have to manually navigate to a data source because it’ll be done automatically in the Open method.

When the user downloads a document to edit, I’ll first create an appropriate CSV file (i.e. first row will be the names of the merge fields, and the second row will be some sample data so the user can test formatting, etc. by switching between viewing merge field names and sample values). The user will download both documents at the same time - perhaps by zipping them up as previously suggested.

After the user finishes editing the document, he/she will have to upload it back to the system. At that point I’ll change the document type to be a normal document. Note - this does not remove any merge fields - it just stops the document from trying to attach to a data source when opened.

I think all of that can be done. The tricky part, and I’m not sure it’s too tricky at all, is to make sure the Open method doesn’t get run when I actually want to use the document to perform a real merge. I think I just have to pass an optional boolean parameter with a default value to my Open method. If the parameter matches the default value, it is being opened by the user on his/her computer. If the parameter does not match the default value, it means we are doing a real merge, in which case I won’t be attaching a data source in the Open method, but instead will be programmatically attaching my data source at runtime.

I hope that all makes sense. I’ll let you know if I can get it to work. I’d be curious to hear if anyone sees any flaws in my logic.

Thanks.

Steve

Hi Steve,

Thanks you for sharing your suggestion. But if you anyways need to send two files (template and data source) to the end user, why don’t you attach the data source before sending them to the end user? In this case, you do not need to create macros in the document that will attach a data source.

Best regards,