前置準備
- 專案加入 COM 參考:Microsoft Word 14.0/15.0/16.0 Object Library(依 Office 版本)
- 引入命名空間:
using Word = Microsoft.Office.Interop.Word;
- 注意:伺服器端自動化 Word 需安裝 Office、注意 DCOM 權限與互動式登入,建議改用 Open XML SDK 或第三方庫(如 DocX、NPOI)於無人值守環境。
核心程式碼架構
public string CreateReport(string outputDir, ReportData data) {
var wordApp = new Word.Application { Visible = false };
Word.Document doc = null;
try {
object missing = Type.Missing;
doc = wordApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);
// 頁眉
SetupHeader(wordApp, "機密文件");
// 內文與表格
var table = doc.Tables.Add(wordApp.Selection.Range, rows: 12, columns: 3);
SetupTableStyle(table);
FillTableContent(table, data);
// 落款
doc.Paragraphs.Last.Range.Text = $"文件建立時間:{DateTime.Now:yyyy-MM-dd HH:mm}";
doc.Paragraphs.Last.Alignment = Word.WdParagraphAlignment.wdAlignParagraphRight;
// 儲存
var fileName = $"Report_{DateTime.Now:yyyyMMddHHmmss}.docx";
var fullPath = Path.Combine(outputDir, fileName);
doc.SaveAs2(fullPath);
return fileName;
}
finally {
doc?.Close(ref missing, ref missing, ref missing);
wordApp.Quit(ref missing, ref missing, ref missing);
// 釋放 COM 物件
if (doc != null) Marshal.ReleaseComObject(doc);
Marshal.ReleaseComObject(wordApp);
GC.Collect(); GC.WaitForPendingFinalizers();
}
}
關鍵操作封裝方法
頁眉/頁腳
void SetupHeader(Word.Application app, string text) {
app.ActiveWindow.View.Type = Word.WdViewType.wdOutlineView;
app.ActiveWindow.ActivePane.Selection.HeaderFooter.LinkToPrevious = false;
app.ActiveWindow.ActivePane.Selection.HeaderFooter.Range.Text = text;
app.ActiveWindow.ActivePane.Selection.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphRight;
app.ActiveWindow.View.SeekView = Word.WdSeekView.wdSeekMainDocument;
}
表格樣式與合併儲存格
void SetupTableStyle(Word.Table table) {
table.Borders.OutsideLineStyle = Word.WdLineStyle.wdLineStyleThickThinLargeGap;
table.Borders.InsideLineStyle = Word.WdLineStyle.wdLineStyleSingle;
table.Columns[1].Width = 100f;
table.Columns[2].Width = 220f;
table.Columns[3].Width = 105f;
}
void MergeCells(Word.Table table, int row, int col1, int col2) {
table.Cell(row, col1).Merge(table.Cell(row, col2));
table.Cell(row, col1).VerticalAlignment = Word.WdCellVerticalAlignment.wdCellAlignVerticalCenter;
table.Cell(row, col1).Range.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
}
插入圖片並設定文字環繞
void InsertPicture(Word.Application app, Word.Document doc, string imagePath, float width, float height) {
var shape = doc.Application.ActiveDocument.InlineShapes
.AddPicture(imagePath, LinkToFile: false, SaveWithDocument: true, Anchor: app.Selection.Range)
.ConvertToShape();
shape.WrapFormat.Type = Word.WdWrapType.wdWrapSquare;
shape.Width = width;
shape.Height = height;
}
常見坑與解法
- COM 物件未釋放導致 Word 残留進程:務必
Marshal.ReleaseComObject + GC.Collect()
- 儲存格式:
SaveAs2 指定 Word.WdSaveFormat.wdFormatXMLDocument 產生 .docx
- 多執行緒:Word COM 為 STA,ASP.NET 中需
AspCompat="true" 或改用 Open XML SDK
- 大量資料:考慮先產生 HTML/RTF 再轉換,或使用 Mail Merge 範本模式
現代替代方案
- Open XML SDK:微軟官方、無需安裝 Office、效能高、適合伺服器端
- DocX (NuGet):封裝 Open XML,API 友善
- NPOI:支援 .doc/.xls/.ppt 與 .xlsx/.docx