如何使用 IronWord 在 C# 中建立可填寫的表格範本
多年來,需要大規模生成個性化Word文件的.NET團隊有兩個現實選擇,但都不理想。
第一個選擇是通過COM互操作自動化Microsoft Word本身。這個方法有效,直到它失效。 Word互操作速度慢、不穩定,要求在每台機器上都有Word授權,而一旦嘗試在Linux容器、Azure函数或任何未安裝Word的伺服器環境中運行它,就會失效。 大多數嘗試過的團隊最後都重寫了相關程式碼。
第二個選擇是自定義查找和替換管線。將.docx作為XML或文字讀取,將佔位符令牌替換為實際值,並保存結果。 這種方法可以解決簡單情況,但會在使用複雜欄位結構的真實Word文件上崩潰,這些結構與開發者預期查找到的簡單{{FirstName}} 令牌完全不同。
IronWord現在原生支持郵件合併。 在Microsoft Word中設計的模板,使用與Word自身生成的合併字段語法相同,直接從.NET程式碼填充,無需安裝Word。
功能用途
郵件合併引擎可以處理Word生成的兩種合併字段樣式:
- 簡單字段,格式為"FieldName",這是您直接在模板中鍵入<
>得到的。 - 複雜字段,多元素XML結構Word通過插入→快速部分→字段生成的。
模板可以包含單一值佔位符,每個文件替換一次,以及由"TableStart:Name"和"TableEnd:Name"界定的重複區域,這些會擴展為每個資料記錄一行。
第二部分就是這個功能的價值所在。 重複區域是指一份發票中的單一模板行擴展為50行明細項目表格,或者標籤紙中的一個聯絡人位在資料庫中變成完整的Avery網格。
來自CRM的個性化介紹信
大多數團隊先在銷售運營中遇到郵件合併。 CRM持有客戶記錄; 市場運營或銷售運營需要發送個性化介紹信、歡迎包或續訂通知。 模式很簡單:一個模板,每個顧客一行,產出一份個性化文件。
// Template: "Dear «FirstName», thank you for your order of «Amount»..."
DataTable customers = LoadFromSalesforce(); // FirstName, LastName, Amount, ...
foreach (DataRow row in customers.Rows)
{
var doc = new WordDocument("cover-letter-template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs($"letters/{row["LastName"]}.docx");
}
// Template: "Dear «FirstName», thank you for your order of «Amount»..."
DataTable customers = LoadFromSalesforce(); // FirstName, LastName, Amount, ...
foreach (DataRow row in customers.Rows)
{
var doc = new WordDocument("cover-letter-template.docx");
doc.MailMerge.Execute(row);
doc.SaveAs($"letters/{row["LastName"]}.docx");
}
Imports System.Data
' Template: "Dear «FirstName», thank you for your order of «Amount»..."
Dim customers As DataTable = LoadFromSalesforce() ' FirstName, LastName, Amount, ...
For Each row As DataRow In customers.Rows
Dim doc As New WordDocument("cover-letter-template.docx")
doc.MailMerge.Execute(row)
doc.SaveAs($"letters/{row("LastName")}.docx")
Next
資料源是DataTable,這意味著任何載入到其中的內容(Salesforce、HubSpot、SQL Server、一個CSV、一個API回應)都會成為郵件合併源,無需額外的適配器程式碼。
具有重複項的發票
發票是重複區域功能發揮作用的地方。一個發票模板有一個標頭(客戶姓名、訂單ID、日期)、明細表中的一行,以及一個尾標(總計)。 當合併運行時,單一模板行會拓展為每個產品一行,無論訂單有一個明細項目還是五十個。
// Template:
// Bill To: «CustomerName» Order: «OrderId»
// ┌──────────┬─────┬──────────┐
// │ «TableStart:Items»«Product» │ «Qty» │ «LineTotal» «TableEnd:Items» │
// └──────────┴─────┴──────────┘
// Total: «Total»
var doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(orderLineItems); // one row per product
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CustomerName", "Acme Industries" },
{ "OrderId", "10444" },
{ "Total", "$1,117.71" },
});
doc.SaveAs("invoice-10444.docx");
// Template:
// Bill To: «CustomerName» Order: «OrderId»
// ┌──────────┬─────┬──────────┐
// │ «TableStart:Items»«Product» │ «Qty» │ «LineTotal» «TableEnd:Items» │
// └──────────┴─────┴──────────┘
// Total: «Total»
var doc = new WordDocument("invoice-template.docx");
doc.MailMerge.ExecuteWithRegions(orderLineItems); // one row per product
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CustomerName", "Acme Industries" },
{ "OrderId", "10444" },
{ "Total", "$1,117.71" },
});
doc.SaveAs("invoice-10444.docx");
Imports System.Collections.Generic
' Template:
' Bill To: «CustomerName» Order: «OrderId»
' ┌──────────┬─────┬──────────┐
' │ «TableStart:Items»«Product» │ «Qty» │ «LineTotal» «TableEnd:Items» │
' └──────────┴─────┴──────────┘
' Total: «Total»
Dim doc As New WordDocument("invoice-template.docx")
doc.MailMerge.ExecuteWithRegions(orderLineItems) ' one row per product
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"CustomerName", "Acme Industries"},
{"OrderId", "10444"},
{"Total", "$1,117.71"}
})
doc.SaveAs("invoice-10444.docx")
相同的模式適用於報價單、採購訂單、對帳單及任何內容長度可變列表位於固定形狀頁面的文件。
Avery標籤紙和信封
運送和運營團隊從聯絡人列表生成標籤和信封,佈局(Avery 5160、5161、5163及其國際對應版本)是已存在數十年的標準模板。 IronWord 直接填充它們:標籤網格中的每個單元格從單一API調用中抓取相應的聯絡人。
// Template: a 3×10 Avery 5160 grid, each cell has «CONTACT_FULLNAME» / «CONTACT_ADDRESS»
var doc = new WordDocument("avery-5160.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CONTACT_FULLNAME", "Jane Doe" },
{ "CONTACT_ADDRESS", "100 Main Street, Boston, MA 02108" },
});
doc.SaveAs("labels-jane.docx");
// Template: a 3×10 Avery 5160 grid, each cell has «CONTACT_FULLNAME» / «CONTACT_ADDRESS»
var doc = new WordDocument("avery-5160.docx");
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CONTACT_FULLNAME", "Jane Doe" },
{ "CONTACT_ADDRESS", "100 Main Street, Boston, MA 02108" },
});
doc.SaveAs("labels-jane.docx");
Imports System.Collections.Generic
' Template: a 3×10 Avery 5160 grid, each cell has «CONTACT_FULLNAME» / «CONTACT_ADDRESS»
Dim doc As New WordDocument("avery-5160.docx")
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"CONTACT_FULLNAME", "Jane Doe"},
{"CONTACT_ADDRESS", "100 Main Street, Boston, MA 02108"}
})
doc.SaveAs("labels-jane.docx")
對於變長的聯絡人列表,應用發票例子中的 ExecuteWithRegions 模式:將一個單元格定義為重複單位,其餘的頁面會自動填滿。
多區域報告
最強大的應用是多區域報告。 季度摘要可能包含"最佳客戶"和"最佳產品"部分,每部分由自己的資料表驅動。 使用包含多個表的DataSet,合併在一次調用中擴展這兩個區域。
// Template:
// Top Customers
// «TableStart:Customers» • «Name» | «City» | «Revenue» «TableEnd:Customers»
// Top Products
// «TableStart:Products» «ProductName»: «Revenue» «TableEnd:Products»
var ds = new DataSet();
ds.Tables.Add(topCustomers); // TableName = "Customers"
ds.Tables.Add(topProducts); // TableName = "Products"
var doc = new WordDocument("quarterly-report.docx");
doc.MailMerge.ExecuteWithRegions(ds); // expands both regions
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CompanyName", "Iron Software" },
{ "ReportDate", "Q2 2026" },
});
doc.SaveAs("Q2-2026-report.docx");
// Template:
// Top Customers
// «TableStart:Customers» • «Name» | «City» | «Revenue» «TableEnd:Customers»
// Top Products
// «TableStart:Products» «ProductName»: «Revenue» «TableEnd:Products»
var ds = new DataSet();
ds.Tables.Add(topCustomers); // TableName = "Customers"
ds.Tables.Add(topProducts); // TableName = "Products"
var doc = new WordDocument("quarterly-report.docx");
doc.MailMerge.ExecuteWithRegions(ds); // expands both regions
doc.MailMerge.Execute(new Dictionary<string, string>
{
{ "CompanyName", "Iron Software" },
{ "ReportDate", "Q2 2026" },
});
doc.SaveAs("Q2-2026-report.docx");
Imports System.Data
Imports System.Collections.Generic
' Template:
' Top Customers
' «TableStart:Customers» • «Name» | «City» | «Revenue» «TableEnd:Customers»
' Top Products
' «TableStart:Products» «ProductName»: «Revenue» «TableEnd:Products»
Dim ds As New DataSet()
ds.Tables.Add(topCustomers) ' TableName = "Customers"
ds.Tables.Add(topProducts) ' TableName = "Products"
Dim doc As New WordDocument("quarterly-report.docx")
doc.MailMerge.ExecuteWithRegions(ds) ' expands both regions
doc.MailMerge.Execute(New Dictionary(Of String, String) From {
{"CompanyName", "Iron Software"},
{"ReportDate", "Q2 2026"}
})
doc.SaveAs("Q2-2026-report.docx")
DataSet中的每個DataTable匹配其對應的"TableStart:..."區域名稱,標量欄位在同一次通過中填充標頭值。
對於有這類文件工作流程的團隊,等待整潔.NET實現,Iron Suite將IronWord和IronPDF、IronOCR、IronXL和IronBarcode捆綁在單一授權中。
開始免費試用,無需信用卡。
為何有效
有幾件事將這種方法與替代方案區分開:
原生Word語法。模板在Microsoft Word中設計,使用Word已經提供的合併字段工具。 保存為.docx,將文件交給IronWord,合併執行。 沒有專有模板語言,沒有翻譯層,沒有為設計文件的團隊設計的新學習曲線。
簡單和複雜字段格式。取決於欄位插入的方式,Word產生兩種不同的欄位結構。 IronWord處理這兩者,這意味著由不同團隊成員以不同方式設計的現有模板都可以不加修改地工作。
沒有外部依賴。程式庫完全在.NET上運行。 不需要Word安裝,不需要COM,不需要Office授權,不需要互操作的不穩定性。 相同的程式碼在Windows開發者機上運行,也能在Linux容器、Azure函式或無伺服器構建代理中相同運行。
摘要
郵件合併一直是.NET文件工具空間中的一個長期漏洞,變通方案未能很好地老化。 IronWord的原生郵件合併填補了這一空白,其模型顯現了Word自身的合併欄位語法,支持簡單值和重複區域,並且沒有任何隨.NET中的文件自動化歷史上附帶的部署負擔。
對於大規模生成發票、標籤、信件、合約和報告的團隊來說,這是從單一模板到成千上萬份個性化文件的最乾淨路徑。
常見問題
什麼是IronWord郵件合併?
IronWord郵件合併是一個功能,允許您從.NET應用程式中生成個人化的Word文件,無需安裝Microsoft Word。
IronWord郵件合併可以大規模生成文件嗎?
是的,IronWord郵件合併設計用於大規模生成個人化的Word文件,非常適合大型批量處理。
使用IronWord郵件合併需要Microsoft Word嗎?
不,IronWord郵件合併不需要安裝Microsoft Word,允許在.NET應用程式中進行無縫的文件生成體驗。
使用IronWord郵件合併可以生成什麼型別的文件?
IronWord郵件合併可以生成各種文件,包括發票、信件、標籤和使用Word模板的報告。
IronWord郵件合併如何與.NET整合?
IronWord郵件合併本機支持.NET,為開發者提供一個直接且高效的方式來在他們的應用程式中實現郵件合併功能。
使用IronWord郵件合併與傳統方法相比有什麼好處?
使用IronWord郵件合併消除了對Microsoft Word的需求,減少了對第三方軟體的依賴,並為從.NET應用程式生成文件提供了一個可擴展的解決方案。
IronWord郵件合併可以用於生成報告嗎?
是的,IronWord郵件合併可以用於從Word模板生成詳細的報告,使其可以適用於各種文件需求。
IronWord郵件合併適合自動化文件生成嗎?
是的,IronWord郵件合併適合自動化文件生成,允許開發者在其.NET應用程式中以程式化的方式建立個人化文件。



