翻譯|使用教程|編輯:胡濤|2023-02-20 11:02:10.410|閱讀 228 次
概述:在本文中,我將向您展示如何在沒有 MS Word 或 Office Interop 的情況下使用 C# 或 VB.NET 執(zhí)行 MS Word 郵件合并。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
Aspose.Words 是一種高級(jí)Word文檔處理API,用于執(zhí)行各種文檔管理和操作任務(wù)。API支持生成,修改,轉(zhuǎn)換,呈現(xiàn)和打印文檔,而無(wú)需在跨平臺(tái)應(yīng)用程序中直接使用Microsoft Word。此外,
Aspose API支持流行文件格式處理,并允許將各類文檔導(dǎo)出或轉(zhuǎn)換為固定布局文件格式和最常用的圖像/多媒體格式。
在本文中,我將向您展示如何在沒有 MS Word 或 Office Interop 的情況下使用 C# 或 VB.NET 執(zhí)行 MS Word 郵件合并。Aspose.Words for .NET是一個(gè)功能豐富且功能強(qiáng)大的 Word API,它提供了所有基本的以及擴(kuò)展的 MS Word 郵件合并功能。它允許您在 Windows 窗體、ASP.NET Web 應(yīng)用程序或任何 .NET/.NET Core 應(yīng)用程序中生成信件、信封、報(bào)告、發(fā)票和其他類型的文檔。
郵件合并是一種自動(dòng)生成報(bào)告、信件、信封、發(fā)票和其他類型文檔的方式。MS Word 中的郵件合并允許您創(chuàng)建包含合并字段的模板文檔,然后使用數(shù)據(jù)源中的記錄填充這些字段。要了解郵件合并,假設(shè)您必須向十個(gè)不同的人發(fā)送一封信,并且只有姓名和地址字段需要更新。在這種情況下,只需創(chuàng)建一個(gè)字母模板,然后通過使用數(shù)據(jù)源填充名稱和地址合并字段來(lái)動(dòng)態(tài)生成字母。
郵件合并的數(shù)據(jù)可以從任何數(shù)據(jù)源(如 XML、JSON 或數(shù)據(jù)庫(kù))中獲取。就 Aspose.Words for .NET 而言,您可以使用 ADO.NET 支持的任何數(shù)據(jù)源。數(shù)據(jù)可以加載到 DataSet、DataTable、DataView 或值數(shù)組中。
郵件合并模板是包含合并字段的文檔。當(dāng)執(zhí)行郵件合并時(shí),這些字段隨后會(huì)填充數(shù)據(jù)源中的數(shù)據(jù)。模板文檔不需要是模板格式,可以是DOC/DOCX文檔。這就是您可以為郵件合并準(zhǔn)備模板的方法。
以下是示例模板文檔的屏幕截圖。
準(zhǔn)備好模板后,您可以執(zhí)行郵件合并以生成文檔。以下是在上述模板上執(zhí)行郵件合并的步驟。
以下代碼示例顯示如何使用 C# 中的值數(shù)組執(zhí)行 MS Word 郵件合并。
// For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET // The path to the documents directory. string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); // Open an existing document. Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc"); // Trim trailing and leading whitespaces mail merge values doc.MailMerge.TrimWhitespaces = false; // Fill the fields in the document with user data. doc.MailMerge.Execute( new string[] { "FullName", "Company", "Address", "Address2", "City" }, new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" }); dataDir = dataDir + "MailMerge.ExecuteArray_out.doc"; // Send the document in Word format to the client browser with an option to save to disk or open inside the current browser.
XML 文件廣泛用于保存和導(dǎo)入/導(dǎo)出數(shù)據(jù)。Aspose.Words for .NET 也支持 XML 作為郵件合并的數(shù)據(jù)源。只需將 XML 讀入DataSet對(duì)象并執(zhí)行郵件合并。以下是我們將要使用的示例 XML 文件。
<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 數(shù)據(jù)源獲取數(shù)據(jù)并使用 C# 執(zhí)行郵件合并。 // For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET // The path to the documents directory. string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); // Create the Dataset and read the XML. DataSet customersDs = new DataSet(); customersDs.ReadXml(dataDir + "Customers.xml"); string fileName = "TestFile XML.doc"; // Open a template document. Document doc = new Document(dataDir + fileName); // Execute mail merge to fill the template with data from XML using DataTable. doc.MailMerge.Execute(customersDs.Tables["Customer"]); dataDir = dataDir + RunExamples.GetOutputFilePath(fileName); // Save the output document. doc.Save(dataDir);
下面是將用 XML 數(shù)據(jù)填充的郵件合并模板。
以下是執(zhí)行郵件合并后得到的結(jié)果 Word 文檔的第 1 頁(yè)。
Aspose.Words for .NET 讓您在執(zhí)行期間更好地控制郵件合并。MailMerge.FieldMergingCallback屬性允許您在遇到任何合并字段時(shí)自定義郵件合并。MailMerge.FieldMergingCallback 接受實(shí)現(xiàn)IFieldMergingCallback.FieldMerging和IFieldMergingCallback.ImageFieldMerging方法的類。
下面的代碼示例顯示了如何自定義郵件合并操作并將格式應(yīng)用于此模板中的單元格。
// For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET // The path to the documents directory. string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc"); // Add a handler for the MergeField event. doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows(); // Execute mail merge with regions. DataTable dataTable = GetSuppliersDataTable(); doc.MailMerge.ExecuteWithRegions(dataTable); dataDir = dataDir + "MailMerge.AlternatingRows_out.doc"; doc.Save(dataDir); 以下是HandleMergeFieldAlternatingRows類的實(shí)現(xiàn)。 // For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET private class HandleMergeFieldAlternatingRows : IFieldMergingCallback { /// <summary> /// 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. /// </summary> void IFieldMergingCallback.FieldMerging(FieldMergingArgs e) { if (mBuilder == null) mBuilder = new DocumentBuilder(e.Document); // This way we catch the beginning of a new row. if (e.FieldName.Equals("CompanyName")) { // Select the color depending on whether the row number is even or odd. Color rowColor; if (IsOdd(mRowIdx)) rowColor = Color.FromArgb(213, 227, 235); else rowColor = Color.FromArgb(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.CellFormat.Shading.BackgroundPatternColor = rowColor; } mRowIdx++; } } void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args) { // Do nothing. } private DocumentBuilder mBuilder; private int mRowIdx; } /// <summary> /// Returns true if the value is odd; false if the value is even. /// </summary> private static bool IsOdd(int value) { // The code is a bit complex, but otherwise automatic conversion to VB does not work. return ((value / 2) * 2).Equals(value); } /// <summary> /// Create DataTable and fill it with data. /// In real life this DataTable should be filled from a database. /// </summary> private static DataTable GetSuppliersDataTable() { DataTable dataTable = new DataTable("Suppliers"); dataTable.Columns.Add("CompanyName"); dataTable.Columns.Add("ContactName"); for (int i = 0; i < 10; i++) { DataRow datarow = dataTable.NewRow(); dataTable.Rows.Add(datarow); datarow[0] = "Company " + i.ToString(); datarow[1] = "Contact " + i.ToString(); } return dataTable; }
當(dāng)您需要填充和重復(fù) Word 文檔中的特定區(qū)域時(shí),可能會(huì)出現(xiàn)這種情況。對(duì)于這種情況,您可以使用區(qū)域郵件合并。要?jiǎng)?chuàng)建區(qū)域,您需要指定區(qū)域的開始和結(jié)束,然后 Mail Megre 將為數(shù)據(jù)源中的每條記錄重復(fù)該區(qū)域。例如,以下模板包含兩個(gè)區(qū)域,Orders 和 OrderDetails,分別具有合并字段 ?TableStart:Orders?、?TableEnd:Orders? 和 ?TableStart:OrderDetails?、?TableEnd:OrderDetails?。
以下是上述模板對(duì)區(qū)域進(jìn)行Mail Megre的代碼示例。
// For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET // The path to the documents directory. string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); string fileName = "MailMerge.ExecuteWithRegions.doc"; Document doc = new Document(dataDir + fileName); // Use DataTable as a data source. int orderId = 10444; DataTable orderTable = GetTestOrder(orderId); doc.MailMerge.ExecuteWithRegions(orderTable); // Instead of using DataTable, you can create a DataView for custom sort or filter and then mail merge. DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId)); orderDetailsView.Sort = "ExtendedPrice DESC"; // Execute the mail merge operation. doc.MailMerge.ExecuteWithRegions(orderDetailsView); // Save the merged document. dataDir = dataDir + RunExamples.GetOutputFilePath(fileName); doc.Save(dataDir);
下面是從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)的方法。
// For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET private static DataTable GetTestOrder(int orderId) { DataTable table = ExecuteDataTable(string.Format( "SELECT * FROM AsposeWordOrders WHERE OrderId = {0}", orderId)); table.TableName = "Orders"; return table; } private static DataTable GetTestOrderDetails(int orderId) { DataTable table = ExecuteDataTable(string.Format( "SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {0} ORDER BY ProductID", orderId)); table.TableName = "OrderDetails"; return table; } /// <summary> /// Utility function that creates a connection, command, /// Executes the command and return the result in a DataTable. /// </summary> private static DataTable ExecuteDataTable(string commandText) { // Open the database connection. string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + RunExamples.GetDataDir_Database() + "Northwind.mdb"; OleDbConnection conn = new OleDbConnection(connString); conn.Open(); // Create and execute a command. OleDbCommand cmd = new OleDbCommand(commandText, conn); OleDbDataAdapter da = new OleDbDataAdapter(cmd); DataTable table = new DataTable(); da.Fill(table); // Close the database. conn.Close(); return table; }
大多數(shù)情況下,我們?cè)跀?shù)據(jù)源中擁有的數(shù)據(jù)以關(guān)系的形式出現(xiàn)。例如,表“Order”將與“OrderDetails”具有一對(duì)多關(guān)系,后者將保存訂單中的項(xiàng)目記錄。為了處理這種父子關(guān)系,使用了嵌套的郵件合并。以下是非常適合這種情況的示例發(fā)票模板。
以下是我們將用于嵌套郵件合并的示例 XML 數(shù)據(jù)源。
<?xml version="1.0" encoding="utf-8"?> <Orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="OrdersSchema.xsd"> <Order> <Number>23</Number> <Address>Nelson Street</Address> <Suburb>Howick</Suburb> <City>Auckland</City> <Phonenumber>543 1234</Phonenumber> <Date>03/01/2010</Date> <Total>14.00</Total> <Item> <Name>BBQ Chicken Pizza</Name> <Price>6.00</Price> <Quantity>1</Quantity> <ItemTotal>6.00</ItemTotal> </Item> <Item> <Name>1.5 Litre Coke</Name> <Price>4.00</Price> <Quantity>2</Quantity> <ItemTotal>8.00</ItemTotal> </Item> </Order> <Order> <Number>10</Number> <Address>Parkville Avenue</Address> <Suburb>Pakuranga</Suburb> <City>Auckland</City> <Phonenumber>548 7342</Phonenumber> <Date>05/03/2010</Date> <Total>6.00</Total> <Item> <Name>Hawaiian Pizza</Name> <Price>4.00</Price> <Quantity>1</Quantity> <ItemTotal>4.00</ItemTotal> </Item> <Item> <Name>Fries</Name> <Price>1.00</Price> <Quantity>2</Quantity> <ItemTotal>2.00</ItemTotal> </Item> </Order> </Orders> 而此 XML 的OrderSchema.xsd是: <?xml version="1.0" encoding ="utf-8"?> <xs:schema id="OrdersSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Orders"> <xs:complexType> <xs:sequence> <xs:element name="Order"> <xs:complexType> <xs:sequence> <xs:element name="Number"/> <xs:element name="Address"/> <xs:element name="Suburb"/> <xs:element name="City"/> <xs:element name="Phonenumber"> <xs:element name="Date"/> <xs:element name="Total"/> <xs:element name="Item"> <xs:complexType> <xs:sequence> <xs:element name="Name"/> <xs:element name="Price"/> <xs:element name="Quantity"/> <xs:element name="ItemTotal"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
以下代碼示例用于使用 C# 執(zhí)行嵌套郵件合并。
// For complete examples and data files, please go to //github.com/aspose-words/Aspose.Words-for-.NET // The path to the documents directory. string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); // Create the Dataset and read the XML. DataSet pizzaDs = new DataSet(); // The Datatable.TableNames and the DataSet.Relations are defined implicitly by .NET through ReadXml. pizzaDs.ReadXml(dataDir + "CustomerData.xml"); string fileName = "Invoice Template.doc"; // Open the template document. Document doc = new Document(dataDir + fileName); // Trim trailing and leading whitespaces mail merge values. doc.MailMerge.TrimWhitespaces = false; // Execute the nested mail merge with regions. doc.MailMerge.ExecuteWithRegions(pizzaDs); dataDir = dataDir + RunExamples.GetOutputFilePath(fileName); // Save the output to file. doc.Save(dataDir); Debug.Assert(doc.MailMerge.GetFieldNames().Length == 0, "There was a problem with mail merge"); Console.WriteLine("\nMail merge performed with nested data successfully.\nFile saved at " + dataDir);
下面是執(zhí)行郵件合并后生成的 Word 文檔的第一頁(yè)。
以上便是使用 C# 或 VB.NET 在 Word 文檔中合并郵件 - .NET 郵件合并 API ,要是您還有其他關(guān)于產(chǎn)品方面的問題,歡迎咨詢我們,或者加入我們官方技術(shù)交流群。
歡迎下載|體驗(yàn)更多Aspose產(chǎn)品
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn