Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Mail Merges in the Cloud: using Aspose.Words for Cloud

11 Jul 2013 1  
Mail Merges in the Cloud: using Aspose.Words for Cloud

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Mail Merge

Mail merges are often run to create letters, and that’s what this example does. FloRelief, a fictional flood relief charity, has an online page where it sells donations of food, water filters, tents and first aid kits to help individuals affected by flooding. You can buy a donation for a friend. (To make it easier to follow the different roles in this scenario, the person who buys the donation is a ‘giver’ and the recipient a ‘donor’.) This is an online service, but the giver has the option of sending a letter to the donor to tell them about the donation. They offer a paper option because some people prefer letters to emails – they feel a little more official and therefore a higher value.

The giver enters information online:

  • Gift details: the size of the donation, how the donor should be contacted.
  • Donor information: the donor’s name and address.
  • Giver information: the giver’s own name. (In a real application, it would also collect billing and invoice address, and credit card details.)

If the giver selects to send a letter, the app takes the gift details, the donor information and the name of giver and merges them into a Microsoft Word template and saves the resulting letter to disk. At the end of the day, a volunteer prints the new files, puts letters into envelopes and mails them.

There are lots of ways of achieving this. The traditional process would be to build an application that sits on a server, collects the data, puts it into a database and then, once daily, runs a mail merge on recent donations.

That’s not FloRelief’s approach. Instead, they use Cloud APIs to perform the mail merge as the form is submitted. (The details are also saved to the database for administrative purposes but that part of the process isn’t part of this example.)

Try Aspose.Words for Cloud.

An Overview of the App

I’ve written a simple web application that launches a web page where a giver selects one or more gifts, whether or not to send a letter and enters some basic user data. To keep it simple, the example doesn’t include gathering or verifying payment details, logging in or any of the background admin that a real application would have. It focuses purely on the process of collecting donor, giver and gift information and mail merging these.

From the user’s perspective, this happens:

  1. The user enters their own and the donor’s details.
  2. Chooses to send a letter.
  3. Selects one or more gifts.
  4. Checks the gifts in the table at the bottom of the page.
  5. Clicks Donate.

In the background, the developer has:

  1. Uploaded a Microsoft Word template to Aspose for Cloud.
  2. Created a web page that collects giver, donor and gift information
  3. Created a new app on Aspose for Cloud and used the ID and key to authenticate requests to the API.
  4. Written the app.

The app:

  1. Builds a table of selected products on the web page.
  2. Collects form data.
  3. Turns form data into XML used for the mail merge.
  4. Sets file name, output path and output format.
  5. Performs the mail merge.
  6. Saves the resulting document.

Everything except the first part is hidden to the user.

The example is written in C# using Microsoft Visual Studio, the Aspose.Words for Cloud .NET SDK and JSON. To access the full example, [download the project].

Note: for the example to run, you need an Aspose.Words for Cloud App ID and key. These are application specific, so the first step of creating an Aspose for Cloud app is creating a new app and getting its ID and key values from your Aspose for Cloud account. Each request sent to Aspose for Cloud has to be signed with the private key to ensure that only authorized apps access the APIs.

Running the Mail Merge

There are a number of aspects to the mail merge: the Microsoft Word template, the HTML page and the code that performs the merge.

The Microsoft Word Template

There are different ways of performing mail merges with Aspose.Words for Cloud. Here, I’m using regions. In the template, I’ve defined two regions with the <<TableStart:NAME>> <<TableEnd:NAME >> tags. The regions are Charity, the body of the letter, and Gift, the table that lists the donations that the giver has selected.

Figure 1: The letter template.

The Web Page

The webpage lists the different gifts and lets the user select them. At the top, users enter giver and donor details.

Figure 2: The input fields

The gifts are listed in the middle. There are six different options, each with a description, a picture and a price.

At the bottom of the page, a table that lists selected gifts is built dynamically.

Figure 4: After selecting gifts, the user clicks Donate.

The Default.aspx.cs File

The Default.aspx.cs contains the main app logic. It builds a table of selected gifts, creates the XML that’s used in the mail merge, and contains the raw values for the app ID and key. (They’ve been replaced with the value NNNN in the code below.)

It performs the mail merge and saves the file. The code that performs the mail merge is contained in this section:

try
            {
                Aspose.Cloud.Words.MailMerge mailMerge = new Aspose.Cloud.Words.MailMerge();
                mailMerge.ExecuteMailMergewithRegions("CharityTemplate.docx", 
                    xml, Aspose.Cloud.Words.SaveFormat.Docx, Server.MapPath("Letters") +
                    "\\" + txtDonorName.Text + ".docx", "", true);
            }
            catch (Exception ex)
            {
                Session["errorMessage"] = ex.Message;
            }
 
        }

Here, the app sets up a new mail merge and defines the template document, data source, output format, output path and file name. It calls MailMerge, described below.

The input - the merge data – is constructed from the data the user enters into the form.

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
 
