We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

How to perform mail merge in ASP.NET MVC

Platform: JavaScript - EJ 2 |
Control: DocumentEditor |
Published Date: March 22, 2019 |
Last Revised Date: March 22, 2019

You can insert fields in to Document Editor and perform mail merge using the Syncfusion DocIO library in server-side, and then view the merged document in the Document Editor control.

 

CSHTML

<div>
            <div style="margin-bottom:12px">
                <button onclick="mergeDocument()" class="e-control e-btn e-primary">Merge Document</button>
            </div>
            <div style="display:flex">
                <div style="width:15%;border:1px solid #e0e0e0">
                    <b><label style="display:block;margin:10px">Select Field to Insert</label></b>
                    @Html.EJS().ListView("listview").Enable(true).Select("onFieldSelect").DataSource((IEnumerable<object>)ViewBag.dataSource).Render()
                </div>
                <div style="width:85%;border:1px solid #e0e0e0">
                    @Html.EJS().DocumentEditor("container").IsReadOnly(false).EnableSelection(true).EnableEditor(true).EnableEditorHistory(true).EnableWordExport(true).Created("onCreated").Render()
                </div>
            </div>
            <div class="overlay" id="popup-overlay" style="display: none;"></div>
            <div id='waiting-popup' style="display: none;">
                <svg class="circular" height="40" width="40">
                    <circle class="circle-path" cx="25" cy="25" r="20" fill="none" stroke-width="6" stroke-miterlimit="10" />
                </svg>
            </div>
        </div>

 

JS

 
    var documenteditor;
    var listView;
 
    function onCreated() {
        documenteditor = document.getElementById("container").ej2_instances[0];
        JS documenteditor.pageOutline ="#e0e0e0"
        listView = document.getElementById("listview").ej2_instances[0];
        documenteditor.resize();
    }
 
    function onFieldSelect(args) {
        let fieldName = args.data.text;
        listView.selectItem(undefined)
        insertField(fieldName);
    }
 
    function insertField(fieldName) {
        fileName = fieldName.replace(/\n/g, '').replace(/\r/g, '').replace(/\r\n/g, '');
        var fieldCode = 'MERGEFIELD  ' + fileName + "  \\* MERGEFORMAT ";
        documenteditor.editor.insertField(fieldCode, '«' + fieldName + '»');
        documenteditor.focusIn();
    }
 
    function mergeDocument() {
        documenteditor.saveAsBlob("Docx").then(function (blob) {
            var fileReader = new FileReader();
            fileReader.onload = function () {
                var base64String = fileReader.result;
                var data = {
                    fileName: documenteditor.documentName + '.docx',
                    documentData: base64String
                }
                showHideWaitingIndicator(true)
                var httpRequest = new XMLHttpRequest();
                httpRequest.open('Post', '/api/DocumentEditor/MailMerge', true);
                httpRequest.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
                httpRequest.onreadystatechange = function () {
                    if (httpRequest.readyState === 4) {
                        if (httpRequest.status === 200 || httpRequest.status === 304) {
                            documenteditor.open(httpRequest.responseText);
                        } else {
                            // Failed to merge document
                        }
                        showHideWaitingIndicator(false);
                    }
                };
                httpRequest.send(JSON.stringify(data));
            }
            fileReader.readAsDataURL(blob);
        });
    }
 
    function showHideWaitingIndicator(show) {
        document.getElementById("popup-overlay").style.display = show ? 'block' : 'none';
        document.getElementById("waiting-popup").style.display = show ? 'block' : 'none';
    }

 

Controller

public ActionResult Index()
        {
            List<object> listdata = new List<object>();
            listdata.Add(new
            {
                text = "FirstName",
                id = "_firstname",
            });
            listdata.Add(new
            {
                text = "LastName",
                id = "_lastname",
            });
            listdata.Add(new
            {
                text = "CustomerID",
                id = "_customerid",
            });
            listdata.Add(new
            {
                text = "EmailID",
                id = "_emailid",
            });
            listdata.Add(new
            {
                text = "MobileNo",
                id = "_mobileno",
            });
            ViewBag.dataSource = listdata;
            return View();
        }

 

Web API

