Dans cet article, je vais vous montrer comment effectuer une fusion et publipostage MS Word à l’aide de C# ou VB.NET sans MS Word ou Office Interop. Aspose.Words for .NET est une API Word riche en fonctionnalités et puissante qui fournit toutes les fonctionnalités de base et étendues de publipostage MS Word. Il vous permet de générer des lettres, des enveloppes, des rapports, des factures et d’autres types de documents dans les formulaires Windows, les applications Web ASP.NET ou toute application .NET/.NET Core.

Couvrant les principales fonctionnalités de notre API .NET Mail Merge, cet article est composé des sections suivantes :

Qu’est-ce que le publipostage ?

Mail Merge est le moyen de générer automatiquement des rapports, des lettres, des enveloppes, des factures et d’autres types de documents. Le publipostage dans MS Word vous permet de créer un modèle de document contenant des champs de fusion, puis de remplir ces champs à l’aide d’enregistrements dans la source de données. Pour comprendre le publipostage, supposons que vous deviez envoyer une lettre à dix personnes différentes et que seuls le nom et les champs d’adresse soient mis à jour. Dans ce cas, créez simplement un modèle de lettre, puis générez dynamiquement les lettres en remplissant les champs de fusion de nom et d’adresse à l’aide de la source de données.

Sources de données pour le publipostage

Les données du publipostage peuvent être extraites de n’importe quelle source de données telle que XML, JSON ou une base de données. En ce qui concerne Aspose.Words for .NET, vous pouvez utiliser n’importe quelle source de données prise en charge par ADO.NET. Les données peuvent être chargées dans un DataSet, un DataTable, un DataView ou un tableau de valeurs.

Préparation du modèle pour le publipostage

Le modèle de publipostage est le document qui contient les champs de fusion. Ces champs sont ensuite renseignés avec les données de la source de données lors de l’exécution du publipostage. Le document modèle n’a pas besoin d’être un format de modèle et il peut s’agir d’un document DOC/DOCX. Voici comment vous pouvez préparer un modèle pour le publipostage.

  • Ouvrez votre document ou créez-en un nouveau dans MS Word.
  • Placez le curseur à l’endroit où vous souhaitez ajouter un champ de fusion.
  • Dans le menu Insertion, sélectionnez l’option Champ.
  • Dans la liste Noms de champs, sélectionnez MergeField.
  • Entrez un nom pour le champ de fusion dans Nom du champ et appuyez sur OK.
  • Enregistrez le document.

Voici la capture d’écran du document exemple de modèle.

Modèle de publipostage

API de fusion et publipostage .NET - Installation

Aspose.Words for .NET peut être téléchargé ou installé de la manière suivante :

Effectuer une fusion et publipostage dans un document Word à l’aide de C#

Une fois le modèle prêt, vous pouvez exécuter le publipostage pour générer les documents. Voici les étapes pour exécuter le publipostage sur le modèle mentionné ci-dessus.

L’exemple de code suivant montre comment exécuter le publipostage MS Word à l’aide d’un tableau de valeurs en C#.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
// Chemin d'accès au répertoire des documents.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
// Ouvrir un document existant.
Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc");

// Couper les valeurs de publipostage des espaces blancs de fin et de début
doc.MailMerge.TrimWhitespaces = false;

