Skip to content

Commit e0c8d63

Browse files
committed
Modified the sample
1 parent 75e9fde commit e0c8d63

9 files changed

Lines changed: 127 additions & 26 deletions

File tree

49.6 KB
Loading
45.3 KB
Loading
60.7 KB
Loading
48.6 KB
Loading
65 KB
Loading

Mail-Merge/Insert-hyperlink-during-Mailmerge/.NET/Insert-hyperlink-during-Mailmerge/Insert-hyperlink-during-Mailmerge.csproj

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,22 @@
1313
</ItemGroup>
1414

1515
<ItemGroup>
16-
<None Update="Data\Template.docx">
16+
<None Update="Data\Andrew.png">
17+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
18+
</None>
19+
<None Update="Data\EmployeesTemplate.docx">
20+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
21+
</None>
22+
<None Update="Data\Janet.png">
23+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
24+
</None>
25+
<None Update="Data\Margaret.png">
26+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
27+
</None>
28+
<None Update="Data\Nancy.png">
29+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
30+
</None>
31+
<None Update="Data\Steven.png">
1732
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
1833
</None>
1934
<None Update="Output\.gitkeep">

Mail-Merge/Insert-hyperlink-during-Mailmerge/.NET/Insert-hyperlink-during-Mailmerge/Program.cs