namespace FloRelief
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                CreateTable();
                GridView2.DataSource = (Session["Data"] as DataTable);
                GridView2.DataBind();
            }
        }
 
        protected void btnDonate_Click(object sender, EventArgs e)
        {
            string xml =
                        @"<root>
                            <Charity>
                              <Date>" + DateTime.Today + @"</Date>
                              <Giver>" + txtGiverName.Text + @"</Giver>
                              <Donor>" + txtDonorName.Text + @"</Donor>
                              <DonorAddress>" + txtDonorAddress.Text + @"</DonorAddress>
                         ";
            foreach (DataRow row in (Session["Data"] as DataTable).Rows)
            {
                xml = xml +
 
                        @"          
                              <Gift>
                                <GiftName>" + row["Gift"] + @"</GiftName>
                                <GiftValue>" + row["Value"] + @"</GiftValue>
                              </Gift>
                         ";
            }
            xml = xml +
                        @"
                            </Charity>
                          </root>";
 
            Aspose.Cloud.Common.AsposeCloudApp.AppSID = "NNNNN”
            Aspose.Cloud.Common.AsposeCloudApp.AppKey = "NNNNN";
 
            Aspose.Cloud.Common.Product.BaseProductUri = "http://api.aspose.com/v1.1";
 
            try
            {
                Aspose.Cloud.Words.MailMerge mailMerge = new Aspose.Cloud.Words.MailMerge();
                mailMerge.ExecuteMailMergewithRegions("CharityTemplate.docx", xml, 
                    Aspose.Cloud.Words.SaveFormat.Docx, Server.MapPath("Letters") + 
                    "\\" + txtDonorName.Text + ".docx", "", true);
            }
            catch (Exception ex)
            {
                Session["errorMessage"] = ex.Message;
            }
 
        }
 
        protected void CartButton_Click(object sender, EventArgs e)
        {
            string giftName = (sender as Button).Attributes["GiftName"];
            string giftValue = (sender as Button).Attributes["GiftValue"];
            (Session["Data"] as DataTable).Rows.Add(giftName, giftValue);
            GridView2.DataSource = (DataTable)Session["Data"];
 
            GridView2.DataBind();
        }
 
        public void CreateTable()
        {
            DataTable table = new DataTable();
            DataColumn column = new DataColumn("Gift", typeof(String));
            table.Columns.Add(column);
            column = new DataColumn("Value", typeof(String));
            table.Columns.Add(column);
            // table.Rows.Add("as", "50");
            Session.Add("Data", table);
        }
 
    }
}

The MailMerge.cs File

In brief, the MailMerge code:

  1. References necessary classes, including Aspose.Cloud.Common.
  2. Builds and signs URIs that validate the API calls.
  3. Gets the response stream.

Below is the MailMerge.cs file in full. You’ll notice that it build up and signs URIs when sending requests to the API.

using System;
using System.Collections.Generic;
using System.Text;
using Aspose.Cloud.Common;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.XPath;
 
namespace Aspose.Cloud.Words
{
    public class MailMerge
    {
        /// <summary>
        /// Execute mail merge with regions.
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="strXML"></param>
        /// <param name="saveformat"></param>
        /// <param name="output"></param>
        /// <param name="documentFolder"></param>
        /// <param name="deleteFromStorage"></param>
        public void ExecuteMailMergewithRegions(string FileName, string strXML, SaveFormat saveformat, string output,
            string documentFolder , bool deleteFromStorage)
        {
            try
            {
                //build URI to get Image
                string strURI = Product.BaseProductUri + "/words/" + FileName + "/executeMailMerge?withRegions=true" +
                    (documentFolder == "" ? "" : "&folder=" + documentFolder);
 
                string signedURI = Utils.Sign(strURI);
 
                string outputFileName = null;
 
                using (Stream responseStream = Utils.ProcessCommand(signedURI, "POST", strXML, "xml"))
                {
                    string strResponse = null;
 
                    using (StreamReader reader = new StreamReader(responseStream))
                    {
                        //further process JSON response
                        strResponse = reader.ReadToEnd();
                    }
 
                    using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(strResponse)))
                    {
                        XPathDocument xPathDoc = new XPathDocument(ms);
                        XPathNavigator navigator = xPathDoc.CreateNavigator();
 
                        //get File Name
                        XPathNodeIterator nodes = navigator.Select("/SaaSposeResponse/Document/FileName");
                        nodes.MoveNext();
                        outputFileName = nodes.Current.InnerXml;
                        //build URI
                        strURI = Product.BaseProductUri + "/words/" + outputFileName;
                        strURI += "?format=" + saveformat + (documentFolder == "" ? "" : "&folder=" + documentFolder);
                    }
                }
                //sign URI
                signedURI = Utils.Sign(strURI);
 
                //get response stream
                using (Stream responseStream = Utils.ProcessCommand(signedURI, "GET"))
                {
                    using (Stream fileStream = System.IO.File.OpenWrite(output))
                    {
                        Utils.CopyStream(responseStream, fileStream);
                    }
                }
 
                if (deleteFromStorage)
                {
                    signedURI = Utils.Sign(Product.BaseProductUri + "/storage/file/" +
                        (documentFolder == "" ? outputFileName : documentFolder + "/" + outputFileName));
                    Utils.ProcessCommand(signedURI, "DELETE");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
 
    }
}

Completed Mail Merge

The output file is formatted like the template but contains the data entered on the web page.

Figure 5: The merged document.

Summary

Cloud APIs can be used for a wide range of tasks. This example has shown how to perform a mail merge from a web app. The process is structured and relatively simple: create the data source, send it to the API and merge it into a template to produce a new document.

Aspose.Words for Cloud provides simple yet sophisticated tools for document management and manipulation in the Cloud. An API that allows a mail merge, for example, makes it easy to integrate web applications and document management.

If you want to try it out, create an account and start a free trial. Try Aspose.Words for Cloud.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here