Dieser Beitrag behandelt, wie Sie Seriendruckvorgänge in MS Word Dokumenten mit Java durchführen. Am Ende dieses Artikels erfahren Sie, wie Sie Serienbriefvorlagen erstellen und Serienbriefe programmgesteuert ausführen.

Über Seriendruck

Seriendruck ist eine bequeme Möglichkeit, Briefe, Umschläge, Rechnungen, Berichte und andere Arten von Dokumenten dynamisch zu erstellen. Mithilfe von Seriendruck erstellen Sie eine Vorlagendatei mit den Seriendruckfeldern und füllen diese Felder dann mit den Daten in einer Datenquelle aus. Angenommen, Sie müssen einen Brief an 20 verschiedene Personen senden und müssen nur den Namen und die Adresse der Empfänger auf jeder Kopie ändern. In diesem Fall können Sie eine Seriendruckvorlage für den Brief erstellen und dann 20 Briefe generieren, indem Sie die Namens und Adressfelder dynamisch ausfüllen.

Java Mail Merge API – kostenloser Download

Aspose.Words for Java ist eine bekannte Textverarbeitungs-API, mit der Sie verschiedene Arten von Dokumenten von Grund auf neu erstellen können. Die API bietet integrierte Seriendruckfunktionen, mit denen Sie Dokumente mithilfe von Vorlagen und Datenquellen dynamisch generieren können. Aspose.Words for Java kann als JAR heruntergeladen oder innerhalb der Maven-basierten Anwendungen installiert werden.

<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>

Datenquellen für den Seriendruck

Die Daten im Seriendruck können aus jeder Datenquelle wie JSON, XML, Tabellenkalkulation oder einer Datenbank abgerufen werden.

Erstellen Sie eine Vorlage für den Seriendruck in MS Word

Die beim Seriendruck verwendete Vorlage kann ein einfaches Word Dokument sein (z. B. DOCX) und muss nicht in einem Vorlagenformat vorliegen. Das Vorlagendokument enthält die Briefvorlagenfelder, die beim Ausführen des Seriendrucks mit Daten gefüllt werden. Im Folgenden finden Sie die Schritte zum Vorbereiten einer Serienbriefvorlage mit MS Word.

  • Erstellen Sie ein neues Dokument in MS Word.
  • Platzieren Sie den Cursor an der Stelle, an der Sie ein Briefvorlagenfeld hinzufügen möchten.
  • Wählen Sie im Menü Einfügen die Option Feld aus.
  • Wählen Sie aus der Liste Feldnamen MergeField aus.
  • Geben Sie einen Namen für das Briefvorlagenfeld in Feldname ein und drücken Sie OK.
  • Speichern Sie das Dokument als DOCX.

Das Folgende ist der Screenshot des Dokuments Beispielvorlage.

Word-Vorlage für Serienbriefe

Erstellen Sie eine Seriendruckvorlage mit Java

Sie können die Seriendruckvorlage auch programmgesteuert generieren. Im Folgenden sind die Schritte dafür.

Das folgende Codebeispiel zeigt, wie eine Seriendruckvorlage mit Java erstellt wird.

// Dokumentenersteller erstellen
DocumentBuilder builder = new DocumentBuilder();

// Fügen Sie ein Texteingabefeld ein, der eindeutige Name dieses Felds ist „Hallo“, die anderen Parameter definieren
// um welche Art von FormField es sich handelt, das Format des Textes, das Feldergebnis und die maximale Textlänge (0 = keine Begrenzung)
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);

// Fügen Sie einen Absatzumbruch in das Dokument ein
builder.insertParagraph();

// Mailtext einfügen
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();

// Email-Endung einfügen
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");

// Dokument speichern
builder.getDocument().save("document.docx");

Seriendruck in Word Dokument mit Java durchführen

Sobald die Vorlage fertig ist, können Sie die Briefvorlagenfelder mit Daten füllen. Im Folgenden sind die Schritte zum Durchführen eines Seriendrucks für eine Word-Vorlage aufgeführt.

Das folgende Codebeispiel zeigt, wie Serienbriefe in Word Dokumenten mit Java durchgeführt werden.

// Fügen Sie den Code für unsere Vorlage hinzu
Document doc = new Document();

// Übergeben Sie das Dokument an Document Builder
DocumentBuilder builder = new DocumentBuilder(doc);

