Tento příspěvek popisuje, jak provádět operace hromadné korespondence v dokumentech MS Word pomocí Java. Na konci tohoto článku se dozvíte, jak vytvářet šablony hromadné korespondence a spouštět hromadnou korespondenci programově.

O hromadné korespondenci

Mail Merge je pohodlný způsob dynamického generování dopisů, obálek, faktur, zpráv a dalších typů dokumentů. Pomocí hromadné korespondence vytvoříte soubor šablony obsahující slučovací pole a poté tato pole naplníte pomocí dat ve zdroji dat. Předpokládejme, že musíte poslat dopis 20 různým lidem a na každé kopii stačí změnit jméno a adresu příjemců. V tomto případě můžete vytvořit šablonu hromadné korespondence pro daný dopis a poté vygenerovat 20 písmen dynamickým vyplněním polí jména a adresy.

Java Mail Merge API – ke stažení zdarma

Aspose.Words for Java je dobře známé rozhraní API pro zpracování textu, které umožňuje vytvářet různé typy dokumentů od začátku. Rozhraní API poskytuje vestavěné funkce hromadné korespondence, které umožňují dynamicky generovat dokumenty pomocí šablon a zdrojů dat. Aspose.Words for Java lze stáhnout jako JAR nebo nainstalovat v rámci aplikací založených na 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>

Zdroje dat pro hromadnou korespondenci

Data v hromadné korespondenci lze načíst z libovolného zdroje dat, jako je JSON, XML, tabulka nebo databáze.

Vytvořte šablonu pro hromadnou korespondenci v MS Word

Šablona používaná v hromadné korespondenci může být jednoduchý dokument aplikace Word (např. DOCX) a nemusí být ve formátu šablony. Dokument šablony obsahuje slučovací pole, která jsou vyplněna daty při spuštění hromadné korespondence. Následují kroky, jak připravit šablonu hromadné korespondence pomocí MS Word.

  • Vytvořte nový dokument v MS Word.
  • Umístěte kurzor na místo, kam chcete přidat slučovací pole.
  • Z nabídky Vložit vyberte možnost Pole.
  • Ze seznamu Názvy polí vyberte MergeField.
  • Do pole Název pole zadejte název slučovacího pole a stiskněte OK.
  • Uložte dokument jako DOCX.

Následuje snímek obrazovky dokumentu ukázka šablony.

šablona slova hromadné korespondence

Vytvořte šablonu hromadné korespondence pomocí Java

Šablonu hromadné korespondence můžete vygenerovat také programově. Následují kroky k tomu.

Následující ukázka kódu ukazuje, jak vytvořit šablonu hromadné korespondence pomocí jazyka Java.

// Vytvořte nástroj pro tvorbu dokumentů
DocumentBuilder builder = new DocumentBuilder();

// Vložte textové vstupní pole jedinečné jméno tohoto pole je "Ahoj", ostatní parametry definují
// o jaký typ FormField se jedná, formát textu, výsledek pole a maximální délka textu (0 = bez omezení)
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);

// Vložte do dokumentu konec odstavce
builder.insertParagraph();

// Vložte tělo pošty
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();

// Vložit konec pošty
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");

// Uložit dokument
builder.getDocument().save("document.docx");

Proveďte hromadnou korespondenci v dokumentu Word pomocí Java

Jakmile je šablona připravena, můžete naplnit slučovací pole daty. Následují kroky provádění hromadné korespondence na šabloně aplikace Word.

Následující ukázka kódu ukazuje, jak provést hromadnou korespondenci v dokumentech aplikace Word pomocí jazyka Java.

// Zahrňte kód naší šablony
Document doc = new Document();

// Předejte dokument tvůrci dokumentů
DocumentBuilder builder = new DocumentBuilder(doc);

// Vytvořte slučovací pole
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// Uložte šablonu
builder.getDocument().save("MailMerge.TestTemplate.docx");

// Vyplňte pole v dokumentu uživatelskými údaji
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// Uložte dokument 
builder.getDocument().save("MailMerge.Simple.docx");

Šablona

jednoduchá hromadná korespondence v Javě

Výstup

jednoduchá hromadná korespondence

Proveďte hromadnou korespondenci pomocí zdroje dat XML

V předchozím příkladu jsme provedli hromadnou korespondenci pomocí objektů Java. Ve většině případů se však k vyplnění slučovacích polí používá zdroj dat. Pro demonstraci se podívejme, jak používat zdroj dat XML v hromadné korespondenci. Následují kroky k tomu.

  • Načtěte zdroj dat XML pomocí třídy DataSet.
  • Načtěte šablonu hromadné korespondence pomocí třídy Document.
  • Pomocí funkce spuštění naplňte slučovací pole pomocí požadované datové tabulky ve zdroji dat.
  • Uložte vygenerovaný dokument Word pomocí metody Document.save(String).

Níže je uveden zdroj dat XML použitý v tomto příkladu.

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

Následující ukázka kódu ukazuje, jak naplnit šablonu hromadné korespondence pomocí tabulky Zákaznická data v poskytnutém zdroji dat XML.

// Vytvořte datovou sadu a přečtěte si XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Otevřete dokument šablony
Document doc = new Document("TestFile XML.docx");

// Spusťte hromadnou korespondenci a naplňte šablonu daty z XML pomocí DataTable.
// Všimněte si, že tato třída také pracuje s jednou opakovatelnou oblastí (a všemi vnořenými oblastmi).
// Chcete-li sloučit více oblastí současně z jednoho zdroje dat XML, použijte třídu XmlMailMergeDataSet.
// např. doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// Uložte výstupní dokument
doc.save("generated-document.docx");

