この投稿では、Javaを使用してMSWord文書でメールマージ操作を実行する方法について説明します。この記事の終わりまでに、Mail Mergeテンプレートを作成し、プログラムでMailMergeを実行する方法を学習します。

メールマージについて

メールマージは、手紙、封筒、請求書、レポート、およびその他の種類のドキュメントを動的に生成する便利な方法です。メールマージを使用して、マージフィールドを含むテンプレートファイルを作成し、データソースのデータを使用してそれらのフィールドにデータを入力します。 20人の異なる人に手紙を送る必要があり、各コピーの受信者の名前と住所を変更するだけでよいと仮定しましょう。この場合、レターのメールマージテンプレートを作成し、名前と住所のフィールドに動的に入力することで20文字を生成できます。

Java Mail Merge API-無料ダウンロード

Aspose.Words for Javaは、さまざまな種類のドキュメントを最初から作成できる、よく知られたワードプロセッシングAPIです。 APIは、テンプレートとデータソースを使用してドキュメントを動的に生成できる組み込みのメールマージ機能を提供します。 Aspose.Words for Javaは、JARとしてダウンロードするか、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>

メールマージのデータソース

Mail Mergeのデータは、JSON、XML、スプレッドシート、データベースなどの任意のデータソースからフェッチできます。

MSWordでメールマージ用のテンプレートを作成する

Mail Mergeで使用されるテンプレートは、単純なWord文書(つまり、DOCX)である可能性があり、テンプレート形式である必要はありません。テンプレートドキュメントには、メールマージの実行時にデータが入力されるマージフィールドが含まれています。以下は、MSWordを使用してメールマージテンプレートを準備する方法の手順です。

  • MSWordで新しいドキュメントを作成します。
  • マージフィールドを追加する場所にカーソルを置きます。
  • [挿入]メニューから[フィールド]オプションを選択します。
  • [フィールド名]リストから、[MergeField]を選択します。
  • [フィールド名]にマージフィールドの名前を入力し、[OK]を押します。
  • ドキュメントをDOCXとして保存します。

以下は、サンプルテンプレートドキュメントのスクリーンショットです。

メールマージワードテンプレート

Javaを使用してメールマージテンプレートを作成する

プログラムでメールマージテンプレートを生成することもできます。そのための手順は次のとおりです。

次のコードサンプルは、Javaを使用してメールマージテンプレートを作成する方法を示しています。

// ドキュメントビルダーを作成する
DocumentBuilder builder = new DocumentBuilder();

// テキスト入力フィールドを挿入します。このフィールドの一意の名前は「Hello」で、他のパラメータは次のように定義します。
// FormFieldのタイプ、テキストの形式、フィールドの結果、および最大テキスト長(0 =制限なし)
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);

// 段落区切りをドキュメントに挿入します
builder.insertParagraph();

// メール本文を挿入
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();

// メールの末尾を挿入
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");

// ドキュメントを保存
builder.getDocument().save("document.docx");

Javaを使用してWord文書でメールマージを実行する

テンプレートの準備ができたら、マージフィールドにデータを入力できます。以下は、Wordテンプレートでメールマージを実行する手順です。

  • Documentクラスを使用して新しいテンプレートを作成します(または既存のテンプレートをロードします)。
  • DocumentBuilderクラスのインスタンスを作成し、Documentオブジェクトをそのコンストラクターに渡します。
  • Document.getMailMerge().execute()メソッドを使用してメールマージを実行し、データソースをパラメーターとして渡します。
  • DocumentBuilder.getDocument().save(String)メソッドを使用して、生成されたWord文書を保存します。

次のコードサンプルは、Javaを使用してWord文書でメールマージを実行する方法を示しています。

// テンプレートのコードを含める
Document doc = new Document();

// ドキュメントをドキュメントビルダーに渡します
DocumentBuilder builder = new DocumentBuilder(doc);

// マージフィールドの作成
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");

// テンプレートを保存します
builder.getDocument().save("MailMerge.TestTemplate.docx");

// ドキュメントのフィールドにユーザーデータを入力します
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
		new Object[] { "John Doe", "Hawaiian", "2" });

// ドキュメントを保存する 
builder.getDocument().save("MailMerge.Simple.docx");

テンプレート

Javaでの単純なメールマージ

出力

シンプルなメールマージ

XMLデータソースを使用してメールマージを実行する

前の例では、Javaオブジェクトを使用してメールマージを実行しました。ただし、ほとんどの場合、データソースを使用してマージフィールドにデータが入力されます。デモンストレーションとして、Mail MergeでXMLデータソースを使用する方法を確認しましょう。そのための手順は次のとおりです。

  • DataSetクラスを使用してXMLデータソースをロードします。
  • Documentクラスを使用してMailMergeテンプレートをロードします。
  • 実行関数を使用して、データソース内の目的のデータテーブルを使用してマージフィールドにデータを入力します。
  • Document.save(String)メソッドを使用して、生成されたWordドキュメントを保存します。

以下は、この例で使用されているXMLデータソースです。

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

次のコードサンプルは、提供されたXMLデータソースのCustomerデータテーブルを使用してMail Mergeテンプレートにデータを入力する方法を示しています。

// データセットを作成し、XMLを読み取ります
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// テンプレートドキュメントを開く
Document doc = new Document("TestFile XML.docx");

// メールマージを実行して、DataTableを使用してテンプレートにXMLからのデータを入力します。
// このクラスは、単一の繰り返し可能な領域(およびネストされた領域)でも機能することに注意してください。
// 単一のXMLデータソースから同時に複数のリージョンをマージするには、XmlMailMergeDataSetクラスを使用します。
// 例:doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));