// Briefvorlagenfelder erstellen
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// Speichern Sie die Vorlage
builder.getDocument().save("MailMerge.TestTemplate.docx");

// Füllen Sie die Felder im Dokument mit Benutzerdaten
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// Speichern Sie das Dokument 
builder.getDocument().save("MailMerge.Simple.docx");

Schablone

Einfacher Seriendruck in Java

Ausgabe

einfacher Seriendruck

Seriendruck mit XML Daten quelle durchführen

Im vorherigen Beispiel haben wir den Seriendruck mit den Java objekten durchgeführt. In den meisten Fällen wird jedoch eine Datenquelle verwendet, um die Briefvorlagenfelder zu füllen. Schauen wir uns zur Demonstration an, wie eine XML Daten quelle im Seriendruck verwendet wird. Im Folgenden sind die Schritte dafür.

  • Laden Sie die XML Daten quelle mithilfe der DataSet Klasse.
  • Laden Sie die Serienbriefvorlage mit der Klasse Document.
  • Verwenden Sie die Ausführungsfunktion, um die Briefvorlagenfelder mit der gewünschten Datentabelle in der Datenquelle zu füllen.
  • Speichern Sie das generierte Word Dokument mit der methode Document.save(String).

Das Folgende ist die XML Daten quelle, die in diesem Beispiel verwendet wird.

<?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> 

Das folgende Codebeispiel zeigt, wie die Serienbriefvorlage mithilfe der Kundendatentabelle in der bereitgestellten XML Daten quelle gefüllt wird.

// Erstellen Sie das Dataset und lesen Sie das XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Öffnen Sie ein Vorlagendokument
Document doc = new Document("TestFile XML.docx");

// Führen Sie einen Seriendruck aus, um die Vorlage mithilfe von DataTable mit Daten aus XML zu füllen.
// Beachten Sie, dass diese Klasse auch mit einem einzelnen wiederholbaren Bereich (und allen verschachtelten Bereichen) funktioniert.
// Um mehrere Regionen gleichzeitig aus einer einzelnen XML Daten quelle zusammenzuführen, verwenden Sie die XmlMailMergeDataSet Klasse.
// zB doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// Speichern Sie das Ausgabedokument
doc.save("generated-document.docx");

Schablone

Seriendruck mit XML

Ausgabe

Seriendruck xml

Seriendruck mit Regionen in Java

In bestimmten Fällen müssen Sie möglicherweise einen bestimmten Bereich im Dokument wiederholen. Beispielsweise möchten Sie die von jedem Kunden aufgegebenen Bestellungen in einer separaten Tabelle anzeigen. In solchen Fällen können Sie die Seriendruckregionen nutzen. Um eine Region zu erstellen, können Sie den Anfang und das Ende der Region festlegen. Daher wird der Bereich während der Ausführung des Seriendrucks für jede Instanz der Daten wiederholt.

Der folgende Screenshot zeigt eine Vorlage, in der die Region aus einer Tabelle besteht. Es beginnt mit «TableStart:Customers» und endet mit «TableEnd:Customers».

Regionsvorlage für Serienbriefe

Das folgende Codebeispiel zeigt, wie eine Vorlage mit Regionen erstellt und mit den Daten gefüllt wird.

// Dokument erstellen
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Der Startpunkt des Seriendrucks mit Regionen das Dataset.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Daten aus Zeilen der Spalte „CustomerName“ der Tabelle „Customers“ werden gelöscht
// in diesem MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// Erstellen Sie Spaltenüberschriften
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// Wir haben eine zweite Datentabelle namens „Bestellungen“, die eine Viele zu Eins-Tabelle enthält
// Beziehung zu "Kunden"
// Abrufen von Zeilen mit demselben CustomerID-Wert.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();

// Der Endpunkt des Seriendrucks mit Regionen.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// Übergeben Sie unser Dataset, um den Seriendruck mit Regionen durchzuführen.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// Speichern Sie das Ergebnis
doc.save("MailMerge.ExecuteWithRegions.docx");

Ausgabe

Seriendruckregion

Erstellen Sie verschachtelte Seriendruckbereiche mit Java

