В этом посте рассказывается, как выполнять операции слияния в документах MS Word с использованием Java. К концу этой статьи вы узнаете, как создавать шаблоны слияния и программно выполнять слияние.
- О слиянии почты
- API слияния почты Java
- Источники данных для слияния
- Создание шаблона рассылки в MS Word
- Создайте шаблон слияния с помощью Java
- Выполнение слияния почты в документе Word с использованием Java
- Слияние почты с использованием источника данных XML
- Выполните слияние почты с регионами
- Создание вложенных областей слияния почты
- Пользовательское форматирование полей слияния
О слиянии почты
Mail Merge — это удобный способ динамического создания писем, конвертов, счетов, отчетов и других типов документов. Используя слияние, вы создаете файл шаблона, содержащий поля слияния, а затем заполняете эти поля, используя данные из источника данных. Предположим, вам нужно отправить письмо 20 разным людям, и вам нужно только изменить имя и адрес получателей на каждом экземпляре. В этом случае вы можете создать шаблон Mail Merge для письма, а затем сгенерировать 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>
Источники данных для слияния
Данные в слиянии могут быть получены из любого источника данных, такого как JSON, XML, электронная таблица или база данных.
Создать шаблон для слияния писем в MS Word
Шаблон, используемый в Mail Merge, может быть простым документом Word (например, DOCX), и он не обязательно должен быть в формате шаблона. Документ-шаблон содержит поля слияния, которые заполняются данными при выполнении слияния. Ниже приведены шаги по подготовке шаблона слияния с помощью MS Word.
- Создайте новый документ в MS Word.
- Поместите курсор туда, где вы хотите добавить поле слияния.
- В меню «Вставка» выберите параметр «Поле».
- В списке Имена полей выберите MergeField.
- Введите имя поля слияния в поле Имя поля и нажмите OK.
- Сохраните документ как DOCX.
Ниже приведен скриншот документа образец шаблона.
Создайте шаблон слияния с помощью Java
Вы также можете сгенерировать шаблон Mail Merge программно. Ниже приведены шаги для этого.
- Создайте экземпляр класса DocumentBuilder.
- Вставьте поля слияния, используя методы, предоставляемые DocumentBuilder, такие как insertTextInput, insertField, InsertParagraph и т. д.
- Сохраните документ, используя метод DocumentBuilder.getDocument().save(String fileName).
В следующем примере кода показано, как создать шаблон слияния с помощью 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");
Шаблон
Выход
Выполнение слияния почты с использованием источника данных XML
В предыдущем примере мы выполнили слияние с использованием объектов Java. Однако в большинстве случаев для заполнения полей слияния используется источник данных. Для демонстрации давайте посмотрим, как использовать источник данных XML в Mail Merge. Ниже приведены шаги для этого.
- Загрузите источник данных 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>
В следующем примере кода показано, как заполнить шаблон слияния, используя таблицу данных Customer в предоставленном источнике данных 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");
Шаблон
Выход
Слияние почты с регионами в Java
В некоторых случаях может потребоваться повторение определенной области в документе. Например, вы хотите отобразить заказы, сделанные каждым клиентом, в отдельной таблице. В таких случаях вы можете воспользоваться регионами Mail Merge. Чтобы создать регион, вы можете указать начало и конец региона. В результате регион будет повторяться для каждого экземпляра данных во время выполнения слияния.
На следующем снимке экрана показан шаблон, в котором область состоит из таблицы. Он начинается с «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
Другой популярный сценарий в Mail Merge — когда у вас есть вложенные регионы. Например, когда вам нужно перечислить заказы и элементы в каждом заказе, вы можете использовать вложенные области. Следующее изображение проясняет картину вложенных регионов.
На изображении выше у нас есть таблица Orders и таблица Items, где каждая запись в Items связана с записью в Orders. Следовательно, между этими двумя таблицами существует отношение «один ко многим». В таких случаях Aspose.Words выполняет слияние, заботясь об отношениях, определенных в наборе данных. Например, если у нас есть источник данных XML, Aspose.Words будет использовать либо информацию о схеме, либо структуру XML, чтобы выяснить отношения. Таким образом, вам не придется заниматься этим вручную самостоятельно, а за вас будет работать метод Document.getMailMerge().executeWithRegions(DataSet) (как в предыдущем примере).
Применение пользовательского форматирования к полям слияния
Чтобы дать вам больше контроля над слиянием, Aspose.Words для 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 с
* указанные столбцы.
*/
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 предоставляет вам широкий спектр функций для динамического создания документов MS Word. Вы можете создавать как простые, так и сложные отчеты на основе данных из баз данных или других источников данных. В этой статье вы увидели, как программно реализовать функции слияния с помощью Java. Вы можете узнать больше о Java Mail Merge API, используя документацию.