How to Mail Merge Word Documents in C
IronWord effectue un publipostage en C# en remplissant les espaces réservés MERGEFIELD dans un modèle Word avec vos données, tirées de dictionnaires, objets DataSet, ou tableaux de région répétée, le tout sans Microsoft Office Interop. Les champs de fusion créés dans Microsoft Word, ou tout outil compatible, sont détectés automatiquement.
Le publipostage est le moyen standard de générer des documents personnalisés à grande échelle : lettres types, factures, certificats, contrats et rapports qui partagent un modèle mais diffèrent pour chaque destinataire. Au lieu de modifier chaque document à la main, vous créez un seul modèle .docx avec des champs de fusion et laissez IronWord les remplir à partir de votre source de données. Chaque opération est atteinte par le point d'entrée WordDocument.MailMerge.
Démarrage rapide : Publipostage d'un document Word
Chargez un modèle contenant des espaces réservés MERGEFIELD, passez un dictionnaire de noms et de valeurs de champ à Execute, et enregistrez le résultat.
-
Installez IronWord avec le Gestionnaire de Packages NuGet
-
Copiez et exécutez cet extrait de code.
WordDocument doc = new WordDocument("template.docx"); doc.MailMerge.Execute(new Dictionary<string, string> { { "FirstName", "Jane" }, { "Company", "Acme Corp" } }); doc.SaveAs("output.docx"); -
Déployez pour tester sur votre environnement de production.
Commencez à utiliser IronWord dans votre projet dès aujourd'hui avec un essai gratuit
Flux de travail minimal (5 étapes)
- Téléchargez la bibliothèque C# pour le publipostage Word depuis NuGet
- Créez un modèle Word avec des espaces réservés
MERGEFIELD - Chargez le modèle avec le constructeur
WordDocument - Appelez
MailMerge.ExecuteouMailMerge.ExecuteWithRegionsavec votre source de données - Enregistrer le document rempli
Comment effectuer un publipostage à partir d'un dictionnaire ?
La source de données la plus simple est un IDictionary<string, string> indexé par le nom du champ de fusion. Execute remplace chaque champ dont le nom correspond à une clé.
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")
MailMerge.Options.CaseInsensitiveFieldNames = false pour exiger une correspondance exacte de casse.
Vous pouvez également fournir deux séquences parallèles de noms de champs et de valeurs :
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" })
Execute(fieldNames, values) lance un ArgumentException lorsque les deux séquences ont des longueurs différentes.
Comment effectuer un publipostage à partir d'un DataTable ou DataRow ?
Lorsque les données proviennent d'une base de données ou d'un DataSet existant, passez un DataTable ou DataRow directement à Execute. Les noms de champ de fusion sont appariés avec les noms de colonne. Execute(DataTable) utilise les valeurs de la première ligne du tableau, tandis que Execute(DataRow) utilise les noms de colonne du tableau parent de la ligne.
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")
Comment remplir des régions de tableau répétitives ?
Les régions répétitives transforment une ligne de modèle en plusieurs, ce qui est idéal pour les lignes d'article de facture ou les listes de commandes. Dans le modèle, entourez le contenu répétitif entre deux champs marqueurs nommés TableStart:RegionName et TableEnd:RegionName. Appelez ensuite ExecuteWithRegions, qui répète le contenu de la région une fois par ligne du tableau correspondant.
ExecuteWithRegions accepte un DataSet complet (expansion de chaque région dont le nom correspond à un tableau), un seul DataTable (expansion de la région dont le nom correspond à dataTable.TableName), ou un nom de région avec un 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 ne peuple que les régions répétées. Pour remplir également les champs de fusion standard en dehors des régions, appelez Execute(...) après l'expansion des régions, comme indiqué ci-dessus.Comment inspecter les champs de fusion d'un modèle ?
Avant la fusion, vous pouvez découvrir ce qu'un modèle contient, ce qui est utile pour valider les modèles ou construire dynamiquement la source de données.
GetFieldNames()renvoie les noms de tous les champs de fusion de type valeur, dans l'ordre du document et dédupliqués.GetRegionNames()renvoie les noms de toutes les régionsTableStartdéclarées dans le document.GetFields()renvoie chaque champ, y compris les marqueursTableEnd, sous forme d'objetsMergeField.
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"]
Chaque MergeField expose son Name, le texte complet Instruction tel qu'il est stocké dans le document (par exemple MERGEFIELD FirstName \* MERGEFORMAT), un RegionName qui est défini uniquement pour les marqueurs de région (par exemple "Orders" de "TableStart:Orders"), et un Kind qui classe le champ comme Value (texte remplacé par une valeur de donnée), TableStart ou TableEnd (les limites d'une région répétitive), ou NextRecord (un champ NEXT qui passe au prochain enregistrement de donnée dans le même corps de modèle).
Comment contrôler les champs non appariés et les valeurs nulles ?
Le comportement de fusion est configuré via MailMerge.Options :
| Option | Default | Comportement |
|---|---|---|
RemoveUnusedFields |
true |
Supprime les champs de fusion sans clé correspondante dans la source de données. Réglez sur false pour les laisser en place. |
RemoveUnusedRegions |
true |
Supprime les régions TableEnd sans table correspondante dans la source de données. |
NullValueReplacement |
"" |
Texte substitué lorsque la source de données fournit une valeur null pour un champ. |
CaseInsensitiveFieldNames |
true |
Définit une correspondance insensible à la casse lorsqu'il s'agit d'apparier les noms de champs, en accord avec le comportement de 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")
Pour une substitution de valeur simple sans source de données, voyez comment remplacer le texte dans un document Word.
Questions Fréquemment Posées
Comment puis-je faire un publipostage d'un document Word en C# ?
Chargez un modèle Word contenant des placeholders MERGEFIELD avec le constructeur WordDocument, puis appelez doc.MailMerge.Execute avec un IDictionary, DataTable, ou DataRow pour remplacer chaque champ dont le nom correspond à une clé ou une colonne, et enregistrez le résultat avec SaveAs. Les champs de fusion créés dans Microsoft Word sont détectés automatiquement, et aucune installation de Microsoft Office n'est requise.
Quelles sources de données IronWord peut-il utiliser pour le publipostage?
MailMerge.Execute accepte un IDictionary de noms de champs et valeurs, deux séquences parallèles de noms de champs et valeurs, un DataTable (en utilisant la première ligne), ou un DataRow (en utilisant les colonnes de sa table parente). MailMerge.ExecuteWithRegions accepte un DataSet ou un DataTable pour étendre les régions de tableau répétitives.
Comment puis-je remplir des régions de tableaux répétitifs dans un publipostage Word?
Enveloppez le contenu répétitif dans le modèle entre les champs de fusion TableStart:RégionNom et TableEnd:RégionNom, puis appelez MailMerge.ExecuteWithRegions avec un DataSet ou DataTable. Le contenu de la région se répète une fois par ligne du tableau correspondant. Comme ExecuteWithRegions ne peuple que les régions, appelez Execute ensuite pour remplir les champs de fusion standard.
Puis-je inspecter les champs de fusion d'un modèle avant de fusionner?
Oui. MailMerge.GetFieldNames renvoie les noms de champs de style valeur dans l'ordre du document, GetRegionNames renvoie les noms de régions TableStart, et GetFields renvoie des objets MergeField exposant le Nom, l'Instruction, le Genre (Value, TableStart, TableEnd, ou NextRecord), et le Nom de Région de chaque champ.
Que se passe-t-il pour les champs de fusion sans données correspondantes?
Par défaut, MailMergeOptions.RemoveUnusedFields est true, donc les champs sans clé correspondante dans la source de données sont supprimés de la sortie. Réglez-le sur false pour les laisser en place. Les régions TableStart/TableEnd non correspondantes sont supprimées lorsque RemoveUnusedRegions est true, et les valeurs nulles sont remplacées par la chaîne NullValueReplacement.
La correspondance des champs de fusion est-elle sensible à la casse ?
Non. Les recherches de noms de champs ne sont pas sensibles à la casse par défaut, ce qui correspond au comportement de Microsoft Word. Réglez MailMerge.Options.CaseInsensitiveFieldNames sur false si vous avez besoin d'une correspondance exacte à la casse.