Ein weiteres beliebtes Szenario beim Seriendruck sind verschachtelte Bereiche. Wenn Sie beispielsweise die Bestellungen und die Artikel in jeder Bestellung auflisten müssen, können Sie die verschachtelten Bereiche verwenden. Das folgende Bild macht das Bild über die verschachtelten Bereiche klarer.

In der obigen Abbildung haben wir die Tabelle „Bestellungen“ und die Tabelle „Artikel“, in denen jeder Datensatz in „Artikel“ mit einem Datensatz in „Bestellungen“ verknüpft ist. Daher besteht zwischen diesen beiden Tabellen eine Eins zu Viele-Beziehung. In solchen Fällen führt Aspose.Words den Seriendruck aus und kümmert sich dabei um die im DataSet definierten Beziehungen. Wenn wir beispielsweise eine XML Daten quelle haben, verwendet Aspose.Words entweder die Schemainformationen oder die Struktur von XML, um die Beziehungen herauszufinden. Daher müssen Sie es nicht selbst manuell handhaben, und die Methode Document.getMailMerge().executeWithRegions(DataSet) funktioniert für Sie (wie im vorherigen Beispiel).

Benutzerdefinierte Formatierung auf Briefvorlagenfelder anwenden

Um Ihnen mehr Kontrolle über den Seriendruck zu geben, können Sie in Aspose.Words for Java die Seriendruckfelder während der Ausführung des Seriendrucks anpassen. Die Methode setFieldMergingCallback(IFieldMergingCallback) akzeptiert eine Klasse, die die Methoden fieldMerging(FieldMergingArgs) und imageFieldMerging(ImageFieldMergingArgs) zur benutzerdefinierten Steuerung des Seriendruckprozesses implementiert. Das fieldMerging(FieldMergingArgs)-Ereignis tritt auf, wenn während der Serienbriefausführung ein Briefvorlagenfeld gefunden wird.

Im Folgenden finden Sie das vollständige Codebeispiel zum Anpassen des Seriendruckvorgangs und zum Anwenden der Formatierung auf die Zellen.

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");

        // Fügen Sie einen Handler für das MergeField-Ereignis hinzu.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // Seriendruck mit Regionen ausführen.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

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

    /**
     * Gibt true zurück, wenn der Wert ungerade ist; false, wenn der Wert gerade ist.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * DataTable erstellen und mit Daten füllen. Im wirklichen Leben diese DataTable
     * sollte aus einer Datenbank gefüllt werden.
     */
    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");
    }

    /**
     * Eine Hilfsmethode, die ein leeres, nicht verbundenes Java-ResultSet mit erstellt
     * die angegebenen Spalten.
     */
    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;
    }

    /**
     * Eine Hilfsmethode, die eine neue Zeile mit den angegebenen Werten zu a hinzufügt
     * getrennte Ergebnismenge.
     */
    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();

        // Dieser "Tanz" wird benötigt, um Zeilen richtig am Ende der Ergebnismenge hinzuzufügen.
        // Wenn ich etwas anderes mache, werden Zeilen entweder vorne hinzugefügt oder das Ergebnis
        // set löst eine Ausnahme über eine gelöschte Zeile während des Seriendrucks aus.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * Wird für jedes im Dokument gefundene Briefvorlagenfeld aufgerufen. Wir können beides
     * einige Daten an die Mail-Merge-Engine zurückgeben oder etwas anderes damit machen
     * dokumentieren. In diesem Fall ändern wir die Zellenformatierung.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // Auf diese Weise fangen wir den Anfang einer neuen Reihe.
        if (e.getFieldName().equals("CompanyName")) {
            // Wählen Sie die Farbe abhängig davon, ob die Zeilennummer gerade oder ungerade ist.
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(242, 242, 242);

            // Momentan gibt es keine Möglichkeit, Zelleigenschaften für die gesamte Zeile festzulegen.
            // also müssen wir über alle Zellen in der Zeile iterieren.
            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 {
        // Nichts tun.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

Fazit

Mail Merge bietet Ihnen eine Vielzahl von Funktionen, um MS Word Dokumente dynamisch zu erstellen. Sie können einfache sowie komplexe Berichte basierend auf den Daten in Datenbanken oder anderen Datenquellen erstellen. In diesem Artikel haben Sie gesehen, wie Sie die Seriendruckfunktionen programmgesteuert mit Java implementieren. Weitere Informationen zur Java Mail Merge API finden Sie in der Dokumentation.

Siehe auch