У цій публікації описано, як виконувати операції злиття в документах MS Word за допомогою Java. Наприкінці цієї статті ви дізнаєтесь, як створювати шаблони злиття та виконувати програмне злиття.

Про злиття

Злиття — це зручний спосіб динамічного створення листів, конвертів, рахунків-фактур, звітів та інших типів документів. Використовуючи злиття, ви створюєте файл шаблону, що містить поля злиття, а потім заповнюєте ці поля, використовуючи дані в джерелі даних. Припустімо, що вам потрібно надіслати лист 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, електронної таблиці або бази даних.

Створення шаблону для злиття в MS Word

Шаблон, який використовується у злитті, може бути простим документом Word (тобто DOCX), і він не обов’язково має бути у форматі шаблону. Шаблон документа містить поля злиття, які заповнюються даними під час виконання злиття. Нижче описано, як підготувати шаблон злиття за допомогою MS Word.

  • Створіть новий документ у MS Word.
  • Помістіть курсор туди, куди потрібно додати поле злиття.
  • У меню «Вставка» виберіть параметр «Поле».
  • У списку «Імена полів» виберіть MergeField.
  • Введіть ім’я для поля об’єднання в поле Ім’я поля та натисніть OK.
  • Збережіть документ як DOCX.

Нижче наведено знімок екрана документа зразок шаблону.

шаблон слова для злиття

Створіть шаблон злиття за допомогою Java

Ви також можете створити шаблон злиття програмним шляхом. Нижче наведено кроки для цього.

У наведеному нижче прикладі коду показано, як створити шаблон злиття за допомогою Java.

// Створення конструктора документів
DocumentBuilder builder = new DocumentBuilder();

// Вставте поле введення тексту, унікальне ім’я цього поля – «Привіт», інші параметри визначають
// який це тип 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");

Виконайте злиття в документі Word за допомогою Java

Коли шаблон буде готовий, ви можете заповнити поля злиття даними. Нижче наведено кроки для виконання злиття в шаблоні Word.

  • Створіть новий шаблон за допомогою класу Document(або завантажте існуючий шаблон).
  • Створіть екземпляр класу DocumentBuilder і передайте об’єкт Document його конструктору.
  • Виконайте злиття за допомогою методу Document.getMailMerge().execute() і передайте джерело даних як параметр.
  • Збережіть створений документ Word за допомогою методу DocumentBuilder.getDocument().save(String).

У наведеному нижче прикладі коду показано, як виконати злиття в документах Word за допомогою Java.

// Додайте код для нашого шаблону
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. Однак у більшості випадків для заповнення полів злиття використовується джерело даних. Для демонстрації давайте перевіримо, як використовувати джерело даних XML у злитті. Нижче наведено кроки для цього.

  • Завантажте джерело даних XML за допомогою класу DataSet.
  • Завантажте шаблон злиття за допомогою класу Document.
  • Використовуйте функцію виконання, щоб заповнити поля злиття за допомогою потрібної таблиці даних у джерелі даних.
  • Збережіть створений документ Word за допомогою методу Document.save(String).

Нижче наведено джерело даних 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.

// Створіть набір даних і прочитайте XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");

// Відкрийте шаблон документа
Document doc = new Document("TestFile XML.docx");

// Виконайте злиття, щоб заповнити шаблон даними з XML за допомогою DataTable.
// Зауважте, що цей клас також працює з однією повторюваною областю (і будь-якими вкладеними областями).
// Щоб об’єднати кілька регіонів одночасно з одного джерела даних XML, використовуйте клас XmlMailMergeDataSet.
// наприклад, doc.getMailMerge().executeWithRegions(новий 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");
// Підуть дані з рядків стовпця "CustomerName" таблиці "Customers".
// у цьому 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();

// У нас є друга таблиця даних під назвою «Замовлення», яка має багато-до-одного
// відносини з "Клієнтами"
// збирання рядків із однаковим значенням 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

Ще один популярний сценарій у злитті — це вкладені області. Наприклад, якщо вам потрібно перерахувати замовлення та елементи в кожному замовленні, ви можете використовувати вкладені області. Наступне зображення робить зображення вкладених областей більш чітким.

На зображенні вище ми маємо таблицю «Замовлення» та таблицю «Елементи», де кожен запис у «Елементи» пов’язаний із записом у «Замовленнях». Отже, між цими двома таблицями існує зв’язок «один до багатьох». У таких випадках 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");
    }

    /**
     * Допоміжний метод, який створює порожній відключений ResultSet Java з
     * зазначені стовпці.
     */
    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;
    }

    /**
     * Допоміжний метод, який додає новий рядок із зазначеними значеннями до a
     * відключений 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;
}

Висновок

Злиття надає вам широкий спектр функцій для динамічного створення документів MS Word. Ви можете створювати прості та складні звіти на основі даних у базах даних або інших джерел даних. У цій статті ви побачили, як програмно реалізувати функції злиття за допомогою Java. Ви можете дізнатися більше про Java Mail Merge API за допомогою документації.

Дивись також