[HttpPost]
        public HttpResponseMessage MailMerge([FromBody]ExportData exportData)
        {
            Byte[] data = Convert.FromBase64String(exportData.documentData.Split(',')[1]);
            MemoryStream stream = new MemoryStream();
            stream.Write(data, 0, data.Length);
            stream.Position = 0;
            try
            {
                Syncfusion.DocIO.DLS.WordDocument document = new Syncfusion.DocIO.DLS.WordDocument(stream, Syncfusion.DocIO.FormatType.Docx);
 
                document.MailMerge.RemoveEmptyGroup = true;
                document.MailMerge.RemoveEmptyParagraphs = true;
                document.MailMerge.ClearFields = true;
 
                document.MailMerge.Execute(CustomerDataModel.GetAllRecords());
                SplitEachRecoreds(document);
 
                document.Save(stream, Syncfusion.DocIO.FormatType.Docx);
            }
            catch (Exception ex)
            {
 
            }
            // Write Pdf stream here.
            return new HttpResponseMessage() { Content = new StringContent(ImportWordDocument(stream)) };
 
        }
 
        public string ImportWordDocument(Stream stream)
        {
            string sfdtText = "";
            Syncfusion.EJ2.DocumentEditor.WordDocument document = Syncfusion.EJ2.DocumentEditor.WordDocument.Load(stream, Syncfusion.EJ2.DocumentEditor.FormatType.Docx);
            sfdtText = Newtonsoft.Json.JsonConvert.SerializeObject(document);
            document.Dispose();
            return sfdtText;
        }
        private void SplitEachRecoreds(Syncfusion.DocIO.DLS.WordDocument document)
        {
            TextSelection[] textSelections = document.FindAll("#PageBreak", true, true);
 
            if (textSelections != null)
            {
                foreach (TextSelection selection in textSelections)
                {
                    WParagraph paragraph = selection.GetAsOneRange().OwnerParagraph;
                    paragraph.Text = string.Empty;
                    paragraph.InsertSectionBreak(SectionBreakCode.NewPage);
                }
            }
        }
        private void ApplyBoldFromatting(object sender, MergeFieldEventArgs args)
        {
            if (args.FieldName == "IsDefault")
            {
                if (args.FieldValue.ToString() == "Yes")
                    isApplyBold = true;
                else
                    isApplyBold = false;
            }
            else if (args.FieldName == "FirstName")
            {
                if (isInsertBreak)
                {
                    bool isInCell = args.CurrentMergeField.OwnerParagraph.Owner is WTableCell;
                    bool isInTextBox = args.CurrentMergeField.OwnerParagraph.Owner is WTextBox;
                    bool isInContentControl = args.CurrentMergeField.OwnerParagraph.Owner is BlockContentControl;
 
                    WParagraph paragraph;
                    if (isInCell)
                    {
                        WTableCell ownerCell = args.CurrentMergeField.OwnerParagraph.Owner as WTableCell;
                        paragraph = ownerCell != null ? (ownerCell.OwnerRow.Owner as WTable).PreviousSibling.PreviousSibling as WParagraph : args.CurrentMergeField.OwnerParagraph.PreviousSibling as WParagraph;
                    }
                    else if (isInTextBox)
                    {
                        WTextBox textBox = args.CurrentMergeField.OwnerParagraph.Owner as WTextBox;
                        paragraph = textBox.OwnerParagraph.PreviousSibling.PreviousSibling is WParagraph ? textBox.OwnerParagraph.PreviousSibling.PreviousSibling as WParagraph : args.CurrentMergeField.OwnerParagraph;
                    }
                    else if (isInContentControl)
                    {
                        BlockContentControl contentControl = args.CurrentMergeField.OwnerParagraph.Owner as BlockContentControl;
                        paragraph = contentControl.PreviousSibling.PreviousSibling as WParagraph;
                    }
                    else
                        paragraph = args.CurrentMergeField.OwnerParagraph.PreviousSibling.PreviousSibling as WParagraph;
 
                    paragraph.Text = "#PageBreak";
                }
                else
                    isInsertBreak = true;
            }
 
            if (isApplyBold)
            {
                foreach (Entity entity in args.CurrentMergeField.OwnerParagraph.Items)
                {
                    if (entity is WTextRange)
                        (entity as WTextRange).CharacterFormat.Bold = true;
                }
                //Apply the bold formatting to adjacent cell.
                WTableCell cell = args.CurrentMergeField.OwnerParagraph.Owner.PreviousSibling as WTableCell;
                ApplyBoldFormattingsForCell(cell);
            }
        }
        private void ApplyBoldFormattingsForCell(WTableCell cell)
        {
            foreach (WParagraph paragraph in cell.Paragraphs)
            {
                foreach (Entity entity in paragraph.Items)
                {
                    if (entity is WTextRange)
                        (entity as WTextRange).CharacterFormat.Bold = true;
                }
            }
        }

 

 

Sample: http://www.syncfusion.com/downloads/support/directtrac/general/ze/Mail_Merge_Sample1301778016

 

In the previous sample, a list view has been added in the left pane, which shows a list of fields that can be inserted in to the Document Editor.

On selecting the list item, the corresponding field will be inserted in to the Document Editor. After inserting the field, you can perform mail merge in server-side and view the merged document by clicking the merge document button.

ADD COMMENT
You must log in to leave a comment
Comments
Gustavo Galvão
Aug 12, 2019

Hello all,

We can see that there are a lot of methods and properties exposed for fields, can anyone clear how to use them... editor.removeFieldInBlock, editor.insertFieldSeparatorText, viewer.getFieldResult...

Reply
Harini Chellappa [Syncfusion]
Aug 14, 2019

Hi Gustavo,

Methods that you mentioned are internal methods. To learn more about document editor API, refer to https://ej2.syncfusion.com/javascript/documentation/api/document-editor/ https://ej2.syncfusion.com/javascript/documentation/api/document-editor/editor/

Currently, we do not have client-side mail merge feature in document editor. However, we can achieve the same using server-side DocIO dependency.

You can follow the steps mentioned in this article to achieve mail merge.

Please sign in to access our KB

This page will automatically be redirected to the sign-in page in 10 seconds.

Up arrow icon

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

Live Chat Icon For mobile