// Remplissez les champs du document avec les données de l'utilisateur.
doc.MailMerge.Execute(
    new string[] { "FullName", "Company", "Address", "Address2", "City" },
    new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" });

dataDir = dataDir + "MailMerge.ExecuteArray_out.doc";
// Envoyez le document au format Word au navigateur client avec une option pour enregistrer sur le disque ou ouvrir dans le navigateur actuel.
doc.Save(dataDir);

Document Word après publipostage

Exécuter le publipostage en C#

Effectuer une fusion et publipostage à l’aide d’une source de données XML en C#

Les fichiers XML sont largement utilisés pour conserver ainsi que pour importer/exporter des données. Aspose.Words for .NET prend également en charge XML comme source de données pour le publipostage. Il suffit de lire le XML dans un objet DataSet et d’exécuter le publipostage. Voici l’exemple de fichier XML que nous allons utiliser.

<customers>
<customer Name="John Ben Jan" ID="1" Domain="History" City="Boston"/>
<customer Name="Lisa Lane" ID="2" Domain="Chemistry" City="LA"/>
<customer Name="Dagomir Zits" ID="3" Domain="Heraldry" City="Milwaukee"/>
<customer Name="Sara Careira Santy" ID="4" Domain="IT" City="Miami"/>
</customers>

L’exemple de code suivant extrait les données d’une source de données XML et exécute le publipostage à l’aide de C#.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
// Chemin d'accès au répertoire des documents.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 

// Créez le jeu de données et lisez le XML.
DataSet customersDs = new DataSet();
customersDs.ReadXml(dataDir + "Customers.xml");

string fileName = "TestFile XML.doc";
// Ouvrez un document modèle.
Document doc = new Document(dataDir + fileName);

// Exécutez le publipostage pour remplir le modèle avec des données XML à l'aide de DataTable.
doc.MailMerge.Execute(customersDs.Tables["Customer"]);

dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// Enregistrez le document de sortie.
doc.Save(dataDir);

Vous trouverez ci-dessous le modèle de publipostage qui sera rempli avec des données XML.

Modèle de publipostage pour XML

Ce qui suit est la page 1 du document Word résultant que nous obtenons après l’exécution du publipostage.

Exécuter le publipostage avec XML en C#

Formatage personnalisé des champs de fusion

Aspose.Words for .NET vous donne plus de contrôle sur le publipostage pendant l’exécution. La propriété MailMerge.FieldMergingCallback vous permet de personnaliser le publipostage lorsqu’un champ de fusion est rencontré. MailMerge.FieldMergingCallback accepte la classe implémentant les méthodes IFieldMergingCallback.FieldMerging et IFieldMergingCallback.ImageFieldMerging.

L’exemple de code suivant montre comment personnaliser l’opération de fusion et publipostage et appliquer la mise en forme aux cellules de ce modèle.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
// Chemin d'accès au répertoire des documents.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

// Ajoutez un gestionnaire pour l'événement MergeField.
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();

// Exécutez le publipostage avec les régions.
DataTable dataTable = GetSuppliersDataTable();
doc.MailMerge.ExecuteWithRegions(dataTable);
dataDir = dataDir + "MailMerge.AlternatingRows_out.doc";
doc.Save(dataDir);

Voici l’implémentation de la classe HandleMergeFieldAlternatingRows.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
    ///<summary>
    /// Appelé pour chaque champ de fusion rencontré dans le document.
    /// Nous pouvons soit renvoyer des données au moteur de publipostage, soit faire quelque chose
    /// Sinon avec le document. Dans ce cas, nous modifions le formatage des cellules.
    ///</summary>
    void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
    {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.Document);

        // De cette façon, nous attrapons le début d'une nouvelle ligne.
        if (e.FieldName.Equals("CompanyName"))
        {
            // Sélectionnez la couleur selon que le numéro de ligne est pair ou impair.
            Color rowColor;
            if (IsOdd(mRowIdx))
                rowColor = Color.FromArgb(213, 227, 235);
            else
                rowColor = Color.FromArgb(242, 242, 242);

            // Il n'y a aucun moyen de définir les propriétés de cellule pour toute la ligne pour le moment,
            // Nous devons donc parcourir toutes les cellules de la ligne.
            for (int colIdx = 0; colIdx < 4; colIdx++)
            {
                mBuilder.MoveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.CellFormat.Shading.BackgroundPatternColor = rowColor;
            }

            mRowIdx++;
        }
    }

    void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
    {
        // Ne fais rien.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}     
///<summary>
/// Renvoie vrai si la valeur est impaire ; false si la valeur est paire.
///</summary>
private static bool IsOdd(int value)
{
    // Le code est un peu complexe, mais sinon la conversion automatique en VB ne fonctionne pas.
    return ((value / 2) * 2).Equals(value);
}      
///<summary>
/// Créez DataTable et remplissez-le avec des données.
/// Dans la vraie vie, ce DataTable devrait être rempli à partir d'une base de données.
///</summary>
private static DataTable GetSuppliersDataTable()
{
    DataTable dataTable = new DataTable("Suppliers");
    dataTable.Columns.Add("CompanyName");
    dataTable.Columns.Add("ContactName");
    for (int i = 0; i < 10; i++)
    {
        DataRow datarow = dataTable.NewRow();
        dataTable.Rows.Add(datarow);
        datarow[0] = "Company " + i.ToString();
        datarow[1] = "Contact " + i.ToString();
    }
    return dataTable;
}

Fusion et publipostage avec les régions à l’aide de C#

Il peut arriver que vous ayez besoin de remplir et de répéter une région particulière dans le document Word. Dans un tel cas, vous pouvez utiliser le publipostage avec les régions. Pour créer une région, vous devez spécifier le début et la fin de la région, puis Mail Megre répétera cette région pour chaque enregistrement dans la source de données. Par exemple, le modèle suivant contient deux régions, Orders et OrderDetails avec les champs de fusion « TableStart:Orders », « TableEnd:Orders » et « TableStart:OrderDetails », « TableEnd:OrderDetails » respectivement.

Fusion et publipostage avec les régions

Voici l’exemple de code qui exécute Mail Megre sur les régions pour le template mentionné ci-dessus.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
// Chemin d'accès au répertoire des documents.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
string fileName = "MailMerge.ExecuteWithRegions.doc";
Document doc = new Document(dataDir + fileName);
 
// Utilisez DataTable comme source de données.
int orderId = 10444;
DataTable orderTable = GetTestOrder(orderId);
doc.MailMerge.ExecuteWithRegions(orderTable);
 
// Au lieu d'utiliser DataTable, vous pouvez créer un DataView pour un tri ou un filtre personnalisé, puis le publipostage.
DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId));
orderDetailsView.Sort = "ExtendedPrice DESC";
 
