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

C# 使用 Microsoft Office Interop Word 自動化處理文件:開啟、書籤替換、儲存完整範例

     編輯:關於C#

前置需求

  • 安裝 Microsoft Office (含 Word) 或至少 Word 獨立安裝。
  • 專案參考 Microsoft.Office.Interop.Word (NuGet: Microsoft.Office.Interop.Word 或 COM 參考)。
  • 目標平台設為 x64 (若 Office 為 64 位元) 或 x86 (32 位元),不可 Any CPU (Prefer 32-bit 勾選視 Office 位元而定)。

完整自動化類別實作

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

public class WordProcessor : IDisposable
{
    private Application _app;
    private Document _doc;
    private bool _disposed;

    public WordProcessor(bool visible = false)
    {
        _app = new Application { Visible = visible };
        // 關閉自動更新欄位、自動儲存提示等干擾
        _app.DisplayAlerts = WdAlertLevel.wdAlertsNone;
        _app.Options.SaveNormalTemplate = false;
    }

    /// 
    /// 開啟範本檔,另存為新檔並處理書籤
    /// 
    public void ProcessTemplate(string templatePath, string outputPath, Dictionary bookmarks)
    {
        if (!File.Exists(templatePath))
            throw new FileNotFoundException("範本檔不存在", templatePath);

        object missing = Missing.Value;
        object fileName = templatePath;
        object readOnly = false;
        object isVisible = false;

        _doc = _app.Documents.Open(ref fileName, ref missing, ref readOnly, ref missing, ref missing,
            ref missing, ref missing, ref missing, ref missing, ref missing,
            ref missing, ref isVisible, ref missing, ref missing, ref missing, ref missing);

        // 另存為新檔 (保留原範本)
        object newFileName = outputPath;
        _doc.SaveAs2(ref newFileName, 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);

        // 替換書籤內容
        foreach (var kvp in bookmarks)
        {
            if (_doc.Bookmarks.Exists(kvp.Key))
            {
                Range range = _doc.Bookmarks[kvp.Key].Range;
                range.Text = kvp.Value;
                // 重新建立書籤以便後續再次替換
                _doc.Bookmarks.Add(kvp.Key, range);
            }
        }

        _doc.Save();
    }

    /// 
    /// 直接開啟現有檔案處理 (不另存)
    /// 
    public void ProcessExisting(string filePath, Dictionary bookmarks)
    {
        object missing = Missing.Value;
        object fileName = filePath;
        _doc = _app.Documents.Open(ref fileName, 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);

        foreach (var kvp in bookmarks)
        {
            if (_doc.Bookmarks.Exists(kvp.Key))
            {
                Range range = _doc.Bookmarks[kvp.Key].Range;
                range.Text = kvp.Value;
                _doc.Bookmarks.Add(kvp.Key, range);
            }
        }
        _doc.Save();
    }

    public void Dispose()
    {
        if (_disposed) return;
        try
        {
            _doc?.Close(WdSaveOptions.wdDoNotSaveChanges);
            _app?.Quit();
        }
        catch { /* 忽略關閉錯誤 */ }
        finally
        {
            // 釋放 COM 物件
            if (_doc != null) Marshal.ReleaseComObject(_doc);
            if (_app != null) Marshal.ReleaseComObject(_app);
            _doc = null;
            _app = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        _disposed = true;
    }
}

呼叫範例

var bookmarks = new Dictionary
{
    { "ClientName", "王小明" },
    { "Date", DateTime.Today.ToString("yyyy年MM月dd日") },
    { "Amount", "NT$ 1,234,567" },
    { "Address", "台北市信義區信義路五段7號" }
};

using (var wp = new WordProcessor(visible: false))
{
    wp.ProcessTemplate(@"C:\Templates\Contract.docx", @"C:\Output\Contract_王小明.docx", bookmarks);
}
Console.WriteLine("文件產生完成");

關鍵技術點

項目說明
書籤替換必須先取得 Range,設定 Text,再 Bookmarks.Add 重建書籤,否則書籤會被覆寫消失。
儲存方法SaveAs2 (Word 2010+) 支援更多格式參數;SaveAs 為舊版相容。
隱藏 Word 視窗建構子 Visible = false,生產環境必須隱藏,否則會彈出視窗干擾。
記憶體洩漏務必 Marshal.ReleaseComObject 釋放 RCW,並呼叫 GC.Collect 強制清理。
例外處理COM 例外為 COMException,錯誤碼 0x800Axxxx 可查 MSDN 對照。

替代方案:Open XML SDK (無需安裝 Office)

// NuGet: DocumentFormat.OpenXml
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

using (var doc = WordprocessingDocument.Open(@"C:\Output\Contract.docx", true))
{
    var body = doc.MainDocumentPart.Document.Body;
    // 文字替換、表格操作、樣式設定... 純 XML 操作,效能極佳、無相依性
}

建議: 伺服器端批次產生文件請優先使用 Open XML SDK;僅需客戶端互動、列印、宏執行才用 Interop。

參考資源

原文連結:https://www.bianceng.cn/Programming/csharp/201410/45580.htm

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved