Mailmerge using PDF template

Hi,

We are using Aspose.Words to MailMerge Word document template. We need to extend this to PDF template as well.

  • Can you please confirm whether Aspose supports PDF mailMerge.

Right now we are converting the PDF to Aspose Word document then mailmerging the template.

It works fine for simple mailMerge, but when our template has multipleRegion/looping (foreach) variable inside a table then all items are printed in the same line.

PDF template with variables :
image.png (81.3 KB)

Merged document :
image.png (87.8 KB)

Note: We use Aspose.Words.Reporting.BuildReport method to mailMerge

@mjjagan

Aspose.PDF for .NET does not provide functionality of MailMerge. However, you can find and replace text inside a PDF document using the API. You can use this feature in order to replace the text markers with your desired values in a PDF. In case you face any issue, please feel free to let us know.

Thanks for your Reply @asad.ali

I tried replacing text inside a PDF document, but it does not satisfy our expectation

We want to replace/mailmerge multiple repeating variables.
But Aspose PDF needs TextFragmentAbsorber object for each variable replacement.


We have used below code to replace multiple repeating variables

Also we have used
TextFragmentAbsorber searchAbsorber = new TextFragmentAbsorber("(?<=ForEach)(.*?)(?=EndForEach)", new TextSearchOptions(true));

to Extract text between a particular start and end text, but it is not working when start and end text is in different line.


   private static void ReplacePdfLoopingText()
    {
        Aspose.Pdf.Document doc = new Aspose.Pdf.Document("C:/Jagan/My Project/MailMergePdf/MailMergePdf/MergeTemplate.pdf");
        TextFragmentAbsorber textFragmentAbsorber;

        List<TemplateParameter> parmaeters = GenerateDictionaryParams();

        TextFragmentAbsorber searchAbsorber = new TextFragmentAbsorber("(?<=ForEach)(.*?)(?=EndForEach)", new TextSearchOptions(true));
        doc.Pages.Accept(searchAbsorber);

        foreach (TextFragment textFragment in searchAbsorber.TextFragments)
        {
            Console.WriteLine(textFragment.Text);
            string[] loopItem = textFragment.Text.Split(' ');
            if (loopItem.Length > 0)
            {
                foreach (string item in loopItem)
                {
                    if (!string.IsNullOrEmpty(item))
                    {
                        List<TemplateParameter> lstParameter = parmaeters.Where(x => x.Key.Equals(item)).ToList();
                        textFragmentAbsorber = new TextFragmentAbsorber(item);
                        doc.Pages.Accept(textFragmentAbsorber);
                        RepaceFragmentText(textFragmentAbsorber, string.Join(Environment.NewLine, lstParameter[0].Values));
                    }
                }
            }
        }

        // Save resultant PDF
        doc.Save(Assembly.GetExecutingAssembly().Location + "ReplacedTemplate.pdf");
    }

    private static void RepaceFragmentText(TextFragmentAbsorber textFragmentAbsorber, string replacedText)
    {
        foreach (TextFragment textFragment in textFragmentAbsorber.TextFragments)
        {
            textFragment.Text = replacedText.Replace("ASPOSENEWLINE", Environment.NewLine);
        }
    }

    private static List<TemplateParameter> GenerateDictionaryParams()
    {
        List<TemplateParameter> lstParams = new List<TemplateParameter>();
        lstParams.Add(new TemplateParameter { Key = "<<[CONTACT_TYPE]>>", Values = new List<string>() { "Contact 1", "Contact 2", "Contact 3"} });
        lstParams.Add(new TemplateParameter { Key = "<<[EMPLOYEEFIRSTNAME]>>", Values = new List<string>() { "Jagan 1", "Jagan 2", "Jagan 3"} });
        lstParams.Add(new TemplateParameter { Key = "<<[EMAIL]>>", Values = new List<string>() { "test@aspose.com 1", "test@aspose.com 2", "test@aspose.com 3" } });
        lstParams.Add(new TemplateParameter { Key = "<<[COMMENTS]>>", Values = new List<string>() { "default 1", "empty 2", "None 3"} });
        lstParams.Add(new TemplateParameter { Key = "<<[PRIMARY_SECONDARY]>>", Values = new List<string>() { "Primary 1", "Secondary 2", "Primary 3"} });
        lstParams.Add(new TemplateParameter { Key = "<<[ESCALATION_CONTACT]>>", Values = new List<string>() { "Briwnie 1", "Reigns 2", "Kantla 3"} });
        lstParams.Add(new TemplateParameter { Key = "<<[ADDED_BY]>>", Values = new List<string>() { "IShant 1", "Cena 2", "Bently 3"} });

        return lstParams;
    }

class TemplateParameter
{
public string Key { get; set; }

    public List<string> Values { get; set; }
}

Template to be Replaced - MergeTemplate.pdf (39.1 KB)
Expected Output Template - ExpectedMerge.pdf (38.1 KB)
Actual Output Template - ActualMerge.pdf (280.9 KB)

Can you please let us if we could get the Expected Output Template from Template to be Replaced using Aspose PDF ?

@mjjagan

Could you please try to replace the text markers one by one using the way like below:

// this list contains all markers/mailmerge fields
List<string> lstTexttoReplace = new List<string>();

foreach (string s in lstTexttoReplace)
{
    TextFragmentAbsorber tfa2 = new TextFragmentAbsorber(s);
    doc.Pages.Accept(tfa2);
    foreach (TextFragment tf in tfa2.TextFragments)
    {
        if(tf.Text == "[CONTACT_TYPE]")
          tf.Text = "Test Contact" + Environment.NewLine + "Test Contact";
    }
}

Please feel free to let us know in case you still notice any issues.

Hi,

I tried the below code earlier too, but its not working.

tf.Text = "Test Contact" + Environment.NewLine + "Test Contact";

Environment.NewLine is not considered in TextFragment.Text and the resultant text is printed in same line.

Complete Code

private static void ReplacePDFForum()
{
List lstTexttoReplace = new List() { “EMPLOYEEFIRSTNAME”, “<<[COMMENTS]>>” };

        Aspose.Pdf.Document doc = new Aspose.Pdf.Document("C:/Jagan/My Project/MailMergePdf/MailMergePdf/MergeTemplate1.pdf");

        foreach (string s in lstTexttoReplace)
        {
            TextFragmentAbsorber tfa2 = new TextFragmentAbsorber(s);
            doc.Pages.Accept(tfa2);
            foreach (TextFragment tf in tfa2.TextFragments)
            {
                if (tf.Text == "EMPLOYEEFIRSTNAME")
                    tf.Text = "Aspose 1" + Environment.NewLine + "Aspose 2";
                else if (tf.Text == "<<[COMMENTS]>>")
                    tf.Text = "New comment 1 " + Environment.NewLine + " New Comment 2";
            }
        }

        doc.Save(Assembly.GetExecutingAssembly().Location + "ForumTemplate.pdf");
    }

Template:
image.png (17.6 KB)

Replaced Template
MailMergePdf.dllForumTemplate.pdf (195.3 KB)

@mjjagan

We have logged an issue as PDFNET-50999 in our issue tracking system after testing the scenario with Aspose.PDF for .NET 21.11. We will further look into its details and keep you posted with the status of its correction. Please be patient and spare us some time.

We are sorry for the inconvenience.