// Exécutez l'opération de fusion et publipostage.
doc.MailMerge.ExecuteWithRegions(orderDetailsView);
 
// Enregistrez le document fusionné.
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
doc.Save(dataDir);

Voici les méthodes pour lire les données de la base de données.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
private static DataTable GetTestOrder(int orderId)
{
    DataTable table = ExecuteDataTable(string.Format(
        "SELECT * FROM AsposeWordOrders WHERE OrderId = {0}", orderId));
    table.TableName = "Orders";
    return table;
}
private static DataTable GetTestOrderDetails(int orderId)
{
    DataTable table = ExecuteDataTable(string.Format(
        "SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {0} ORDER BY ProductID", orderId));
    table.TableName = "OrderDetails";
    return table;
}
///<summary>
/// Fonction utilitaire qui crée une connexion, commande, 
/// Exécute la commande et renvoie le résultat dans un DataTable.
///</summary>
private static DataTable ExecuteDataTable(string commandText)
{
    // Ouvrez la connexion à la base de données.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
        RunExamples.GetDataDir_Database() + "Northwind.mdb";
    OleDbConnection conn = new OleDbConnection(connString);
    conn.Open();

    // Créer et exécuter une commande.
    OleDbCommand cmd = new OleDbCommand(commandText, conn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);
    DataTable table = new DataTable();
    da.Fill(table);

    // Fermez la base de données.
    conn.Close();

    return table;
}

Régions de publipostage imbriquées

Le plus souvent, les données que nous avons dans la source de données se présentent sous la forme de relations. Par exemple, la table “Order” aura une relation un-à-plusieurs avec “OrderDetails” qui conservera les enregistrements des articles d’une commande. Pour gérer ces relations parent-enfant, le publipostage imbriqué est utilisé. Voici un exemple de modèle de facture qui convient bien à ce scénario.

Modèle de publipostage avec régions

Voici l’exemple de source de données XML que nous utiliserons pour le publipostage imbriqué.

