Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>Merge_markdown_during_mail_merge</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Syncfusion.DocIO.Net.Core" Version="*" />
</ItemGroup>

<ItemGroup>
<None Update="Data\Template.docx">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Output\.gitkeep">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -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<WParagraph, Dictionary<int, string>> paraToInsertMarkdown = new Dictionary<WParagraph, Dictionary<int, string>>();
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
/// <summary>
/// Replaces merge field with Markdown string by using MergeFieldEventHandler.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
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<int, string> fieldValues = new Dictionary<int, string>();
fieldValues.Add(mergeFieldIndex, args.FieldValue.ToString());
//Maintain paragraph in collection.
paraToInsertMarkdown.Add(paragraph, fieldValues);
//Set field value as empty.
args.Text = string.Empty;
}
}
}
/// <summary>
/// Gets the data to perform mail merge
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// Append Markdown to paragraph.
/// </summary>
private static void InsertMarkdown()
{
//Iterates through each item in the dictionary.
foreach (KeyValuePair<WParagraph, Dictionary<int, string>> dictionaryItems in paraToInsertMarkdown)
{
WParagraph paragraph = dictionaryItems.Key as WParagraph;
Dictionary<int, string> values = dictionaryItems.Value as Dictionary<int, string>;
//Iterates through each value in the dictionary.
foreach (KeyValuePair<int, string> 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
}
}
Loading