Šablona

hromadné korespondence s XML

Výstup

hromadná korespondence xml

Hromadná korespondence s regiony v Javě

V určitých případech může být nutné opakovat určitou oblast v dokumentu. Chcete například zobrazit objednávky zadané každým zákazníkem v samostatné tabulce. V takových případech můžete využít oblasti hromadné korespondence. Chcete-li vytvořit oblast, můžete určit začátek a konec oblasti. V důsledku toho se oblast bude opakovat pro každou instanci dat během provádění hromadné korespondence.

Následující snímek obrazovky ukazuje šablonu, ve které se oblast skládá z tabulky. Začíná to «TableStart:Customers» a končí «TableEnd:Customers».

šablona oblasti hromadné korespondence

Následující ukázka kódu ukazuje, jak vytvořit šablonu s oblastmi a naplnit ji daty.

// Vytvořte dokument
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Počáteční bod hromadné korespondence s oblastmi datové sady.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Půjdou data z řádků sloupce "CustomerName" tabulky "Customers".
// v tomto MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// Vytvořte záhlaví sloupců
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// Máme druhou datovou tabulku nazvanou "Objednávky", která má mnoho ku jedné
// vztah se "zákazníky"
// vyzvednutí řádků se stejnou hodnotou 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();

// Koncový bod hromadné korespondence s oblastmi.
builder.insertField(" MERGEFIELD TableEnd:Customers");

// Předejte naši datovou sadu k provedení hromadné korespondence s regiony.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// Uložte výsledek
doc.save("MailMerge.ExecuteWithRegions.docx");

Výstup

oblast hromadné korespondence

Vytvořte vnořené oblasti hromadné korespondence pomocí Java

Dalším oblíbeným scénářem hromadné korespondence je situace, kdy máte vnořené oblasti. Pokud například musíte uvést seznam objednávek a položek v každé objednávce, můžete použít vnořené oblasti. Na následujícím obrázku je obrázek o vnořených oblastech jasnější.

Na obrázku výše máme tabulku Objednávky a tabulku Položky, kde je každý záznam v Položkách propojen se záznamem v Zakázkách. Mezi těmito dvěma tabulkami tedy existuje vztah jedna k mnoha. V takových případech Aspose.Words spustí hromadnou korespondenci, přičemž se postará o vztahy definované v DataSet. Například, pokud máme zdroj dat XML, pak Aspose.Words použije informace o schématu nebo strukturu XML ke zjištění vztahů. Nebudete to tedy muset zpracovávat ručně sami a metoda Document.getMailMerge().executeWithRegions(DataSet) vám bude fungovat (jako předchozí příklad).

Použít vlastní formátování na slučovací pole

Abyste získali větší kontrolu nad hromadnou korespondencí, Aspose.Words for Java vám umožňuje přizpůsobit slučovací pole během provádění hromadné korespondence. Metoda setFieldMergingCallback(IFieldMergingCallback) přijímá třídu, která implementuje metody fieldMerging(FieldMergingArgs) a imageFieldMerging(ImageFieldMergingArgs) pro vlastní kontrolu nad procesem hromadné korespondence. K události fieldMerging(FieldMergingArgs) dochází, když je během provádění hromadné korespondence zjištěno slučovací pole.

Následuje úplná ukázka kódu, jak přizpůsobit operaci hromadné korespondence a použít formátování na buňky.

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

        // Přidejte obslužnou rutinu pro událost MergeField.
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // Proveďte hromadnou korespondenci s oblastmi.
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

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

    /**
     * Vrátí true, pokud je hodnota lichá; false, pokud je hodnota sudá.
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * Vytvořte DataTable a naplňte ji daty. V reálném životě tato DataTable
     * by měly být vyplněny z databáze.
     */
    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");
    }

    /**
     * Pomocná metoda, která vytvoří prázdnou sadu ResultSet odpojenou od Java s
     * zadané sloupce.
     */
    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;
    }

    /**
     * Pomocná metoda, která přidá nový řádek se zadanými hodnotami do a
     * odpojený 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();

        // Tento "tanec" je nutný pro správné přidání řádků na konec sady výsledků.
        // Pokud udělám něco jiného, pak se řádky přidají buď dopředu, nebo výsledek
        // set vyvolá výjimku o smazaném řádku během hromadné korespondence.
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * Volá se pro každé slučovací pole nalezené v dokumentu. Můžeme buď
     * vraťte některá data do modulu hromadné korespondence nebo s ním proveďte něco jiného
     * dokument. V tomto případě upravíme formátování buněk.
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // Tímto způsobem chytíme začátek nové řady.
        if (e.getFieldName().equals("CompanyName")) {
            // Vyberte barvu podle toho, zda je číslo řádku sudé nebo liché.
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(242, 242, 242);

            // V tuto chvíli neexistuje způsob, jak nastavit vlastnosti buňky pro celý řádek,
            // takže musíme iterovat přes všechny buňky v řádku.
           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 {
        // Nedělat nic.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

Závěr

Hromadná korespondence vám poskytuje širokou škálu funkcí pro dynamické generování dokumentů MS Word. Na základě dat v databázích nebo jiných zdrojích dat můžete generovat jednoduché i složité sestavy. V tomto článku jste viděli, jak implementovat funkce hromadné korespondence programově pomocí Java. Více o Java Mail Merge API se můžete dozvědět pomocí dokumentace.

Viz také