Aspose.Words功能演示:使用Java在MS Word文档中进行邮件合并
邮件合并是一种动态生成信件,信封,发票,报告和其他类型文档的便捷方法。使用邮件合并,您可以创建一个包含合并字段的模板文件,然后使用数据源中的数据填充这些字段。
假设您必须向20个不同的人发送一封信,并且只需要更改每个副本上收件人的姓名和地址。在这种情况下,您可以为该信件创建一个邮件合并模板,然后通过动态填充名称和地址字段来生成20个信件。
这篇文章介绍了如何使用Java在MS Word文档中执行邮件合并操作。同时,将学习如何创建邮件合并模板和以编程方式执行邮件合并。
>>如果想要测试这项新功能,可点击这里下载最新版试用。
- 使用Java中的密码保护Word DOCX文件
- 保护具有不同保护类型的DOCX文件
- 使用Java取消保护/解锁DOCX文件
创建用于MS Word中邮件合并的模板
邮件合并中使用的模板可以是一个简单的Word文档(即DOCX),并且不必采用模板格式。模板文档包含执行“邮件合并”时填充有数据的合并字段。以下是如何使用MS Word准备邮件合并模板的步骤。
- 在MS Word中创建一个新文档。
- 将光标放在要添加合并字段的位置。
- 从 插入 菜单中选择字段 选项。
- 从 字段名称 列表中,选择 MergeField。
- 在字段名称中为合并字段输入名称 ,然后按 确定。
- 将文档另存为DOCX。
以下是示例模板 文档的屏幕截图 。
使用Java创建邮件合并模板
还可以以编程方式生成邮件合并模板。以下是其步骤。
- 创建DocumentBuilder类的实例。
- 使用DocumentBuilder提供的方法(例如insertTextInput, insertField,InsertParagraph等)插入合并字段。
- 使用DocumentBuilder.getDocument()。save(String fileName)方法保存文档。
下面的代码示例演示如何使用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");
使用Java在Word文档中执行邮件合并
模板准备好后,您可以用数据填充合并字段。以下是在Word模板上执行邮件合并的步骤。
- 使用Document 类创建一个新模板 (或加载现有模板)。
- 创建DocumentBuilder类的实例,然后将Document对象传递给其构造函数。
- 使用Document.getMailMerge()。execute() 方法执行邮件合并 ,并将数据源作为参数传递。
- 使用DocumentBuilder.getDocument()。save(String)方法保存生成的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");
模板
输出
使用XML数据源执行邮件合并
在前面的示例中,我们使用Java对象执行了邮件合并。但是,在大多数情况下,数据源用于填充合并字段。为了演示,让我们检查一下如何在Mail Merge中使用XML数据源。以下是其步骤。
- 使用DataSet类加载XML数据源。
- 使用文档类加载邮件合并模板。
- 使用execute函数在数据源中使用所需的数据表填充合并字段。
- 使用Document.save(String)方法保存生成的Word文档。
以下是此示例中使用的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");
模板
输出
Java中的区域合并邮件
在某些情况下,您可能需要重复文档中的特定区域。例如,您要在单独的表格中显示每个客户下的订单。在这种情况下,您可以利用邮件合并区域。为了创建区域,您可以指定区域的开始和结束。结果,在邮件合并执行期间,将为数据的每个实例重复该区域。
以下屏幕快照显示了一个模板,其中区域由一个表组成。它以《 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");
输出
使用Java创建嵌套的邮件合并区域
邮件合并中的另一种流行情况是当您具有嵌套区域时。例如,当您必须列出订单和每个订单中的项目时,可以使用嵌套区域。下图使图片更清晰地显示了嵌套区域。
在上图中,我们有订单表和项目,其中每个记录表项目链接到创纪录的订单。因此,这两个表之间存在一对多关系。在这种情况下,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; }
还想要更多吗?您可以点击阅读【2020 · Aspose最新资源整合】,查找需要的教程资源。如果您有任何疑问或需求,请随时加入Aspose技术交流群(761297826),我们很高兴为您提供查询和咨询。