<?xml version="1.0" encoding="utf-8"?>
<Orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="OrdersSchema.xsd">
  <Order>
    <Number>23</Number>
    <Address>Nelson Street</Address>
    <Suburb>Howick</Suburb>
    <City>Auckland</City>
    <Phonenumber>543 1234</Phonenumber>
    <Date>03/01/2010</Date>
    <Total>14.00</Total>
    <Item>
      <Name>BBQ Chicken Pizza</Name>
      <Price>6.00</Price>
      <Quantity>1</Quantity>
      <ItemTotal>6.00</ItemTotal>
    </Item>
    <Item>
      <Name>1.5 Litre Coke</Name>
      <Price>4.00</Price>
      <Quantity>2</Quantity>
      <ItemTotal>8.00</ItemTotal>
    </Item>
  </Order>
  <Order>
    <Number>10</Number>
    <Address>Parkville Avenue</Address>
    <Suburb>Pakuranga</Suburb>
    <City>Auckland</City>
    <Phonenumber>548 7342</Phonenumber>
    <Date>05/03/2010</Date>
    <Total>6.00</Total>
    <Item>
      <Name>Hawaiian Pizza</Name>
      <Price>4.00</Price>
      <Quantity>1</Quantity>
      <ItemTotal>4.00</ItemTotal>
    </Item>
    <Item>
      <Name>Fries</Name>
      <Price>1.00</Price>
      <Quantity>2</Quantity>
      <ItemTotal>2.00</ItemTotal>
    </Item>
  </Order>
</Orders>

Alors que OrderSchema.xsd pour ce XML est :

<?xml version="1.0" encoding ="utf-8"?>
<xs:schema id="OrdersSchema"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="Orders">
 <xs:complexType>
 <xs:sequence>
  <xs:element name="Order">
  <xs:complexType>
  <xs:sequence>
  <xs:element name="Number"/>
  <xs:element name="Address"/>
  <xs:element name="Suburb"/>
  <xs:element name="City"/>
  <xs:element name="Phonenumber">
  <xs:element name="Date"/>
  <xs:element name="Total"/>
  <xs:element name="Item">
   <xs:complexType>
   <xs:sequence>
   <xs:element name="Name"/>
   <xs:element name="Price"/>
   <xs:element name="Quantity"/>
   <xs:element name="ItemTotal"/>
   </xs:sequence>
  </xs:complexType>
  </xs:element>
  </xs:sequence>
  </xs:complexType>
 </xs:element>
 </xs:sequence>
 </xs:complexType>
 </xs:element>
</xs:schema>

L’exemple de code suivant est utilisé pour exécuter le publipostage imbriqué à l’aide de C#.

// Pour des exemples complets et des fichiers de données, rendez-vous sur https://github.com/aspose-words/Aspose.Words-for-.NET
// Chemin d'accès au répertoire des documents.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
	 
// Créez le jeu de données et lisez le XML.
DataSet pizzaDs = new DataSet();
	 
// Le Datatable.TableNames et le DataSet.Relations sont définis implicitement par .NET via ReadXml.
pizzaDs.ReadXml(dataDir + "CustomerData.xml");
string fileName = "Invoice Template.doc";

// Ouvrez le modèle de document.
Document doc = new Document(dataDir + fileName);
	 
// Coupez les valeurs de publipostage des espaces blancs de fin et de début.
doc.MailMerge.TrimWhitespaces = false;
	 
// Exécutez le publipostage imbriqué avec les régions.
doc.MailMerge.ExecuteWithRegions(pizzaDs);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);

// Enregistrez la sortie dans un fichier.
doc.Save(dataDir);

Debug.Assert(doc.MailMerge.GetFieldNames().Length == 0, "There was a problem with mail merge");
Console.WriteLine("\nMail merge performed with nested data successfully.\nFile saved at " + dataDir);

Document Word après publipostage

Ci-dessous se trouve la première page du document Word résultant après l’exécution du publipostage.

Document Word après publipostage

Conclusion

Aspose.Words for .NET est une API de publipostage riche en fonctionnalités qui fournit toutes les fonctionnalités de publipostage standard et étendues pour les applications .NET. En quelques lignes de code, vous pouvez créer en toute transparence des rapports simples ou complexes à partir de différents types de sources de données. Vous pouvez en savoir plus sur l’API .NET Mail Merge dans la documentation. Pour en savoir plus sur Aspose.Words for .NET, commencez par les guides du développeur et les exemples de code GitHub.

Essayez gratuitement Aspose.Words for .NET

Vous pouvez obtenir une licence temporaire gratuite pour essayer Aspose.Words for .NET sans aucune limitation. Obtenez votre licence temporaire maintenant.

Voir également