How to Mail Merge Word Documents in C

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronWord在C#中通过将DataSet对象或重复区域表中提取,无需Microsoft Office Interop。使用Microsoft Word或任何兼容工具创建的合并字段会自动被检测。

邮件合并是大规模生成个性化文档的标准方法:格式信函、发票、证书、合同和共享同一模板但每位收件人不同的报告。 您无需手动编辑每个文档,只需创建一个包含合并字段的.docx模板,让IronWord从您的数据源中填入这些字段。 每个操作都是通过WordDocument.MailMerge入口点进行的。

快速入门:邮件合并一个Word文档

加载一个包含Execute,并保存结果。

  1. 使用 NuGet 包管理器安装 https://www.nuget.org/packages/IronWord

    PM > Install-Package IronWord
  2. 复制并运行这段代码。

    WordDocument doc = new WordDocument("template.docx");
    doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" }, { "Company", "Acme Corp" } });
    doc.SaveAs("output.docx");
  3. 部署到您的生产环境中进行测试

    通过免费试用立即在您的项目中开始使用IronWord

    arrow pointer


如何从字典进行邮件合并?

最简单的数据源是一个由合并字段名称键入的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")
$vbLabelText   $csharpLabel

字段名称查找默认不区分大小写,符合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" })
$vbLabelText   $csharpLabel

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")
$vbLabelText   $csharpLabel

如何填充重复的表格区域?

重复区域将一个模板行转化为多个,这对于发票行项目或订单列表非常理想。 在模板中,将重复内容包裹在名为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")
$vbLabelText   $csharpLabel

请注意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"]
$vbLabelText   $csharpLabel

每个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")
$vbLabelText   $csharpLabel

对于无需数据源的简单值替换,请参阅如何替换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。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 48,355 | 版本: 2026.7 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronWord
运行示例 观看您的数据变成 Word 文档。