Aspose.Words功能演示:使用Java在MS Word文檔中進(jìn)行郵件合并
郵件合并是一種動態(tài)生成信件,信封,發(fā)票,報告和其他類型文檔的便捷方法。使用郵件合并,您可以創(chuàng)建一個包含合并字段的模板文件,然后使用數(shù)據(jù)源中的數(shù)據(jù)填充這些字段。
假設(shè)您必須向20個不同的人發(fā)送一封信,并且只需要更改每個副本上收件人的姓名和地址。在這種情況下,您可以為該信件創(chuàng)建一個郵件合并模板,然后通過動態(tài)填充名稱和地址字段來生成20個信件。
這篇文章介紹了如何使用Java在MS Word文檔中執(zhí)行郵件合并操作。同時,將學(xué)習(xí)如何創(chuàng)建郵件合并模板和以編程方式執(zhí)行郵件合并。
>>如果想要測試這項新功能,可點擊這里下載最新版試用。
- 使用Java中的密碼保護(hù)Word DOCX文件
- 保護(hù)具有不同保護(hù)類型的DOCX文件
- 使用Java取消保護(hù)/解鎖DOCX文件
創(chuàng)建用于MS Word中郵件合并的模板
郵件合并中使用的模板可以是一個簡單的Word文檔(即DOCX),并且不必采用模板格式。模板文檔包含執(zhí)行“郵件合并”時填充有數(shù)據(jù)的合并字段。以下是如何使用MS Word準(zhǔn)備郵件合并模板的步驟。
- 在MS Word中創(chuàng)建一個新文檔。
- 將光標(biāo)放在要添加合并字段的位置。
- 從 插入 菜單中選擇字段 選項。
- 從 字段名稱 列表中,選擇 MergeField。
- 在字段名稱中為合并字段輸入名稱 ,然后按 確定。
- 將文檔另存為DOCX。
以下是示例模板 文檔的屏幕截圖 。
使用Java創(chuàng)建郵件合并模板
還可以以編程方式生成郵件合并模板。以下是其步驟。
- 創(chuàng)建DocumentBuilder類的實例。
- 使用DocumentBuilder提供的方法(例如insertTextInput, insertField,InsertParagraph等)插入合并字段。
- 使用DocumentBuilder.getDocument()。save(String fileName)方法保存文檔。
下面的代碼示例演示如何使用Java創(chuàng)建郵件合并模板。
// 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文檔中執(zhí)行郵件合并
模板準(zhǔn)備好后,您可以用數(shù)據(jù)填充合并字段。以下是在Word模板上執(zhí)行郵件合并的步驟。
- 使用Document 類創(chuàng)建一個新模板 (或加載現(xiàn)有模板)。
- 創(chuàng)建DocumentBuilder類的實例,然后將Document對象傳遞給其構(gòu)造函數(shù)。
- 使用Document.getMailMerge()。execute() 方法執(zhí)行郵件合并 ,并將數(shù)據(jù)源作為參數(shù)傳遞。
- 使用DocumentBuilder.getDocument()。save(String)方法保存生成的Word文檔 。
下面的代碼示例演示如何使用Java在Word文檔中執(zhí)行郵件合并。
// 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數(shù)據(jù)源執(zhí)行郵件合并
在前面的示例中,我們使用Java對象執(zhí)行了郵件合并。但是,在大多數(shù)情況下,數(shù)據(jù)源用于填充合并字段。為了演示,讓我們檢查一下如何在Mail Merge中使用XML數(shù)據(jù)源。以下是其步驟。
- 使用DataSet類加載XML數(shù)據(jù)源。
- 使用文檔類加載郵件合并模板。
- 使用execute函數(shù)在數(shù)據(jù)源中使用所需的數(shù)據(jù)表填充合并字段。
- 使用Document.save(String)方法保存生成的Word文檔。
以下是此示例中使用的XML數(shù)據(jù)源。
下面的代碼示例演示如何使用提供的XML數(shù)據(jù)源中的Customer數(shù)據(jù)表填充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中的區(qū)域合并郵件
在某些情況下,您可能需要重復(fù)文檔中的特定區(qū)域。例如,您要在單獨的表格中顯示每個客戶下的訂單。在這種情況下,您可以利用郵件合并區(qū)域。為了創(chuàng)建區(qū)域,您可以指定區(qū)域的開始和結(jié)束。結(jié)果,在郵件合并執(zhí)行期間,將為數(shù)據(jù)的每個實例重復(fù)該區(qū)域。
以下屏幕快照顯示了一個模板,其中區(qū)域由一個表組成。它以《 TableStart:Customers》開頭,并以《 TableEnd:Customers》結(jié)尾。
以下代碼示例顯示了如何創(chuàng)建具有區(qū)域的模板并使用數(shù)據(jù)填充它。
// 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創(chuàng)建嵌套的郵件合并區(qū)域
郵件合并中的另一種流行情況是當(dāng)您具有嵌套區(qū)域時。例如,當(dāng)您必須列出訂單和每個訂單中的項目時,可以使用嵌套區(qū)域。下圖使圖片更清晰地顯示了嵌套區(qū)域。
在上圖中,我們有訂單表和項目,其中每個記錄表項目鏈接到創(chuàng)紀(jì)錄的訂單。因此,這兩個表之間存在一對多關(guān)系。在這種情況下,Aspose.Words將執(zhí)行Data Merge中定義的關(guān)系的郵件合并。例如,如果我們有一個XML數(shù)據(jù)源,那么Aspose.Words將使用模式信息或XML結(jié)構(gòu)來查找關(guān)系。因此,您不必自己手動處理它,而Document.getMailMerge()。executeWithRegions(DataSet)方法將為您工作(如上例所示)。
在合并字段上應(yīng)用自定義格式
為了使您能夠更好地控制郵件合并,Aspose.Words for Java允許您在郵件合并執(zhí)行期間自定義合并字段。所述 setFieldMergingCallback(IFieldMergingCallback) 方法接受了一類工具fieldMerging(FieldMergingArgs) 和 imageFieldMerging(ImageFieldMergingArgs)用于在郵件合并過程定制的控制方法。該 fieldMerging(FieldMergingArgs) 當(dāng)郵件合并執(zhí)行過程中遇到合并域發(fā)生的事件。
以下是有關(guān)如何自定義郵件合并操作以及將格式應(yīng)用于單元格的完整代碼示例。
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技術(shù)交流群(761297826),我們很高興為您提供查詢和咨詢。