Lines changed: 111 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,140 @@ namespace Insert_hyperlink_during_mailmerge
44
{
55
class Program
66
{
7+
static Dictionary<WParagraph, List<int>> paraToInsertHyperlink = new Dictionary<WParagraph, List<int>>();
78
public static void Main(string[] args)
89
{
910
// Open the template Word document
10-
WordDocument document = new WordDocument(Path.GetFullPath(@"Data/Template.docx"));
11-
// Attach the event handler that runs when a merge field is processed
11+
WordDocument document = new WordDocument(Path.GetFullPath(@"Data/EmployeesTemplate.docx"));
12+
// Gets the employee details as IEnumerable collection.
13+
List<Employee> employeeList = GetEmployees();
14+
// Creates an instance of MailMergeDataTable by specifying MailMerge group name and IEnumerable collection.
15+
MailMergeDataTable dataSource = new MailMergeDataTable("Employees", employeeList);
16+
// Uses the mail merge events handler for image fields.
17+
document.MailMerge.MergeImageField += new MergeImageFieldEventHandler(MergeField_EmployeeImage);
18+
// Uses the mail merge event handler for merge fields.
1219
document.MailMerge.MergeField += MailMerge_MergeField;
13-
// Define the merge field names present in the template document
14-
string[] fieldNames = new string[] { "EmployeeId", "Name", "Phone", "City", "Contact" };
15-
// Define the values that will replace the merge fields during mail merge
16-
string[] fieldValues = new string[] { "1001", "Peter", "+122-2222222", "London", "peter@xyz.com" };
17-
//Execute Mail merge
18-
document.MailMerge.Execute(fieldNames, fieldValues);
20+
// Performs Mail merge.
21+
document.MailMerge.ExecuteGroup(dataSource);
22+
// Insert Hyperlink to the merge field text.
23+
InsertHyperlink(document);
1924
// Save the result document
2025
document.Save(Path.GetFullPath(@"../../../Output/output.docx"));
2126
// Close the Word document
2227
document.Close();
2328
}
2429
/// <summary>
25-
/// Event handler that customizes how merge fields are processed.
30+
/// Event handler that customizes how merge fields are processed during mail merge.
2631
/// </summary>
2732
/// <param name="sender">The source object raising the event (MailMerge engine).</param>
2833
/// <param name="args">Provides details about the current merge field being processed</param>
2934
private static void MailMerge_MergeField(object sender, MergeFieldEventArgs args)
3035
{
3136

32-
// Check if the current merge field is "Contact", If Yes this field will be replaced with a hyperlink
37+
// Check if the current merge field is "Contact"
3338
if (args.FieldName == "Contact")
3439
{
35-
// Create a new paragraph and append hyperlink,
36-
WParagraph paragraph = new WParagraph(args.Document);
37-
WField hyperlink = paragraph.AppendHyperlink(args.FieldValue.ToString(), "Click ME", HyperlinkType.WebLink) as WField;
38-
// Get the current merge field object being processed
39-
WField mergeField = args.CurrentMergeField as WField;
40-
// Ensure the merge field exists before replacing it
41-
if (mergeField != null)
40+
// Get the mergefield's Owner paragraph
41+
WParagraph mergeFieldOwnerParagraph = args.CurrentMergeField.OwnerParagraph;
42+
// Check if this paragraph already has an entry in the dictionary.
43+
// If not, create a new list to store field index.
44+
if (!paraToInsertHyperlink.TryGetValue(mergeFieldOwnerParagraph, out var fields))
4245
{
43-
// Get the paragraph that contains the merge field
44-
WParagraph ownerParagraph = mergeField.OwnerParagraph;
45-
// Insert the child entity (e.g., hyperlink) from the new paragraph into the original paragraph
46-
for (int i = 0; i < paragraph.ChildEntities.Count; i++)
46+
fields = new List<int>();
47+
paraToInsertHyperlink[mergeFieldOwnerParagraph] = fields;
48+
}
49+
// Add the current merge field's index
50+
fields.Add(mergeFieldOwnerParagraph.ChildEntities.IndexOf(args.CurrentMergeField));
51+
}
52+
}
53+
/// <summary>
54+
/// Inserts hyperlinks into the Word document at the positions of merge fields
55+
/// </summary>
56+
/// <param name="document">The WordDocument object being processed.</param>
57+
private static void InsertHyperlink(WordDocument document)
58+
{
59+
foreach (KeyValuePair<WParagraph, List<int>> dictionaryItems in paraToInsertHyperlink)
60+
{
61+
// Get the paragraph where Hyperlink needs to be inserted.
62+
WParagraph paragraph = dictionaryItems.Key;
63+
// Get the list of index for the merge fields.
64+
List<int> values = dictionaryItems.Value;
65+
// Iterate through the list in reverse order
66+
for (int i = values.Count - 1; i >= 0; i--)
67+
{
68+
// Get the index of the merge field within the paragraph.
69+
int index = values[i];
70+
// Get the merge field content to insert as Hyperlink.
71+
WTextRange mergeFieldText = paragraph.ChildEntities[index] as WTextRange;
72+
if (mergeFieldText != null)
4773
{
48-
int fieldIndex = ownerParagraph.ChildEntities.IndexOf(mergeField);
49-
ownerParagraph.ChildEntities.Insert(fieldIndex, paragraph.ChildEntities[i].Clone());
74+
WParagraph hyperlinkParagraph = new WParagraph(document);
75+
WField hyperlink = hyperlinkParagraph.AppendHyperlink(mergeFieldText.Text.ToString(), "Click ME", HyperlinkType.WebLink) as WField;
76+
// Insert the child entity (e.g., hyperlink) from the new paragraph into the original paragraph
77+
for (int j = hyperlinkParagraph.ChildEntities.Count - 1; j >= 0; j--)
78+
{
79+
paragraph.ChildEntities.Insert(index, hyperlinkParagraph.ChildEntities[j].Clone());
80+
}
81+
// Remove the original merge field text from the paragraph
82+
paragraph.ChildEntities.Remove(mergeFieldText);
5083
}
51-
// Remove the original merge field from the paragraph
52-
ownerParagraph.ChildEntities.Remove(mergeField);
5384
}
5485
}
86+
paraToInsertHyperlink.Clear();
87+
}
88+
/// <summary>
89+
/// Represents the method that handles MergeImageField event.
90+
/// </summary>
91+
private static void MergeField_EmployeeImage(object sender, MergeImageFieldEventArgs args)
92+
{
93+
//Binds image from file system during mail merge.
94+
if (args.FieldName == "Photo")
95+
{
96+
string photoFileName = args.FieldValue.ToString();
97+
//Gets the image from file system.
98+
FileStream imageStream = new FileStream(Path.GetFullPath(@"Data/" + photoFileName), FileMode.Open, FileAccess.Read);
99+
args.ImageStream = imageStream;
100+
}
101+
}
102+
/// <summary>
103+
/// Gets the employee details to perform mail merge.
104+
/// </summary>
105+
public static List<Employee> GetEmployees()
106+
{
107+
List<Employee> employees = new List<Employee>();
108+
employees.Add(new Employee("Nancy", "Smith", "Sales Representative", "505 - 20th Ave. E. Apt. 2A,", "Seattle", "WA", "USA","nancy.smith@xyz.com", "Nancy.png"));
109+
employees.Add(new Employee("Andrew", "Fuller", "Vice President, Sales", "908 W. Capital Way", "Tacoma", "WA", "USA", "andrew.fuller@xyz.com", "Andrew.png"));
110+
employees.Add(new Employee("Roland", "Mendel", "Sales Representative", "722 Moss Bay Blvd.", "Kirkland", "WA", "USA", "roland.mendel@xyz.com", "Janet.png"));
111+
employees.Add(new Employee("Margaret", "Peacock", "Sales Representative", "4110 Old Redmond Rd.", "Redmond", "WA", "USA", "margaret.peacock@xyz.com", "Margaret.png"));
112+
employees.Add(new Employee("Steven", "Buchanan", "Sales Manager", "14 Garrett Hill", "London", string.Empty, "UK", "steven.buchanan@xyz.com", "Steven.png"));
113+
return employees;
114+
}
115+
/// <summary>
116+
/// Represents a class to maintain employee details.
117+
/// </summary>
118+
public class Employee
119+
{
120+
public string FirstName { get; set; }
121+
public string LastName { get; set; }
122+
public string Address { get; set; }
123+
public string City { get; set; }
124+
public string Region { get; set; }
125+
public string Country { get; set; }
126+
public string Title { get; set; }
127+
public string Contact { get; set; }
128+
public string Photo { get; set; }
129+
public Employee(string firstName, string lastName, string title, string address, string city, string region, string country, string contact, string photoFilePath)
130+
{
131+
FirstName = firstName;
132+
LastName = lastName;
133+
Title = title;
134+
Address = address;
135+
City = city;
136+
Region = region;
137+
Country = country;
138+
Contact = contact;
139+
Photo = photoFilePath;
140+
}
55141
}
56142
}
57143
}

0 commit comments

Comments
 (0)