// 出力ドキュメントを保存します
doc.save("generated-document.docx");

テンプレート

メールとXMLのマージ

出力

メールマージxml

Javaのリージョンとのメールマージ

場合によっては、ドキュメント内の特定の領域を繰り返す必要があります。たとえば、各顧客からの注文を別々のテーブルに表示するとします。このような場合、メールマージリージョンを利用できます。リージョンを作成するために、リージョンの開始と終了を指定できます。その結果、メールマージの実行中に、データのインスタンスごとにリージョンが繰り返されます。

次のスクリーンショットは、リージョンがテーブルで構成されているテンプレートを示しています。 «TableStart:Customers»で始まり、«TableEnd:Customers»で終わります。

メールマージリージョンテンプレート

次のコードサンプルは、リージョンを含むテンプレートを作成し、データを入力する方法を示しています。

// ドキュメントを作成する
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// メールの開始点は、データセットのリージョンとマージされます。
builder.insertField(" MERGEFIELD TableStart:Customers");
// 「Customers」テーブルの「CustomerName」列の行からのデータが送信されます
// このMERGEFIELDで。
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");

// 列ヘッダーを作成する
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();

// 「Orders」と呼ばれる2番目のデータテーブルがあります。これには多対1があります。
// 「お客様」との関係
// 同じ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();

// メールのエンドポイントはリージョンとマージされます。
builder.insertField(" MERGEFIELD TableEnd:Customers");

// データセットを渡して、リージョンとのメールマージを実行します。
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);

// 結果を保存する
doc.save("MailMerge.ExecuteWithRegions.docx");

出力

メールマージリージョン

Javaを使用してネストされたメールマージ領域を作成する

Mail Mergeのもう1つの一般的なシナリオは、ネストされたリージョンがある場合です。たとえば、注文と各注文のアイテムを一覧表示する必要がある場合は、ネストされたリージョンを使用できます。次の画像は、ネストされた領域についての画像をより明確にしています。

上の画像には、OrdersテーブルとItemsテーブルがあり、Itemsの各レコードがOrdersのレコードにリンクされています。したがって、これら2つのテーブルの間には1対多の関係が存在します。このような場合、Aspose.Wordsは、DataSetで定義された関係を処理してメールマージを実行します。たとえば、XMLデータソースがある場合、Aspose.Wordsはスキーマ情報またはXMLの構造を使用して関係を見つけます。したがって、手動で処理する必要はなく、Document.getMailMerge().executeWithRegions(DataSet)メソッドが機能します(前の例のように)。

マージフィールドにカスタムフォーマットを適用する

メールマージをより細かく制御できるようにするために、Aspose.Words for Javaでは、メールマージの実行中にマージフィールドをカスタマイズできます。 setFieldMergingCallback(IFieldMergingCallback)メソッドは、メールマージプロセスをカスタム制御するためのfieldMerging(FieldMergingArgs)およびimageFieldMerging(ImageFieldMergingArgs)メソッドを実装するクラスを受け入れます。 fieldMerging(FieldMergingArgs)イベントは、メールマージの実行中にマージフィールドが検出されたときに発生します。

以下は、メールマージ操作をカスタマイズしてセルに書式を適用する方法の完全なコードサンプルです。

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

        // MergeFieldイベントのハンドラーを追加します。
        doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());

        // リージョンとのメールマージを実行します。
        DataTable dataTable = getSuppliersDataTable();
        doc.getMailMerge().executeWithRegions(dataTable);

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

    /**
     * 値が奇数の場合はtrueを返します。値が偶数の場合はfalse。
     */
    public static boolean isOdd(int value) throws Exception {
        return (value % 2 != 0);
    }

    /**
     * DataTableを作成し、データを入力します。実生活では、このDataTable
     * データベースから入力する必要があります。
     */
    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");
    }

    /**
     * 空のJava切断ResultSetを作成するヘルパーメソッド
     * 指定された列。
     */
    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;
    }

    /**
     * 指定された値を持つ新しい行をに追加するヘルパーメソッド
     * 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();

        // この「ダンス」は、結果セットの最後に行を適切に追加するために必要です。
        // 他のことをすると、行が先頭または結果に追加されます
        // setは、メールのマージ中に削除された行に関する例外をスローします。
        resultSet.moveToCurrentRow();
        resultSet.last();
    }
}

class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
    /**
     * ドキュメントで検出されたすべてのマージフィールドに対して呼び出されます。私たちはどちらかができます
     * 一部のデータをメールマージエンジンに返すか、
     * 資料。この場合、セルのフォーマットを変更します。
     */
    public void fieldMerging(FieldMergingArgs e) throws Exception {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.getDocument());

        // このようにして、新しい行の始まりをキャッチします。
        if (e.getFieldName().equals("CompanyName")) {
            // 行番号が偶数か奇数かに応じて色を選択します。
            Color rowColor;
            if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
                rowColor = new Color(213, 227, 235);
            else
                rowColor = new Color(242, 242, 242);

            // 現時点では、行全体のセルプロパティを設定する方法はありません。
            // したがって、行内のすべてのセルを反復処理する必要があります。
            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 {
        // 何もしない。
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

結論

Mail Mergeは、MSWord文書を動的に生成するための幅広い機能を提供します。データベースまたはその他のデータソースのデータに基づいて、単純なレポートと複雑なレポートを生成できます。この記事では、Javaを使用してプログラムでメールマージ機能を実装する方法を見てきました。 ドキュメントを使用して、Java MailMergeAPIの詳細を学ぶことができます。

関連項目