Det här inlägget täcker hur man utför Mail Merge-operationer i MS Word-dokument med Java. I slutet av den här artikeln kommer du att lära dig hur du skapar Mail Merge-mallar och exekverar Mail Merge programmatiskt.

Om Mail Merge

Mail Merge är ett bekvämt sätt att generera brev, kuvert, fakturor, rapporter och andra typer av dokument dynamiskt. Med Mail Merge skapar du en mallfil som innehåller sammanslagningsfälten och fyller sedan i dessa fält med hjälp av data i en datakälla. Låt oss anta att du måste skicka ett brev till 20 olika personer och att du bara behöver ändra namnet och adressen till mottagarna på varje kopia. I det här fallet kan du skapa en mall för brevkoppling för brevet och sedan generera 20 bokstäver genom att fylla i namn- och adressfälten dynamiskt.

Java Mail Merge API - Gratis nedladdning

Aspose.Words for Java är ett välkänt ordbehandlings-API som låter dig skapa olika typer av dokument från grunden. API:et har inbyggda Mail Merge-funktioner som gör att du dynamiskt kan generera dokument med hjälp av mallar och datakällor. Aspose.Words för Java kan laddas ner som JAR eller installeras i Maven-baserade applikationer.

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

Datakällor för Mail Merge

Data i Mail Merge kan hämtas från vilken datakälla som helst som JSON, XML, kalkylblad eller en databas.

Skapa mall för Mail Merge i MS Word

Mallen som används i Mail Merge kan vara ett enkelt Word-dokument (dvs. DOCX) och det behöver inte vara i ett mallformat. Malldokumentet innehåller sammanslagningsfälten som fylls med data när Mail Merge körs. Följande är stegen för hur man förbereder en mall för koppling av brev med MS Word.

  • Skapa ett nytt dokument i MS Word.
  • Placera markören där du vill lägga till ett sammanfogningsfält.
  • Välj alternativet Fält i menyn Infoga.
  • I listan Fältnamn väljer du MergeField.
  • Ange ett namn för sammanslagningsfältet i fältnamnet och tryck på OK.
  • Spara dokumentet som DOCX.

Följande är skärmdumpen av dokumentet exempelmall.

mall för kopplingsord

Skapa mall för e-postkoppling med Java

Du kan också skapa mallen för sammankoppling av utskrifter programmatiskt. Följande är stegen för det.

Följande kodexempel visar hur man skapar en Mail Merge-mall med Java.

// Skapa dokumentbyggare
DocumentBuilder builder = new DocumentBuilder();

// Infoga ett textinmatningsfält det unika namnet på detta fält är "Hej", de andra parametrarna definierar
// vilken typ av FormField det är, formatet på texten, fältresultatet och den maximala textlängden (0 = ingen gräns)
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);

// Infoga en styckebrytning i dokumentet
builder.insertParagraph();

// Infoga meddelandetext
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();

// Infoga e-postslut
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");

// Spara dokument
builder.getDocument().save("document.docx");

Utför Mail Merge i Word-dokument med Java

När mallen är klar kan du fylla i sammanslagningsfälten med data. Följande är stegen för att utföra koppling av brev på en Word-mall.

Följande kodexempel visar hur man utför sammanslagning i Word-dokument med Java.

// Inkludera koden för vår mall
Document doc = new Document();

// Skicka dokumentet till dokumentbyggaren
DocumentBuilder builder = new DocumentBuilder(doc);

// Skapa sammanslagningsfält
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// Spara mallen
builder.getDocument().save("MailMerge.TestTemplate.docx");

// Fyll i fälten i dokumentet med användardata
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// Spara dokumentet 
builder.getDocument().save("MailMerge.Simple.docx");

Mall

enkel brevkoppling i java

Produktion

enkel sammanfogning

Utför Mail Merge med XML-datakälla

I det föregående exemplet utförde vi Mail Merge med Java-objekten. Men i de flesta fall används en datakälla för att fylla i sammanslagningsfälten. För demonstration, låt oss kolla in hur man använder en XML-datakälla i Mail Merge. Följande är stegen för det.

  • Ladda XML-datakällan med klassen DataSet.
  • Ladda Mail Merge-mallen med klassen Document.
  • Använd exekveringsfunktionen för att fylla i sammanslagningsfälten med den önskade datatabellen i datakällan.
  • Spara det genererade Word-dokumentet med metoden Document.save(String).

Följande är XML-datakällan som används i detta exempel.

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

Följande kodexempel visar hur du fyller i Mail Merge-mallen med hjälp av kunddatatabellen i den medföljande XML-datakällan.

// Skapa datamängden och läs XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Öppna ett malldokument
Document doc = new Document("TestFile XML.docx");

// Kör sammanslagningen för att fylla mallen med data från XML med DataTable.
// Observera att den här klassen också fungerar med en enda repeterbar region (och eventuella kapslade regioner).
// För att slå samman flera regioner samtidigt från en enda XML-datakälla, använd klassen XmlMailMergeDataSet.
// t.ex. doc.getMailMerge().executeWithRegions(nya XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// Spara utdatadokumentet
doc.save("generated-document.docx");

