翻译|使用教程|编辑:李显亮|2020-12-14 11:15:52.183|阅读 589 次
概述:邮件合并是一种动态生成信件,信封,发票,报告和其他类型文档的便捷方法。这篇文章介绍了如何使用Java在MS Word文档中执行邮件合并操作。同时,将学习如何创建邮件合并模板和以编程方式执行邮件合并。
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
相关链接:
邮件合并是一种动态生成信件,信封,发票,报告和其他类型文档的便捷方法。使用邮件合并,您可以创建一个包含合并字段的模板文件,然后使用数据源中的数据填充这些字段。
假设您必须向20个不同的人发送一封信,并且只需要更改每个副本上收件人的姓名和地址。在这种情况下,您可以为该信件创建一个邮件合并模板,然后通过动态填充名称和地址字段来生成20个信件。
这篇文章介绍了如何使用Java在MS Word文档中执行邮件合并操作。同时,将学习如何创建邮件合并模板和以编程方式执行邮件合并。
>>如果想要测试这项新功能,可点击这里下载最新版试用。
邮件合并中使用的模板可以是一个简单的Word文档(即DOCX),并且不必采用模板格式。模板文档包含执行“邮件合并”时填充有数据的合并字段。以下是如何使用MS Word准备邮件合并模板的步骤。
以下是示例模板 文档的屏幕截图 。
还可以以编程方式生成邮件合并模板。以下是其步骤。
下面的代码示例演示如何使用Java创建邮件合并模板。
// Create document builder
DocumentBuilder builder = new DocumentBuilder();
// Insert a text input field the unique name of this field is "Hello", the other parameters define
// what type of FormField it is, the format of the text, the field result and the maximum text length (0 = no limit)
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);
// Insert a paragraph break into the document
builder.insertParagraph();
// Insert mail body
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();
// Insert mail ending
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");
// Save document
builder.getDocument().save("document.docx");
模板准备好后,您可以用数据填充合并字段。以下是在Word模板上执行邮件合并的步骤。
下面的代码示例演示如何使用Java在Word文档中执行邮件合并。
// Include the code for our template
Document doc = new Document();
// Pass the document to document builder
DocumentBuilder builder = new DocumentBuilder(doc);
// Create Merge Fields
builder.insertField(" MERGEFIELD CustomerName ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Item ");
builder.insertParagraph();
builder.insertField(" MERGEFIELD Quantity ");
// Save the template
builder.getDocument().save("MailMerge.TestTemplate.docx");
// Fill the fields in the document with user data
doc.getMailMerge().execute(new String[] { "CustomerName", "Item", "Quantity" },
new Object[] { "John Doe", "Hawaiian", "2" });
// Save the document
builder.getDocument().save("MailMerge.Simple.docx");
模板
输出
在前面的示例中,我们使用Java对象执行了邮件合并。但是,在大多数情况下,数据源用于填充合并字段。为了演示,让我们检查一下如何在Mail Merge中使用XML数据源。以下是其步骤。
以下是此示例中使用的XML数据源。
下面的代码示例演示如何使用提供的XML数据源中的Customer数据表填充Mail Merge模板。
// Create the Dataset and read the XML
DataSet customersDs = new DataSet();
customersDs.readXml("Customers.xml");
// Open a template document
Document doc = new Document("TestFile XML.docx");
// Execute mail merge to fill the template with data from XML using DataTable.
// Note that this class also works with a single repeatable region (and any nested regions).
// To merge multiple regions at the same time from a single XML data source, use the XmlMailMergeDataSet class.
// e.g doc.getMailMerge().executeWithRegions(new XmlMailMergeDataSet(xmlData));
doc.getMailMerge().execute(customersDs.getTables().get("Customer"));
// Save the output document
doc.save("generated-document.docx");
模板
输出
在某些情况下,您可能需要重复文档中的特定区域。例如,您要在单独的表格中显示每个客户下的订单。在这种情况下,您可以利用邮件合并区域。为了创建区域,您可以指定区域的开始和结束。结果,在邮件合并执行期间,将为数据的每个实例重复该区域。
以下屏幕快照显示了一个模板,其中区域由一个表组成。它以《 TableStart:Customers》开头,并以《 TableEnd:Customers》结尾。
以下代码示例显示了如何创建具有区域的模板并使用数据填充它。
// Create document
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// The start point of mail merge with regions the dataset.
builder.insertField(" MERGEFIELD TableStart:Customers");
// Data from rows of the "CustomerName" column of the "Customers" table will go
// in this MERGEFIELD.
builder.write("Orders for ");
builder.insertField(" MERGEFIELD CustomerName");
builder.write(":");
// Create column headers
builder.startTable();
builder.insertCell();
builder.write("Item");
builder.insertCell();
builder.write("Quantity");
builder.endRow();
// We have a second data table called "Orders", which has a many-to-one
// relationship with "Customers"
// picking up rows with the same CustomerID value.
builder.insertCell();
builder.insertField(" MERGEFIELD TableStart:Orders");
builder.insertField(" MERGEFIELD ItemName");
builder.insertCell();
builder.insertField(" MERGEFIELD Quantity");
builder.insertField(" MERGEFIELD TableEnd:Orders");
builder.endTable();
// The end point of mail merge with regions.
builder.insertField(" MERGEFIELD TableEnd:Customers");
// Pass our dataset to perform mail merge with regions.
DataSet customersAndOrders = CreateDataSet();
doc.getMailMerge().executeWithRegions(customersAndOrders);
// Save the result
doc.save("MailMerge.ExecuteWithRegions.docx");
输出
邮件合并中的另一种流行情况是当您具有嵌套区域时。例如,当您必须列出订单和每个订单中的项目时,可以使用嵌套区域。下图使图片更清晰地显示了嵌套区域。
在上图中,我们有订单表和项目,其中每个记录表项目链接到创纪录的订单。因此,这两个表之间存在一对多关系。在这种情况下,Aspose.Words将执行Data Merge中定义的关系的邮件合并。例如,如果我们有一个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");
// Add a handler for the MergeField event.
doc.getMailMerge().setFieldMergingCallback(new HandleMergeFieldAlternatingRows());
// Execute mail merge with regions.
DataTable dataTable = getSuppliersDataTable();
doc.getMailMerge().executeWithRegions(dataTable);
doc.save(dataDir + "MailMerge.AlternatingRows Out.doc");
}
/**
* Returns true if the value is odd; false if the value is even.
*/
public static boolean isOdd(int value) throws Exception {
return (value % 2 != 0);
}
/**
* Create DataTable and fill it with data. In real life this DataTable
* should be filled from a database.
*/
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");
}
/**
* A helper method that creates an empty Java disconnected ResultSet with
* the specified columns.
*/
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 helper method that adds a new row with the specified values to a
* disconnected 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();
// This "dance" is needed to add rows to the end of the result set properly.
// If I do something else then rows are either added at the front or the result
// set throws an exception about a deleted row during mail merge.
resultSet.moveToCurrentRow();
resultSet.last();
}
}
class HandleMergeFieldAlternatingRows implements IFieldMergingCallback {
/**
* Called for every merge field encountered in the document. We can either
* return some data to the mail merge engine or do something else with the
* document. In this case we modify cell formatting.
*/
public void fieldMerging(FieldMergingArgs e) throws Exception {
if (mBuilder == null)
mBuilder = new DocumentBuilder(e.getDocument());
// This way we catch the beginning of a new row.
if (e.getFieldName().equals("CompanyName")) {
// Select the color depending on whether the row number is even or odd.
Color rowColor;
if (ApplyCustomFormattingDuringMailMerge.isOdd(mRowIdx))
rowColor = new Color(213, 227, 235);
else
rowColor = new Color(242, 242, 242);
// There is no way to set cell properties for the whole row at the moment,
// so we have to iterate over all cells in the row.
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 {
// Do nothing.
}
private DocumentBuilder mBuilder;
private int mRowIdx;
}
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@ke049m.cn