I’m currently working on a C# project that uses GemBox.Document to perform a mail merge operation. I have a Word template that contains a table with merge fields. I’m using a JSON object as the data source for the mail merge. The JSON object contains a list of officers, each with an “InclExcl” property, which can be either “include” or “exclude.”
My goal is to conditionally hide or remove table rows during the mail merge process based on dynamic conditions coming from fields in the template itself. The conditions are not hardcoded in the C# code and should be evaluated within the template. For example, if the “InclExcl” value is “exclude”, I want to hide or remove the entire table row for that officer. I cannot modify the JSON object.
I tried using the FieldMerging event, but it seems to process all rows, and I couldn’t find a way to hide or remove the table row based on the “InclExcl” value.
Could someone please suggest a solution or alternative approach to achieve this functionality using GemBox.Document, considering the dynamic nature of the conditions coming from the template itself?
Then in the FieldMerging event, you could check that the data record for the “MyRange” doesn’t have an “exclude” value for the InclExcl property.
If it does, you can cancel the merging by setting the e.Inline to null. Also, by using the MailMergeClearOptions.RemoveEmptyTableRows the row will be removed because all the fields inside it were canceled.
In other words, something like this:
var source = new[]
{
new { InclExcl = "include", Name="Person 1", Company = "Company 1"},
new { InclExcl = "exclude", Name="Person 2", Company = "Company 2"},
new { InclExcl = "exclude", Name="Person 3", Company = "Company 3"},
new { InclExcl = "include", Name="Person 4", Company = "Company 4"},
new { InclExcl = "include", Name="Person 5", Company = "Company 5"},
new { InclExcl = "exclude", Name="Person 6", Company = "Company 6"},
};
var document = DocumentModel.Load("input.docx");
document.MailMerge.FieldMerging += (sender, e) =>
{
if (!e.IsValueFound || e.Value == null)
return;
if (e.MergeContext.RangeName == "MyRange")
{
dynamic record = e.MergeContext.Record;
if (record.InclExcl == "exclude")
e.Inline = null;
}
};
document.MailMerge.ClearOptions = MailMergeClearOptions.RemoveEmptyTableRows;
document.MailMerge.Execute(source, "MyRange");
document.Save("output.docx");
Thank you for your quick response. The problem with this solution is somehting that I might not state it clearly but I am going to try to restate it:
Conditions are in templates, meaning I can’t code them. I think the only way to do that is using IF fields in combination with COMBINE (I don’t remember the name exactly). Then, when merging, I need to read result and filter out rows didn’t pass validation.
Noe, there is currently no built-in function for this so you’ll need to define some logic that you’ll either handle in the MailMerge.FieldMerging event or after the MailMerge.Execute method.
So, for example, you could have an IF field that would add some custom text which would be an indicator for you to delete that parent row.
In other words, let’s say you have this conditional field:
It’s basically the same, it’s just that in my case I’m searching only the content of the TableRow elements while in your case you’re searching the content of the whole document.
Nevertheless, you could simply your iteration by using the Element.GetParentElements method, like this:
foreach (ContentRange rowContent in document.Content.Find("_delrow").Reverse())
{
Element row = rowContent.Start.Parent.GetParentElements(ElementType.TableRow).FirstOrDefault();
row?.Content.Delete();
}