Mall

sammanslagning med XML

Produktion

mail merge xml

Mail Merge med regioner i Java

I vissa fall kan du behöva upprepa en viss region i dokumentet. Till exempel vill du visa beställningar som lagts av varje kund i en separat tabell. I sådana fall kan du dra fördel av Mail Merge-regionerna. För att skapa en region kan du ange början och slutet av regionen. Som ett resultat kommer regionen att upprepas för varje instans av data under körningen av Mail Merge.

Följande skärmdump visar en mall där regionen består av en tabell. Det börjar med «TabellStart:Kunder» och slutar med «Tabellslut:Kunder».

mall för kopplingsregion

Följande kodexempel visar hur man skapar en mall med regioner och fyller i den med data.

// Skapa dokument
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Startpunkten för e-postsammanfogning med regioner i datasetet.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Data från rader i kolumnen "Kundnamn" i tabellen "Kunder" försvinner
// i detta MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// Skapa kolumnrubriker
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// Vi har en andra datatabell som heter "Order", som har en många-till-en
// relation med "kunder"
// plocka upp rader med samma CustomerID-värde.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();

// Slutpunkten för post sammanfogas med regioner.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// Skicka vår datauppsättning för att utföra e-postsammanslagning med regioner.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// Spara resultatet
doc.save("MailMerge.ExecuteWithRegions.docx");

Produktion

kopplingsregion

Skapa kapslade kopplingsregioner med Java

Ett annat populärt scenario i Mail Merge är när du har kapslade regioner. Till exempel, när du måste lista beställningarna och artiklarna i varje beställning kan du använda de kapslade regionerna. Följande bild gör bilden mer tydlig om de kapslade områdena.

I bilden ovan har vi Order-tabellen och Artikeltabellen där varje post i Artiklar är länkad till en post i Order. Därför finns det en en-till-många-relation mellan dessa två tabeller. I sådana fall utför Aspose.Words Mail Merge och tar hand om de relationer som definieras i datamängden. Om vi till exempel har en XML-datakälla kommer Aspose.Words antingen använda schemainformationen eller strukturen för XML för att ta reda på sambanden. Du behöver alltså inte hantera det manuellt själv och metoden Document.getMailMerge().executeWithRegions(DataSet) kommer att fungera för dig (som föregående exempel).

Använd anpassad formatering på sammanfogningsfält

För att ge dig mer kontroll över Mail Merge låter Aspose.Words för Java dig anpassa sammanslagningsfälten under körningen av Mail Merge. Metoden setFieldMergingCallback(IFieldMergingCallback) accepterar en klass som implementerar metoderna fieldMerging(FieldMergingArgs) och imageFieldMerging(ImageFieldMergingArgs) för anpassad kontroll över Mail Merge-processen. Händelsen fieldMerging(FieldMergingArgs) inträffar när ett sammanfogningsfält påträffas under körningen av Mail Merge.

Följande är det fullständiga kodexemplet på hur man anpassar funktionen Mail Merge och tillämpar formatering på cellerna.

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

        // Lägg till en hanterare för MergeField-händelsen.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // Utför e-postsammanslagning med regioner.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

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

    /**
     * Returnerar sant om värdet är udda; falskt om värdet är jämnt.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * Skapa DataTable och fyll den med data. I verkliga livet denna DataTable
     * ska fyllas i från en databas.
     */
    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");
    }

    /**
     * En hjälpmetod som skapar en tom Java frånkopplad ResultSet med
     * de angivna kolumnerna.
     */
    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;
    }

    /**
     * En hjälpmetod som lägger till en ny rad med de angivna värdena till en
     * frånkopplad ResultSet.
     */
    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();

        // Denna "dans" behövs för att lägga till rader i slutet av resultatuppsättningen ordentligt.
        // Om jag gör något annat så läggs rader antingen till längst fram eller resultatet
        // set ger ett undantag om en raderad rad under sammanslagningen.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * Anropas för varje sammanslagningsfält som påträffas i dokumentet. Vi kan antingen
     * returnera vissa data till kopplingsmotorn eller göra något annat med
     * dokumentera. I det här fallet ändrar vi cellformateringen.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // På så sätt fångar vi början på en ny rad.
        if (e.getFieldName().equals("CompanyName")) {
            // Välj färg beroende på om radnumret är jämnt eller udda.
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(242, 242, 242);

            // Det finns inget sätt att ställa in cellegenskaper för hela raden för tillfället,
            // så vi måste iterera över alla celler i raden.
           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 {
        // Göra ingenting.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

Slutsats

Mail Merge ger dig ett brett utbud av funktioner för att generera MS Word-dokument dynamiskt. Du kan generera enkla såväl som komplexa rapporter baserat på data i databaser eller andra datakällor. I den här artikeln har du sett hur du implementerar Mail Merge-funktionerna programmatiskt med Java. Du kan lära dig mer om Java Mail Merge API med hjälp av dokumentationen.

Se även