Cet article explique comment effectuer des opérations de fusion et publipostage dans des documents MS Word à l’aide de Java. À la fin de cet article, vous apprendrez à créer des modèles de publipostage et à exécuter le publipostage par programme.

À propos du publipostage

Mail Merge est un moyen pratique de générer dynamiquement des lettres, des enveloppes, des factures, des rapports et d’autres types de documents. À l’aide du publipostage, vous créez un fichier de modèle contenant les champs de fusion, puis remplissez ces champs à l’aide des données d’une source de données. Supposons que vous deviez envoyer une lettre à 20 personnes différentes et que vous n’ayez qu’à changer le nom et l’adresse des destinataires sur chaque copie. Dans ce cas, vous pouvez créer un modèle de publipostage pour la lettre, puis générer 20 lettres en remplissant dynamiquement les champs de nom et d’adresse.

API Java Mail Merge - Téléchargement gratuit

Aspose.Words for Java est une API de traitement de texte bien connue qui vous permet de créer différents types de documents à partir de zéro. L’API fournit des fonctionnalités intégrées de publipostage qui vous permettent de générer dynamiquement des documents à l’aide de modèles et de sources de données. Aspose.Words for Java peut être téléchargé en tant que JAR ou installé dans les applications basées sur Maven.

<repository>
    <id>AsposeJavaAPI</id>
    <name>Aspose Java API</name>
    <url>https://repository.aspose.com/repo/</url>
</repository>
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>20.11</version>
    <classifier>jdk17</classifier>
</dependency>

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 JSON, XML, une feuille de calcul ou une base de données.

Créer un modèle pour le publipostage dans MS Word

Le modèle utilisé dans le publipostage peut être un simple document Word (c’est-à-dire DOCX) et il n’a pas besoin d’être dans un format de modèle. Le document modèle contient les champs de fusion qui sont remplis avec des données lors de l’exécution du publipostage. Voici les étapes de préparation d’un modèle de publipostage à l’aide de MS Word.

  • Créez un nouveau document 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 au format DOCX.

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

modèle Word de fusion et publipostage

Créer un modèle de publipostage à l’aide de Java

Vous pouvez également générer le modèle de publipostage par programme. Voici les étapes pour cela.

L’exemple de code suivant montre comment créer un modèle de publipostage à l’aide de Java.

// Créer un générateur de documents
DocumentBuilder builder = new DocumentBuilder();

