-
Notifications
You must be signed in to change notification settings - Fork 1
/
Index.razor
186 lines (168 loc) · 7.29 KB
/
Index.razor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
@page "/"
@inject IJSRuntime JS
@using System.IO
@using DevExpress.XtraRichEdit
@using MimeKit;
@using MailKit.Net.Smtp
@using Microsoft.Extensions.Logging
@inject ILogger<Index> logger
<div class="container">
<div class="card mt-3">
<div class="card-header">
Word (RTF) Mail Merge
</div>
<div class="card-body px-0">
<DxFormLayout>
<DxFormLayoutItem ColSpanMd="12">
<Template>
<p>
This example uses the
<a href="https://www.devexpress.com/products/net/office-file-api/word/">Word Processing Document API</a>
to generate personalized letters based on a template. Select a sender and click <b>Send emails</b> to send
letters to all recipients. Click <b>Download</b> to download a letter in PDF format for a specific recipient.
</p>
</Template>
</DxFormLayoutItem>
<DxFormLayoutItem Caption="From:" ColSpanMd="4">
<Template>
<DxComboBox Data="@dataSource.SenderList"
TextFieldName="FullName"
@bind-Value="@SelectedSender" CssClass="p-0" />
</Template>
</DxFormLayoutItem>
<DxFormLayoutItem>
<Template>
<DxButton Click="SendEmails" Text="Send emails" />
</Template>
</DxFormLayoutItem>
</DxFormLayout>
<div class="col">
<DxDataGrid Data="@dataSource.RecipientList"
SelectionMode="DataGridSelectionMode.None"
CssClass="mt-3"
ShowPager="false">
<DxDataGridColumn Field="@nameof(Recipient.ContactName)"
Caption="Recipient" />
<DxDataGridColumn Field="@nameof(Recipient.Email)"
Caption="Email" />
<DxDataGridColumn Caption="Attachment"
Width="150px">
<DisplayTemplate>
@{
var recipient = context as Recipient;
@if (recipient != null) {
<DxButton Text="Download"
CssClass="btn-block"
Click="@((MouseEventArgs args) => DownloadPdf(recipient))"/>
}
}
</DisplayTemplate>
</DxDataGridColumn>
</DxDataGrid>
</div>
</div>
</div>
</div>
@code {
RichEditDocumentServer documentServer = new();
SampleData dataSource = new();
Sender? selectedSender;
Sender? SelectedSender {
get => selectedSender;
set { selectedSender = value;
InvokeAsync(StateHasChanged); }
}
protected override Task OnInitializedAsync() {
selectedSender = dataSource.SenderList[0];
documentServer.LoadDocument("Data/MailMerge.rtf", DocumentFormat.Rtf);
return base.OnInitializedAsync();
}
<!--#region CreateAttachment-->
MemoryStream CreateAttachment(Recipient recipient) {
ArgumentNullException.ThrowIfNull(SelectedSender);
using (var resultDocumentServer = new RichEditDocumentServer())
{
MemoryStream stream = new MemoryStream();
// Fill the data table with information about the selected sender
// and recipient. Use the table as a data source for mail merge.
documentServer.Options.MailMerge.DataSource = dataSource.GetDataSource(SelectedSender, recipient);
documentServer.Options.MailMerge.ViewMergedData = true;
// Execute mail merge.
documentServer.MailMerge(resultDocumentServer.Document);
// Export the result to PDF.
resultDocumentServer.ExportToPdf(stream);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
}
<!--#endregion CreateAttachment-->
void DownloadPdf(Recipient recipient) {
// Execute mail merge.
using (MemoryStream stream = CreateAttachment(recipient))
{
// Download letter in PDF format on the client.
JS.InvokeVoidAsync("exportToPdf", "output.pdf",
Convert.ToBase64String(stream.ToArray()));
}
}
<!--#region SendMessages-->
void SendEmails(MouseEventArgs mouseEventArgs) {
// Obtain a list of recipients.
List<Recipient> recipientList = dataSource.RecipientList;
for (int i = 0; i < recipientList.Count; i++) {
// Execute mail merge to generate a letter for each recipient.
using (MemoryStream attachmentStream = CreateAttachment(recipientList[i])) {
// Create e-mail message for each recipient.
// Attach letter to the message as a PDF file.
MimeMessage message = CreateMessage("YOUR_EMAIL_ADDRESS",
recipientList[i], attachmentStream);
// Send the message.
SendMessage(message);
}
}
}
MimeMessage CreateMessage(string from, Recipient recipient, MemoryStream attachmentStream) {
var message = new MimeMessage();
// Specify the sender's address.
message.From.Add(new MailboxAddress(SelectedSender?.FullName, from));
// Specify the recipient's address.
message.To.Add(new MailboxAddress(recipient.ContactName, recipient.Email));
message.Subject = "Your message subject";
// Create the body of your message.
var body = new TextPart() {
Text = "Your message text"
};
// Create a PDF attachment to send the generated letter.
var attachment = new MimePart("application", "pdf") {
Content = new MimeContent(attachmentStream, ContentEncoding.Default),
ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
ContentTransferEncoding = ContentEncoding.Base64,
FileName = "attachment.pdf"
};
var multipart = new Multipart("mixed");
multipart.Add(body);
multipart.Add(attachment);
message.Body = multipart;
return message;
}
void SendMessage(MimeMessage message) {
using (var client = new SmtpClient()) {
// Connect to your SMTP server to send the message.
// Use one of these ports: 25, 465, 587, or 2525.
client.Connect("MAIL_SERVER", 587, false);
// Use the code below if your SMTP server requires authentication.
client.Authenticate("USERNAME", "PASSWORD");
try {
// Send the message.
client.Send(message);
}
catch(Exception ex) {
logger.LogError(ex.Message);
}
finally {
client.Disconnect(true);
}
}
}
<!--#endregion SendMessages-->
}