diff --git a/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge.sln b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge.sln new file mode 100644 index 000000000..232505ace --- /dev/null +++ b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31911.196 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Merge-markdown-during-mail-merge", "Merge-markdown-during-mail-merge\Merge-markdown-during-mail-merge.csproj", "{38FB99D1-DB4A-4A3F-B90B-7135724337EF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B75368E1-9546-4CD5-BE4C-5C905E8D16C2} + EndGlobalSection +EndGlobal diff --git a/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Data/Template.docx b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Data/Template.docx new file mode 100644 index 000000000..9f0340eb9 Binary files /dev/null and b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Data/Template.docx differ diff --git a/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Merge-markdown-during-mail-merge.csproj b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Merge-markdown-during-mail-merge.csproj new file mode 100644 index 000000000..b1c10e5ea --- /dev/null +++ b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Merge-markdown-during-mail-merge.csproj @@ -0,0 +1,22 @@ + + + + Exe + net8.0 + Merge_markdown_during_mail_merge + + + + + + + + + Always + + + Always + + + + diff --git a/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Output/.gitkeep b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Output/.gitkeep new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Output/.gitkeep @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Program.cs b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Program.cs new file mode 100644 index 000000000..9a0209192 --- /dev/null +++ b/Mail-Merge/Merge-markdown-during-mail-merge/.NET/Merge-markdown-during-mail-merge/Program.cs @@ -0,0 +1,129 @@ +using Syncfusion.DocIO; +using Syncfusion.DocIO.DLS; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Text; + +namespace Merge_markdown_during_mail_merge +{ + class Program + { + static Dictionary> paraToInsertMarkdown = new Dictionary>(); + static void Main(string[] args) + { + using (FileStream inputFileStream = new FileStream(Path.GetFullPath(@"Data/Template.docx"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + //Opens an existing document from stream through constructor of `WordDocument` class. + using (WordDocument document = new WordDocument(inputFileStream, FormatType.Automatic)) + { + //Creates mail merge events handler to replace merge field with HTML. + document.MailMerge.MergeField += new MergeFieldEventHandler(MergeFieldEvent); + //Gets data to perform mail merge. + DataTable table = GetDataTable(); + //Performs the mail merge. + document.MailMerge.Execute(table); + //Append Markdown to paragraph. + InsertMarkdown(); + //Removes mail merge events handler. + document.MailMerge.MergeField -= new MergeFieldEventHandler(MergeFieldEvent); + //Creates file stream. + using (FileStream outputFileStream = new FileStream(Path.GetFullPath(@"Output/Result.docx"), FileMode.Create, FileAccess.ReadWrite)) + { + //Saves the Word document to file stream. + document.Save(outputFileStream, FormatType.Docx); + } + //Closes the document. + document.Close(); + } + } + } + + #region Helper methods + /// + /// Replaces merge field with Markdown string by using MergeFieldEventHandler. + /// + /// + /// + public static void MergeFieldEvent(object sender, MergeFieldEventArgs args) + { + if (args.TableName.Equals("Markdown")) + { + if (args.FieldName.Equals("ProductList")) + { + //Gets the current merge field owner paragraph. + WParagraph paragraph = args.CurrentMergeField.OwnerParagraph; + //Gets the current merge field index in the current paragraph. + int mergeFieldIndex = paragraph.ChildEntities.IndexOf(args.CurrentMergeField); + //Maintain Markdown in collection. + Dictionary fieldValues = new Dictionary(); + fieldValues.Add(mergeFieldIndex, args.FieldValue.ToString()); + //Maintain paragraph in collection. + paraToInsertMarkdown.Add(paragraph, fieldValues); + //Set field value as empty. + args.Text = string.Empty; + } + } + } + /// + /// Gets the data to perform mail merge + /// + /// + private static DataTable GetDataTable() + { + DataTable dataTable = new DataTable("Markdown"); + dataTable.Columns.Add("CustomerName"); + dataTable.Columns.Add("Address"); + dataTable.Columns.Add("Phone"); + dataTable.Columns.Add("ProductList"); + DataRow datarow = dataTable.NewRow(); + dataTable.Rows.Add(datarow); + datarow["CustomerName"] = "Nancy Davolio"; + datarow["Address"] = "59 rue de I'Abbaye, Reims 51100, France"; + datarow["Phone"] = "1-888-936-8638"; + //Markdown content. + string markdown = "# Hello Markdown!\nThis is some **bold** text."; + datarow["ProductList"] = markdown; + return dataTable; + } + /// + /// Append Markdown to paragraph. + /// + private static void InsertMarkdown() + { + //Iterates through each item in the dictionary. + foreach (KeyValuePair> dictionaryItems in paraToInsertMarkdown) + { + WParagraph paragraph = dictionaryItems.Key as WParagraph; + Dictionary values = dictionaryItems.Value as Dictionary; + //Iterates through each value in the dictionary. + foreach (KeyValuePair valuePair in values) + { + int index = valuePair.Key; + string fieldValue = valuePair.Value; + // Convert the markdown string to bytes using UTF-8 encoding + byte[] contentBytes = Encoding.UTF8.GetBytes(fieldValue); + + // Create a MemoryStream from the content bytes + using (MemoryStream memoryStream = new MemoryStream(contentBytes)) + { + //Open the markdown Word document + using (WordDocument markdownDoc = new WordDocument(memoryStream, FormatType.Markdown)) + { + TextBodyPart bodyPart = new TextBodyPart(paragraph.OwnerTextBody.Document); + BodyItemCollection m_bodyItems = bodyPart.BodyItems; + //Copy and paste the markdown at the same position of mergefield in Word document. + foreach (Entity entity in markdownDoc.LastSection.Body.ChildEntities) + { + m_bodyItems.Add(entity.Clone()); + } + bodyPart.PasteAt(paragraph.OwnerTextBody, paragraph.OwnerTextBody.ChildEntities.IndexOf(paragraph), index); + } + } + } + } + paraToInsertMarkdown.Clear(); + } + #endregion + } +}