Skip to content

Commit a1a7a3a

Browse files
Merge pull request #336 from SyncfusionExamples/Replace-merge-field-with-markdown
ES-846413 - Add the sample Merge_markdown_during_mail_merge
2 parents a5195a8 + c0c47cc commit a1a7a3a

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31911.196
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
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}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{38FB99D1-DB4A-4A3F-B90B-7135724337EF}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {B75368E1-9546-4CD5-BE4C-5C905E8D16C2}
24+
EndGlobalSection
25+
EndGlobal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<RootNamespace>Merge_markdown_during_mail_merge</RootNamespace>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Syncfusion.DocIO.Net.Core" Version="*" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<None Update="Data\Template.docx">
15+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
16+
</None>
17+
<None Update="Output\.gitkeep">
18+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
19+
</None>
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using Syncfusion.DocIO;
2+
using Syncfusion.DocIO.DLS;
3+
using System.Collections.Generic;
4+
using System.Data;
5+
using System.IO;
6+
using System.Text;
7+
8+
namespace Merge_markdown_during_mail_merge
9+
{
10+
class Program
11+
{
12+
static Dictionary<WParagraph, Dictionary<int, string>> paraToInsertMarkdown = new Dictionary<WParagraph, Dictionary<int, string>>();
13+
static void Main(string[] args)
14+
{
15+
using (FileStream inputFileStream = new FileStream(Path.GetFullPath(@"Data/Template.docx"), FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
16+
{
17+
//Opens an existing document from stream through constructor of `WordDocument` class.
18+
using (WordDocument document = new WordDocument(inputFileStream, FormatType.Automatic))
19+
{
20+
//Creates mail merge events handler to replace merge field with HTML.
21+
document.MailMerge.MergeField += new MergeFieldEventHandler(MergeFieldEvent);
22+
//Gets data to perform mail merge.
23+
DataTable table = GetDataTable();
24+
//Performs the mail merge.
25+
document.MailMerge.Execute(table);
26+
//Append Markdown to paragraph.
27+
InsertMarkdown();
28+
//Removes mail merge events handler.
29+
document.MailMerge.MergeField -= new MergeFieldEventHandler(MergeFieldEvent);
30+
//Creates file stream.
31+
using (FileStream outputFileStream = new FileStream(Path.GetFullPath(@"Output/Result.docx"), FileMode.Create, FileAccess.ReadWrite))
32+
{
33+
//Saves the Word document to file stream.
34+
document.Save(outputFileStream, FormatType.Docx);
35+
}
36+
//Closes the document.
37+
document.Close();
38+
}
39+
}
40+
}
41+
42+
#region Helper methods
43+
/// <summary>
44+
/// Replaces merge field with Markdown string by using MergeFieldEventHandler.
45+
/// </summary>
46+
/// <param name="sender"></param>
47+
/// <param name="args"></param>
48+
public static void MergeFieldEvent(object sender, MergeFieldEventArgs args)
49+
{
50+
if (args.TableName.Equals("Markdown"))
51+
{
52+
if (args.FieldName.Equals("ProductList"))
53+
{
54+
//Gets the current merge field owner paragraph.
55+
WParagraph paragraph = args.CurrentMergeField.OwnerParagraph;
56+
//Gets the current merge field index in the current paragraph.
57+
int mergeFieldIndex = paragraph.ChildEntities.IndexOf(args.CurrentMergeField);
58+
//Maintain Markdown in collection.
59+
Dictionary<int, string> fieldValues = new Dictionary<int, string>();
60+
fieldValues.Add(mergeFieldIndex, args.FieldValue.ToString());
61+
//Maintain paragraph in collection.
62+
paraToInsertMarkdown.Add(paragraph, fieldValues);
63+
//Set field value as empty.
64+
args.Text = string.Empty;
65+
}
66+
}
67+
}
68+
/// <summary>
69+
/// Gets the data to perform mail merge
70+
/// </summary>
71+
/// <returns></returns>
72+
private static DataTable GetDataTable()
73+
{
74+
DataTable dataTable = new DataTable("Markdown");
75+
dataTable.Columns.Add("CustomerName");
76+
dataTable.Columns.Add("Address");
77+
dataTable.Columns.Add("Phone");
78+
dataTable.Columns.Add("ProductList");
79+
DataRow datarow = dataTable.NewRow();
80+
dataTable.Rows.Add(datarow);
81+
datarow["CustomerName"] = "Nancy Davolio";
82+
datarow["Address"] = "59 rue de I'Abbaye, Reims 51100, France";
83+
datarow["Phone"] = "1-888-936-8638";
84+
//Markdown content.
85+
string markdown = "# Hello Markdown!\nThis is some **bold** text.";
86+
datarow["ProductList"] = markdown;
87+
return dataTable;
88+
}
89+
/// <summary>
90+
/// Append Markdown to paragraph.
91+
/// </summary>
92+
private static void InsertMarkdown()
93+
{
94+
//Iterates through each item in the dictionary.
95+
foreach (KeyValuePair<WParagraph, Dictionary<int, string>> dictionaryItems in paraToInsertMarkdown)
96+
{
97+
WParagraph paragraph = dictionaryItems.Key as WParagraph;
98+
Dictionary<int, string> values = dictionaryItems.Value as Dictionary<int, string>;
99+
//Iterates through each value in the dictionary.
100+
foreach (KeyValuePair<int, string> valuePair in values)
101+
{
102+
int index = valuePair.Key;
103+
string fieldValue = valuePair.Value;
104+
// Convert the markdown string to bytes using UTF-8 encoding
105+
byte[] contentBytes = Encoding.UTF8.GetBytes(fieldValue);
106+
107+
// Create a MemoryStream from the content bytes
108+
using (MemoryStream memoryStream = new MemoryStream(contentBytes))
109+
{
110+
//Open the markdown Word document
111+
using (WordDocument markdownDoc = new WordDocument(memoryStream, FormatType.Markdown))
112+
{
113+
TextBodyPart bodyPart = new TextBodyPart(paragraph.OwnerTextBody.Document);
114+
BodyItemCollection m_bodyItems = bodyPart.BodyItems;
115+
//Copy and paste the markdown at the same position of mergefield in Word document.
116+
foreach (Entity entity in markdownDoc.LastSection.Body.ChildEntities)
117+
{
118+
m_bodyItems.Add(entity.Clone());
119+
}
120+
bodyPart.PasteAt(paragraph.OwnerTextBody, paragraph.OwnerTextBody.ChildEntities.IndexOf(paragraph), index);
121+
}
122+
}
123+
}
124+
}
125+
paraToInsertMarkdown.Clear();
126+
}
127+
#endregion
128+
}
129+
}

0 commit comments

Comments
 (0)