// Insérer un champ de saisie de texte le nom unique de ce champ est "Bonjour", les autres paramètres définissent
// de quel type de FormField il s'agit, le format du texte, le résultat du champ et la longueur maximale du texte (0 = pas de limite)
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Hello", 0);
builder.insertField("MERGEFIELD CustomerFirstName \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD CustomerLastName \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " , ", 0);

// Insérer un saut de paragraphe dans le document
builder.insertParagraph();

// Insérer le corps du message
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Thanks for purchasing our ", 0);
builder.insertField("MERGEFIELD ProductName \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", please download your Invoice at ",
	0);
builder.insertField("MERGEFIELD InvoiceURL \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "",
	". If you have any questions please call ", 0);
builder.insertField("MERGEFIELD Supportphone \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ", or email us at ", 0);
builder.insertField("MERGEFIELD SupportEmail \\* MERGEFORMAT");

builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", ".", 0);

builder.insertParagraph();

// Insérer la fin du courrier
builder.insertTextInput("TextInput", TextFormFieldType.REGULAR, "", "Best regards,", 0);
builder.insertBreak(BreakType.LINE_BREAK);
builder.insertField("MERGEFIELD EmployeeFullname \\* MERGEFORMAT");

builder.insertTextInput("TextInput1", TextFormFieldType.REGULAR, "", " ", 0);
builder.insertField("MERGEFIELD EmployeeDepartment \\* MERGEFORMAT");

// Enregistrer le document
builder.getDocument().save("document.docx");

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

Une fois le modèle prêt, vous pouvez remplir les champs de fusion avec des données. Voici les étapes d’exécution du publipostage sur un modèle Word.

L’exemple de code suivant montre comment effectuer un publipostage dans des documents Word à l’aide de Java.

// Inclure le code de notre modèle
Document doc = new Document();

// Transmettre le document au générateur de documents
DocumentBuilder builder = new DocumentBuilder(doc);

// Créer des champs de fusion
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// Enregistrer le modèle
builder.getDocument().save("MailMerge.TestTemplate.docx");

// Remplir les champs du document avec les données utilisateur
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// Enregistrer le document 
builder.getDocument().save("MailMerge.Simple.docx");

Modèle

publipostage simple en java

Production

publipostage simple

Effectuer un publipostage à l’aide d’une source de données XML

Dans l’exemple précédent, nous avons effectué un publipostage à l’aide des objets Java. Cependant, dans la plupart des cas, une source de données est utilisée pour remplir les champs de fusion. À titre de démonstration, voyons comment utiliser une source de données XML dans le publipostage. Voici les étapes pour cela.

  • Chargez la source de données XML à l’aide de la classe DataSet.
  • Chargez le modèle de publipostage à l’aide de la classe Document.
  • Utilisez la fonction d’exécution pour remplir les champs de fusion à l’aide de la table de données souhaitée dans la source de données.
  • Enregistrez le document Word généré à l’aide de la méthode Document.save(String).

Voici la source de données XML utilisée dans cet exemple.

<?xml version="1.0" encoding="utf-8"?>
<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 montre comment remplir le modèle de publipostage à l’aide de la table de données Customer dans la source de données XML fournie.

// Créer le jeu de données et lire le XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Ouvrir un modèle de document
Document doc = new Document("TestFile XML.docx");

// Exécutez le publipostage pour remplir le modèle avec des données XML à l'aide de DataTable.
// Notez que cette classe fonctionne également avec une seule région répétable (et toutes les régions imbriquées).
// Pour fusionner plusieurs régions en même temps à partir d'une seule source de données XML, utilisez la classe XmlMailMergeDataSet.
// par exemple doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// Enregistrer le document de sortie
doc.save("generated-document.docx");

Modèle

publipostage avec XML

Production

publipostage xml

Fusion et publipostage avec les régions en Java

Dans certains cas, vous devrez peut-être répéter une région particulière dans le document. Par exemple, vous souhaitez afficher les commandes passées par chaque client dans un tableau séparé. Dans de tels cas, vous pouvez tirer parti des régions de publipostage. Pour créer une région, vous pouvez spécifier le début et la fin de la région. Par conséquent, la région sera répétée pour chaque instance des données lors de l’exécution du publipostage.

La capture d’écran suivante montre un modèle dans lequel la région consiste en une table. Il commence par « TableStart : Clients » et se termine par « TableEnd : Clients ».

modèle de région de fusion et publipostage

L’exemple de code suivant montre comment créer un modèle avec des régions et le remplir avec les données.

// Créer un document
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Point de départ du publipostage avec les régions de l'ensemble de données.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Les données des lignes de la colonne "CustomerName" de la table "Customers" iront
// dans ce MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// Créer des en-têtes de colonne
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// Nous avons une deuxième table de données appelée "Orders", qui a un plusieurs à un
// relation avec les "clients"
// ramasser des lignes avec la même valeur CustomerID.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();

// Le point final du publipostage avec les régions.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// Transmettez notre jeu de données pour effectuer un publipostage avec les régions.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// Enregistrer le résultat
doc.save("MailMerge.ExecuteWithRegions.docx");

Production

région de fusion et publipostage

Créer des régions de publipostage imbriquées à l’aide de Java

Un autre scénario populaire dans le publipostage est lorsque vous avez des régions imbriquées. Par exemple, lorsque vous devez répertorier les commandes et les articles de chaque commande, vous pouvez utiliser les régions imbriquées. L’image suivante rend l’image plus claire sur les régions imbriquées.

Dans l’image ci-dessus, nous avons la table Orders et la table Items où chaque enregistrement dans Items est lié à un enregistrement dans Orders. Il existe donc une relation un-à-plusieurs entre ces deux tables. Dans de tels cas, Aspose.Words exécute le publipostage en prenant soin des relations définies dans le DataSet. Par exemple, si nous avons une source de données XML, Aspose.Words utilisera soit les informations de schéma, soit la structure de XML pour découvrir les relations. Ainsi, vous n’aurez pas à le gérer manuellement par vous-même et la méthode Document.getMailMerge().executeWithRegions(DataSet) fonctionnera pour vous (comme dans l’exemple précédent).

Appliquer une mise en forme personnalisée sur les champs de fusion

Afin de vous donner plus de contrôle sur le publipostage, Aspose.Words for Java vous permet de personnaliser les champs de fusion lors de l’exécution du publipostage. La méthode setFieldMergingCallback(IFieldMergingCallback) accepte une classe qui implémente les méthodes fieldMerging(FieldMergingArgs) et imageFieldMerging(ImageFieldMergingArgs) pour un contrôle personnalisé sur le processus de publipostage. L’événement fieldMerging(FieldMergingArgs) se produit lorsqu’un champ de fusion est rencontré lors de l’exécution du publipostage.

Voici l’exemple de code complet expliquant comment personnaliser l’opération de fusion et publipostage et appliquer la mise en forme aux cellules.

public class ApplyCustomFormattingDuringMailMerge {

    private static final String dataDir = Utils.getSharedDataDir(ApplyCustomFormattingDuringMailMerge.class) + "MailMerge/";

    public static void main(String[] args) throws Exception {
        Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

        // Ajoutez un gestionnaire pour l'événement MergeField.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // Exécutez le publipostage avec les régions.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

        doc.save(dataDir + "MailMerge.AlternatingRows Out.doc");
    }

    /**
     * Renvoie vrai si la valeur est impaire ; false si la valeur est paire.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * Créez DataTable et remplissez-le avec des données. Dans la vraie vie, ce DataTable
     * doit être rempli à partir d'une base de données.
     */
    private static DataTable getSuppliersDataTable() throws Exception {
        java.sql.ResultSet resultSet = createCachedRowSet(new String[]{"CompanyName", "ContactName"});

        for (int i = 0; i < 10; i++)
            addRow(resultSet, new String[]{"Company " + Integer.toString(i), "Contact " + Integer.toString(i)});

        return new DataTable(resultSet, "Suppliers");
    }

    /**
     * Une méthode d'assistance qui crée un ResultSet déconnecté Java vide avec
     * les colonnes spécifiées.
     */
    private static ResultSet createCachedRowSet(String[] columnNames) throws Exception {
        RowSetMetaDataImpl metaData = new RowSetMetaDataImpl();
        metaData.setColumnCount(columnNames.length);
        for (int i = 0; i < columnNames.length; i++) {
            metaData.setColumnName(i + 1, columnNames[i]);
            metaData.setColumnType(i + 1, java.sql.Types.VARCHAR);
        }

        CachedRowSet rowSet = RowSetProvider.newFactory().createCachedRowSet();
        ;
        rowSet.setMetaData(metaData);

        return rowSet;
    }

    /**
     * Une méthode d'assistance qui ajoute une nouvelle ligne avec les valeurs spécifiées à un
     * ResultSet déconnecté.
     */
    private static void addRow(ResultSet resultSet, String[] values) throws Exception {
        resultSet.moveToInsertRow();

        for (int i = 0; i < values.length; i++)
            resultSet.updateString(i + 1, values[i]);

        resultSet.insertRow();

        // Cette "danse" est nécessaire pour ajouter correctement des lignes à la fin du jeu de résultats.
        // Si je fais autre chose, des lignes sont soit ajoutées au début, soit au résultat
        // set lève une exception à propos d'une ligne supprimée lors du publipostage.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * Appelé pour chaque champ de fusion rencontré dans le document. Nous pouvons soit
     * renvoyer des données au moteur de publipostage ou faire autre chose avec le
     * document. Dans ce cas, nous modifions le formatage des cellules.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // De cette façon, nous attrapons le début d'une nouvelle ligne.
        if (e.getFieldName().equals("CompanyName")) {
            // Sélectionnez la couleur selon que le numéro de ligne est pair ou impair.
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(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.getCellFormat().getShading().setBackgroundPatternColor(rowColor);
            }

            mRowIdx++;
        }
    }

    public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception {
        // Ne fais rien.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

Conclusion

Le publipostage vous offre un large éventail de fonctionnalités pour générer dynamiquement des documents MS Word. Vous pouvez générer des rapports simples et complexes basés sur les données des bases de données ou d’autres sources de données. Dans cet article, vous avez vu comment implémenter les fonctionnalités de publipostage par programmation à l’aide de Java. Vous pouvez en savoir plus sur l’API Java Mail Merge en utilisant la documentation.

Voir également