diff --git a/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields.sln b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields.sln new file mode 100644 index 000000000..cf3a5aae0 --- /dev/null +++ b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36518.9 d17.14 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apply-custom-formatting-mailmerge-fields", "Apply-custom-formatting-mailmerge-fields\Apply-custom-formatting-mailmerge-fields.csproj", "{F0C26935-893F-44DC-99CE-8AFEF31BF30D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F0C26935-893F-44DC-99CE-8AFEF31BF30D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0C26935-893F-44DC-99CE-8AFEF31BF30D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0C26935-893F-44DC-99CE-8AFEF31BF30D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0C26935-893F-44DC-99CE-8AFEF31BF30D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {04BDD3BB-2942-4C48-8E80-492D6AE1B900} + EndGlobalSection +EndGlobal diff --git a/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Apply-custom-formatting-mailmerge-fields.csproj b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Apply-custom-formatting-mailmerge-fields.csproj new file mode 100644 index 000000000..08e6e345d --- /dev/null +++ b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Apply-custom-formatting-mailmerge-fields.csproj @@ -0,0 +1,24 @@ + + + + Exe + net8.0 + Apply_custom_formatting_mailmerge_fields + enable + enable + + + + + + + + + Always + + + Always + + + + diff --git a/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Data/Template.docx b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Data/Template.docx new file mode 100644 index 000000000..139d72bc5 Binary files /dev/null and b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Data/Template.docx differ diff --git a/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Output/.gitkeep b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Output/.gitkeep new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Output/.gitkeep @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Program.cs b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Program.cs new file mode 100644 index 000000000..aeff876a2 --- /dev/null +++ b/Mail-Merge/Apply-custom-formatting-mailmerge-fields/.NET/Apply-custom-formatting-mailmerge-fields/Program.cs @@ -0,0 +1,146 @@ +using Syncfusion.DocIO.DLS; +using System.Collections.Generic; +using System.Data; + +namespace Apply_custom_formatting_mailmerge_fields +{ + class Program + { + public static Dictionary>> paratoModifyNumberFormat + = new Dictionary>>(); + public static Dictionary>> paratoModifyDateFormat + = new Dictionary>>(); + public static void Main(string[] args) + { + // Load the existing word document + WordDocument document = new WordDocument(Path.GetFullPath(@"Data\Template.docx")); + // Enable separate page for each invoice + document.MailMerge.StartAtNewPage = true; + document.MailMerge.MergeField += new MergeFieldEventHandler(MergeFieldEvent); + // Perform mail merge + document.MailMerge.ExecuteGroup(GetInvoiceData()); + // Update the merge field results with formatted values. + UpdateMergeFieldResult(true); + UpdateMergeFieldResult(false); + // Save the Word document. + document.Save(Path.GetFullPath(@"../../../Output/Output.docx")); + // Close the document + document.Close(); + + } + /// + /// Event handler triggered during mail merge for each merge field. + /// + /// The source of the event (MailMerge engine) + /// Provides information about the current merge field. + private static void MergeFieldEvent(object sender, MergeFieldEventArgs args) + { + // Get the mergefield's Owner paragraph + WParagraph mergeFieldOwnerParagraph = args.CurrentMergeField.OwnerParagraph; + // Find the index of the current merge field within the paragraph. + int index = mergeFieldOwnerParagraph.ChildEntities.IndexOf(args.CurrentMergeField); + if (args.FieldName == "Amount") + { + // Check if this paragraph already has an entry in the dictionary. + // If not, create a new list to store field index and field value. + if (!paratoModifyNumberFormat.TryGetValue(mergeFieldOwnerParagraph, out var fields)) + { + fields = new List>(); + paratoModifyNumberFormat[mergeFieldOwnerParagraph] = fields; + } + // Add the current merge field's index and field name + fields.Add(new KeyValuePair(index, args.FieldValue.ToString())); + } + else if (args.FieldName == "InvoiceDate") + { + // Check if this paragraph already has an entry in the dictionary. + // If not, create a new list to store field index and field value. + if (!paratoModifyDateFormat.TryGetValue(mergeFieldOwnerParagraph, out var fields)) + { + fields = new List>(); + paratoModifyDateFormat[mergeFieldOwnerParagraph] = fields; + } + // Add the current merge field's index and field name + fields.Add(new KeyValuePair(index, args.FieldValue.ToString())); + } + } + /// + /// Updates the merge fields result after mail merge by applying number and date formatting using IF fields. + /// + /// The boolean denotes current changes as Number format + public static void UpdateMergeFieldResult(bool numberType) + { + Dictionary>> mergeFieldResults; + if (numberType) + mergeFieldResults = paratoModifyNumberFormat; + else + mergeFieldResults = paratoModifyDateFormat; + // Iterate the outer dictionary entries + foreach (KeyValuePair>> dictionaryItem in mergeFieldResults) + { + // Get the merge field result paragraph + WParagraph mergeFieldParagraph = dictionaryItem.Key; + // The list of (index, fieldValues) pairs for this paragraph. + List> fieldList = dictionaryItem.Value; + for (int i = 0; i <= fieldList.Count - 1; i++) + { + // Get the index and Field values ("Number" or "Date") + int index = fieldList[i].Key; + string fieldValue = fieldList[i].Value; + // Get the existing merge field result text at the specified index. + WTextRange mergeFieldText = (WTextRange)mergeFieldParagraph.ChildEntities[index]; + if (mergeFieldText != null) + { + // Create the temporary document and insert the IF field. + WordDocument tempDocument = new WordDocument(); + WSection section = (WSection)tempDocument.AddSection(); + WParagraph ifFieldParagraph = (WParagraph)section.AddParagraph(); + WIfField field = (WIfField)ifFieldParagraph.AppendField("IfField", Syncfusion.DocIO.FieldType.FieldIf); + // Check if the Number field value + if (numberType) + { + // Format number: 1,234.56 + field.FieldCode = $"IF 1 = 1 \"{fieldValue}\" \" \" \\# \"#,##0.00"; + } + // Update the Date field value + else + { + // Format date: dd/MMM/yyyy + field.FieldCode = $"IF 1 = 1 \"{fieldValue}\" \" \" \\@ \"dd/MMM/yyyy\" "; + } + // Update the field and unlink + tempDocument.UpdateDocumentFields(); + field.Unlink(); + // Update the Merge field result + WTextRange modifiedText = (WTextRange)ifFieldParagraph.ChildEntities[0]; + mergeFieldText.Text = modifiedText.Text; + // close the temp document + tempDocument.Close(); + } + } + } + if (numberType) + paratoModifyNumberFormat.Clear(); + else + paratoModifyDateFormat.Clear(); + } + private static DataTable GetInvoiceData() + { + DataTable table = new DataTable("Invoice"); + + table.Columns.Add("InvoiceNumber"); + table.Columns.Add("InvoiceDate"); + table.Columns.Add("CustomerName"); + table.Columns.Add("ItemDescription"); + table.Columns.Add("Amount"); + // First Invoice + table.Rows.Add("INV001", "2024-05-01", "Andy Bernard", "Consulting Services", "3,000.578"); + // Second Invoice + table.Rows.Add("INV002", "2024-05-05", "Stanley Hudson", "Software Development", "4,500.052"); + // Third Invoice + table.Rows.Add("INV003", "2024-05-10", "Margaret Peacock", "UI Design Services", "2,000.600"); + + return table; + } + } +} \ No newline at end of file