How to Mail Merge Word Documents in C
IronWord在C#中通过将DataSet对象或重复区域表中提取,无需Microsoft Office Interop。使用Microsoft Word或任何兼容工具创建的合并字段会自动被检测。
邮件合并是大规模生成个性化文档的标准方法:格式信函、发票、证书、合同和共享同一模板但每位收件人不同的报告。 您无需手动编辑每个文档,只需创建一个包含合并字段的.docx模板,让IronWord从您的数据源中填入这些字段。 每个操作都是通过WordDocument.MailMerge入口点进行的。
快速入门:邮件合并一个Word文档
加载一个包含Execute,并保存结果。
-
使用 NuGet 包管理器安装 https://www.nuget.org/packages/IronWord
-
复制并运行这段代码。
WordDocument doc = new WordDocument("template.docx"); doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" }, { "Company", "Acme Corp" } }); doc.SaveAs("output.docx"); -
部署到您的生产环境中进行测试
通过免费试用立即在您的项目中开始使用IronWord
最小工作流程(5 个步骤)
- 从NuGet下载C#库用于Word邮件合并。
- 创作一个带有
MERGEFIELD占位符的Word模板。 - 使用
WordDocument构造函数加载模板。 - 使用您的数据源调用
MailMerge.Execute或MailMerge.ExecuteWithRegions。 - 保存填充的文档
如何从字典进行邮件合并?
最简单的数据源是一个由合并字段名称键入的IDictionary<string, string>。 Execute替换每个名称与键匹配的字段。
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "FirstName", "Jane" },
{ "LastName", "Smith" },
{ "Company", "Acme Corp" }
});
doc.SaveAs("output.docx");
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "FirstName", "Jane" },
{ "LastName", "Smith" },
{ "Company", "Acme Corp" }
});
doc.SaveAs("output.docx");
Dim doc As New WordDocument("template.docx")
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"FirstName", "Jane"},
{"LastName", "Smith"},
{"Company", "Acme Corp"}
})
doc.SaveAs("output.docx")
字段名称查找默认不区分大小写,符合Microsoft Word。 设置MailMerge.Options.CaseInsensitiveFieldNames = false以要求完全对应的大小写匹配。
您还可以提供两个并行的字段名和值序列:
doc.MailMerge.Execute(
new[] { "FirstName", "LastName" },
new[] { "Jane", "Smith" });
doc.MailMerge.Execute(
new[] { "FirstName", "LastName" },
new[] { "Jane", "Smith" });
doc.MailMerge.Execute(
New String() { "FirstName", "LastName" },
New String() { "Jane", "Smith" })
ArgumentException。
如何从DataTable或DataRow进行邮件合并?
当数据来自数据库或现有的Execute。 合并字段名与列名匹配。 Execute(DataRow)使用该行父表的列名。
DataTable table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "Jane";
row["LastName"] = "Smith";
table.Rows.Add(row);
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs("output.docx");
DataTable table = new DataTable();
table.Columns.Add("FirstName");
table.Columns.Add("LastName");
DataRow row = table.NewRow();
row["FirstName"] = "Jane";
row["LastName"] = "Smith";
table.Rows.Add(row);
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs("output.docx");
Imports System.Data
Dim table As New DataTable()
table.Columns.Add("FirstName")
table.Columns.Add("LastName")
Dim row As DataRow = table.NewRow()
row("FirstName") = "Jane"
row("LastName") = "Smith"
table.Rows.Add(row)
Dim doc As New WordDocument("template.docx")
doc.MailMerge.Execute(row)
doc.SaveAs("output.docx")
如何填充重复的表格区域?
重复区域将一个模板行转化为多个,这对于发票行项目或订单列表非常理想。 在模板中,将重复内容包裹在名为TableEnd:RegionName的两个标记字段之间。 然后调用ExecuteWithRegions,它会根据匹配表的每一行重复区域内容。
DataTable一起的区域名称。
DataTable orders = new DataTable("Orders");
orders.Columns.Add("Item");
orders.Columns.Add("Qty");
orders.Rows.Add("Widget A", "3");
orders.Rows.Add("Widget B", "1");
DataSet ds = new DataSet();
ds.Tables.Add(orders);
WordDocument doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(ds);
doc.MailMerge.Execute(new Dictionary<string, string> { { "CustomerName", "Jane Smith" } });
doc.SaveAs("invoice.docx");
DataTable orders = new DataTable("Orders");
orders.Columns.Add("Item");
orders.Columns.Add("Qty");
orders.Rows.Add("Widget A", "3");
orders.Rows.Add("Widget B", "1");
DataSet ds = new DataSet();
ds.Tables.Add(orders);
WordDocument doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(ds);
doc.MailMerge.Execute(new Dictionary<string, string> { { "CustomerName", "Jane Smith" } });
doc.SaveAs("invoice.docx");
Imports System.Data
Imports System.Collections.Generic
Dim orders As New DataTable("Orders")
orders.Columns.Add("Item")
orders.Columns.Add("Qty")
orders.Rows.Add("Widget A", "3")
orders.Rows.Add("Widget B", "1")
Dim ds As New DataSet()
ds.Tables.Add(orders)
Dim doc As New WordDocument("invoice-template.docx")
doc.MailMerge.ExecuteWithRegions(ds)
doc.MailMerge.Execute(New Dictionary(Of String, String) From {{"CustomerName", "Jane Smith"}})
doc.SaveAs("invoice.docx")
ExecuteWithRegions仅填充重复区域。 要填充区域外的标准合并字段,请在扩展区域后调用Execute(...),如上所示。
如何检查模板的合并字段?
在合并之前,您可以发现一个模板包含哪些内容,这对于验证模板或动态构建数据源很有用。
GetFieldNames()返回所有值样式合并字段的名称,按照文档排列并去重。TableStart区域的名称。MergeField对象。
WordDocument doc = new WordDocument("template.docx");
IReadOnlyList<string> fieldNames = doc.MailMerge.GetFieldNames();
IReadOnlyList<string> regionNames = doc.MailMerge.GetRegionNames();
// fieldNames: ["FirstName", "LastName", "Company"]
// regionNames: ["Orders", "LineItems"]
WordDocument doc = new WordDocument("template.docx");
IReadOnlyList<string> fieldNames = doc.MailMerge.GetFieldNames();
IReadOnlyList<string> regionNames = doc.MailMerge.GetRegionNames();
// fieldNames: ["FirstName", "LastName", "Company"]
// regionNames: ["Orders", "LineItems"]
Dim doc As New WordDocument("template.docx")
Dim fieldNames As IReadOnlyList(Of String) = doc.MailMerge.GetFieldNames()
Dim regionNames As IReadOnlyList(Of String) = doc.MailMerge.GetRegionNames()
' fieldNames: ["FirstName", "LastName", "Company"]
' regionNames: ["Orders", "LineItems"]
每个Kind。
如何控制未匹配字段和空值?
合并行为通过MailMerge.Options进行配置:
| 选项 | Default | 行为 |
|---|---|---|
RemoveUnusedFields |
true |
移除数据源中没有匹配键的合并字段。 设置为false以将它们保留在原位。 |
RemoveUnusedRegions |
true |
移除在数据源中无匹配表的TableEnd区域。 |
NullValueReplacement |
"" |
当数据源为字段提供null值时,替换的文本。 |
CaseInsensitiveFieldNames |
true |
在匹配字段名时忽略大小写,符合Microsoft Word行为。 |
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Options.RemoveUnusedFields = false;
doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" } });
doc.SaveAs("partial-output.docx");
WordDocument doc = new WordDocument("template.docx");
doc.MailMerge.Options.RemoveUnusedFields = false;
doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" } });
doc.SaveAs("partial-output.docx");
Dim doc As New WordDocument("template.docx")
doc.MailMerge.Options.RemoveUnusedFields = False
doc.MailMerge.Execute(New Dictionary(Of String, String) From {{"FirstName", "Jane"}})
doc.SaveAs("partial-output.docx")
对于无需数据源的简单值替换,请参阅如何替换Word文档中的文本。
常见问题解答
如何在C#中邮件合并Word文档?
加载一个包含MERGEFIELD占位符的Word模板,使用WordDocument构造函数,然后调用doc.MailMerge.Execute,使用IDictionary, DataTable, 或DataRow替换每个名称匹配键或列的字段,使用SaveAs保存结果。在Microsoft Word中创建的合并字段会自动检测到,不需要安装Microsoft Office。
IronWord邮件合并可以使用哪些数据源?
MailMerge.Execute接受字段名称和值的IDictionary,两个并行的字段名称和值序列,DataTable(使用第一行),或DataRow(使用父表的列)。MailMerge.ExecuteWithRegions接受DataSet或DataTable以扩展重复的表格区域。
如何在Word邮件合并中填充重复的表格区域?
在模板中将重复的内容包裹在TableStart:RegionName和TableEnd:RegionName合并字段之间,然后调用MailMerge.ExecuteWithRegions使用DataSet或DataTable。区域的内容根据匹配表的每一行重复一次。因为ExecuteWithRegions只填充区域,之后需要调用Execute来填充任何标准合并字段。
我可以在合并前检查模板的合并字段吗?
可以。MailMerge.GetFieldNames按文档顺序返回值样式的字段名称,GetRegionNames返回TableStart区域名称,GetFields返回MergeField对象,展示每个字段的Name, Instruction, Kind(Value, TableStart, TableEnd, 或NextRecord),和RegionName。
如果合并字段没有匹配的数据会怎样?
默认情况下,MailMergeOptions.RemoveUnusedFields为true,因此没有匹配键的数据源中的字段会从输出中移除。设置为false以保留它们。未匹配的TableStart/TableEnd区域将在RemoveUnusedRegions为true时移除,null值会替换为NullValueReplacement字符串。
邮件合并字段匹配是区分大小写的吗?
不是。字段名查找默认不区分大小写,与Microsoft Word的行为相符。如需精确大小写匹配,请将MailMerge.Options.CaseInsensitiveFieldNames设置为false。

