首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 實作 Word MailMerge 結合 Excel 資料來源完整範例

     編輯:關於C語言

需求

使用 Word 郵件合併功能,資料來源為 Excel 工作表,透過 C# 自動化產出客製化文件(信函、標籤、合約等)。

前置準備

  1. Visual Studio 專案 → 參考 → COM → 勾選 Microsoft Word 1x.0 Object Library。
  2. 準備 Word 模板 (Template.docx):插入合併欄位(插入 → 快速組件 → 欄位 → MergeField)。
  3. 準備 Excel 資料 (Data.xlsx):第一列為欄位名稱,資料從第二列開始,工作表名稱如 Sheet1。

核心程式碼

using Word = Microsoft.Office.Interop.Word;
using System.Reflection;
using System.IO;

public class MailMergeHelper
{
    private readonly Word.Application _app;

    public MailMergeHelper()
    {
        _app = new Word.Application { Visible = false };
    }

    public void ExecuteMerge(string templatePath, string excelPath, string outputPath, 
        string sheetName = "Sheet1", string[] mergeFields = null)
    {
        object missing = Missing.Value;
        object falseVal = false;
        object trueVal = true;

        // 1. 複製模板與資料檔至暫存目錄(避免鎖定原檔)
        string tempDoc = CopyToTemp(templatePath);
        string tempXls = CopyToTemp(excelPath);

        // 2. 開啟 Word 文件
        Word.Document doc = _app.Documents.Open(tempDoc, ref missing, ref falseVal, 
            ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, 
            ref missing, ref missing, ref trueVal, ref missing, ref missing, ref missing);

        try
        {
            // 3. 設定郵件合併資料來源
            object linkTo = tempXls;
            object query = $"SELECT * FROM `{sheetName}$`"; // Excel SQL 查詢
            object header = string.Join(",", mergeFields ?? new[] { "Name", "Category", "Address", "Content" });

            doc.MailMerge.CreateDataSource(ref linkTo, ref missing, ref missing, 
                ref header, ref falseVal, ref query, ref missing, ref missing, ref trueVal);

            // 4. 可選:插入合併欄位至文件(若模板未預設)
            if (mergeFields != null)
            {
                foreach (string field in mergeFields)
                    doc.MailMerge.Fields.Add(_app.Selection.Range, field);
            }

            // 5. 執行合併並另存新檔
            doc.MailMerge.Destination = Word.WdMailMergeDestination.wdSendToNewDocument;
            doc.MailMerge.Execute(ref missing);

            // 6. 儲存合併後文件
            Word.Document mergedDoc = _app.ActiveDocument;
            mergedDoc.SaveAs2(outputPath, ref missing, ref missing, ref missing, 
                ref missing, ref missing, ref missing, ref missing, ref missing, 
                ref missing, ref missing, ref missing, ref missing, ref missing, 
                ref missing, ref missing);
            mergedDoc.Close(ref falseVal, ref missing, ref missing);
        }
        finally
        {
            doc.Close(ref falseVal, ref missing, ref missing);
            // 7. 覆寫 Excel 檔案(解決某些版本儲存後檔案損毀問題)
            File.Copy(tempXls, excelPath, true);
        }
    }

    private string CopyToTemp(string sourcePath)
    {
        string temp = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + Path.GetExtension(sourcePath));
        File.Copy(sourcePath, temp, true);
        return temp;
    }

    public void Dispose()
    {
        _app.Quit(ref falseVal, ref missing, ref missing);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(_app);
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}

使用範例

using (var helper = new MailMergeHelper())
{
    helper.ExecuteMerge(
        templatePath: @"C:\Templates\Letter.docx",
        excelPath: @"C:\Data\Customers.xlsx",
        outputPath: @"C:\Output\MergedLetters.docx",
        sheetName: "Sheet1",
        mergeFields: new[] { "Name", "Category", "Address", "Content" });
}

關鍵坑點與解決方案

問題原因解決
Excel 連結失敗工作表名稱需加 $ 且用反引號包裹查詢字串:SELECT * FROM `Sheet1$`
合併欄位不顯示模板未插入 MergeField 或欄位名稱不符確認模板欄位名稱與 header 參數完全一致
輸出檔案損毀/無法開啟Word 併發存取 Excel 導致鎖定複製至暫存目錄操作,結束後覆寫回原檔
Word 進程殘留COM 物件未正確釋放Marshal.ReleaseComObject + GC.Collect + Quit
伺服器端自動化不支援Microsoft 不建議在 Server 端自動化 Office改用 Open XML SDK、Aspose.Words 或 DocX 純 .NET 庫

現代替代方案(無 Office 安裝)

  • Open XML SDK:微軟官方,操作 .docx 封裝,效能高、無相依。
  • DocX (NuGet):簡潔 API,支援 MailMerge 類似功能。
  • Aspose.Words:商業庫,功能最完整,相容性最佳。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved