C# 使用 Open XML SDK 2.5 輸出 Word 文件

安裝套件

先使用 NuGet 安裝 DocumentFormat.OpenXml 套件,或是使用 .NET CLI 執行以下指令安裝
	
dotnet add package DocumentFormat.OpenXml --version 2.19.0
    

產生 Word 檔案

    
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;

using var wordDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);
wordDocument.Close();;
    

WordprocessingDocumentType.Document 就是平時最常用的 docx 檔案,而 WordprocessingDocumentType 列舉中總共有以下四種:
  • Document(Word 文件): .docx
  • Template(Word 範本): .dotx
  • MacroEnabledDocument(包含巨集的 Word 文件): .docm
  • MacroEnabledTemplate(包含巨集的 Word 範本): .dotm

輸入文字

在程式中 Word 的層級為檔案(WordprocessingDocument) > 主要文件區域(MainDocumentPart) > 文件(Document) > 身體(Body) > 段落(Paragraph) > 文本片段(Run) > 文字(Text)
    
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

string filepath = @"C:\Users\ruyut\Desktop\test\test.docx";
using var wordDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);

MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph paragraph = body.AppendChild(new Paragraph());
Run run = paragraph.AppendChild(new Run());
run.AppendChild(new Text("Hello, Word!"));

wordDocument.Close();

    
下面是簡化的具有同等效果的語法:
    
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

string filepath = @"C:\Users\ruyut\Desktop\test\test.docx";
using var wordDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);

MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document(
    new Body(
        new Paragraph(
            new Run(
                new Text("Hello, Word!")
            )
        )
    )
);

wordDocument.Close();

    

多段落、文字

如果想要放入多個段落,直接在 Paragraph 後面加上逗號,再加入 Paragraph 即可。
    
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document(
    new Body(
        new Paragraph(
            new Run(
                new Text("Name:"),
                new Text("Ruyut")
            )
        ),
        new Paragraph(
            new Run(
                new Text("Website:"),
                new Text("ruyut.com")
            )
        )
    )
);
    
想要插入換行可以使用 new Break() ,不過筆者發現 new Break() 產生的換行是呼是在 Word 中按下 Shift + Enter ,並不是 Enter ,如果知道如何插入 Enter 符號的歡迎留言補充

上面多個 Text 接續的部分並沒有差別,可以將內容放在同一個 Text 中可以達成相同的顯示效果。而多個 Run 也是,除非其中的文字格式不同,例如下面的顏色

調整字體、大小、顏色

可以在 Run 裡面再增加一個 RunProperties 來設定屬性:
    
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document(
    new Body(
        new Paragraph(
            new Run(
                new RunProperties(
                    new RunFonts { EastAsia = "標楷體" },
                    new FontSize { Val = "48pt" },
                    new Color { Val = "F5932A" }
                ),
                new Text("Ruyut")
            )
        )
    )
);

    

表格

    
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

string filepath = @"C:\Users\ruyut\Desktop\test\test.docx";
using var wordDocument = WordprocessingDocument.Create(filepath, WordprocessingDocumentType.Document);


Table table = new Table();

TableProperties tableProperties = new TableProperties();
TableBorders borders = new TableBorders
{
    TopBorder = new TopBorder { Val = BorderValues.Single }, // 上邊框
    BottomBorder = new BottomBorder { Val = BorderValues.Single }, // 下邊框
    LeftBorder = new LeftBorder { Val = BorderValues.Single }, // 左邊框
    RightBorder = new RightBorder { Val = BorderValues.Single }, // 右邊框
    InsideHorizontalBorder = new InsideHorizontalBorder { Val = BorderValues.Single }, // 內部水平邊框
    InsideVerticalBorder = new InsideVerticalBorder { Val = BorderValues.Single }, // 內部垂直邊框
};
tableProperties.Append(borders);
table.AppendChild(tableProperties);

TableRow row1 = new TableRow();
TableCell cell1 = new TableCell();
cell1.Append(new Paragraph(new Run(new Text("1-1"))));
TableCell cell2 = new TableCell();
cell2.Append(new Paragraph(new Run(new Text("1-2"))));
row1.Append(cell1, cell2);
table.AppendChild(row1);

table.AppendChild(
    new TableRow(
        new TableCell(
            new Paragraph(new Run(new Text("2-1")))
        ),
        new TableCell(
            new Paragraph(new Run(new Text("2-2")))
        )
    )
);

MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
mainPart.Document = new Document(
    new Body(
        table
    )
);

wordDocument.Close();
    


參考資料:
Github - dotnet/Open-XML-SDK
Microsoft.Learn - Open and add text to a word processing document (Open XML SDK)

留言