??OpenXML SDK是微軟為高效處理Office文檔(如Word、Excel)而開發的開源.NET庫,它直接操作文檔內部的XML結構,無需安裝Office軟件即可實現文檔的創建、讀取和編輯,常用于服務器端批量生成報表、自動化文檔處理等場景,輕量且跨平臺。本文學習基于OpenXML SDK打開word文檔查找輸入框并插入內容、查找并復制表格的基本用法。
??VS2022創建控制臺程序,在Nuget包管理器中搜索并安裝DocumentFormat.OpenXml包。
??使用DeepSeek生成帶封面和表格的兩頁文檔用于功能測試(實際上生成的是html文件,下載到本地后用word打開又另存為word),如下圖所示。
??在word軟件的選項中啟用開發工具菜單,然后在開發工具菜單欄中使用屬性菜單設置封面中輸入框的標記,同時通過表格屬性設置表格的標題,以便后續通過程序能夠查找相應的內容。
??OpenXML SDK中WordprocessingDocument類代表文檔對象,使用WordprocessingDocument.Open函數打開word文檔,該函數支持通過文件路徑或文件流形式打開文檔。
??MainDocumentPart、Body、SdtElement 和Table 是處理 Word 文檔(.docx)的核心類,下表列出其簡要介紹和用途:
類 | 說明 | 所在命名空間 | 常用屬性/方法 |
---|---|---|---|
MainDocumentPart | 代表 Word 文檔的主文檔部分,是操作文檔內容的入口點。 | DocumentFormat.OpenXml.Packaging | Document (獲取文檔對象), AddNewPart() (添加新部件), GetPartById(String) (通過ID獲取部件) |
Body | 表示 Word 文檔的正文,是段落、表格等塊級元素的容器。 | DocumentFormat.OpenXml.Wordprocessing | AppendChild(OpenXmlElement) (添加子元素), Descendants() (獲取特定類型的后代元素), Elements() (獲取子元素) |
SdtElement | 代表內容控件(Structured Document Tag),用于創建結構化、可重復使用的文檔區域或表單。 | DocumentFormat.OpenXml.Wordprocessing | Descendants(), SdtProperties (獲取內容控件的屬性), SdtContentBlock (獲取內容塊) |
Table | 表示 Word 文檔中的一個表格,由行(TableRow)和單元格(TableCell)組成。 | DocumentFormat.OpenXml.Wordprocessing | AppendChild(TableRow), TableProperties (表格屬性), Descendants() |
??基于上述類,打開word文檔并獲取正文對象的主要代碼如下:
Dictionary<string, string> dicTest = new Dictionary<string, string>();
dicTest.Add("filename", "測試文件名稱");
dicTest.Add("filecode", "test-file-code-001");
dicTest.Add("createtime", DateTime.Now.ToString());
dicTest.Add("dept", "測試部門");
dicTest.Add("editor", "tom");WordprocessingDocument doc = WordprocessingDocument.Open(fileStream, true);
MainDocumentPart mainPart = doc.MainDocumentPart;
Body body = mainPart.Document.Body;
??基于標記查找內容控件并輸入文本的主要代碼如下:
var contentControls = Body.Descendants<SdtElement>();foreach (var control in contentControls)
{// 獲取內容控件的標記var tag = control.Descendants<Tag>().FirstOrDefault()?.Val?.Value;if (tag != null && dicTest.ContainsKey(tag)){// 找到文本元素并替換內容var textElement = control.Descendants<Text>().FirstOrDefault();if (textElement != null){textElement.Text = dicTest[tag];}}
}
??查找并輔助表格的主要代碼如下所示:
Table targetTable = FindTableByTableTitle(body, tableTitle);
Table clonedTable = (Table)targetTable.CloneNode(true);
body.AppendChild(clonedTable );private static Table FindTableByTableTitle(Body body, string title)
{// 查找所有表格var tables = body.Descendants<Table>();foreach (var table in tables){// 獲取表格屬性var tableProperties = table.Elements<TableProperties>().FirstOrDefault();if (tableProperties != null){// 獲取表格標題var tableCaption = tableProperties.Elements<TableCaption>().FirstOrDefault();if (tableCaption != null && tableCaption.Val != null && tableCaption.Val.Value.Equals(title, StringComparison.OrdinalIgnoreCase)){return table;}}}return null;
}
??封面內容替換的程序運行效果如下所示,表格復制內容都是相同的,就不再重復截圖。
參考文獻:
[1]https://github.com/dotnet/Open-XML-SDK
[2]https://learn.microsoft.com/zh-cn/office/open-xml/open-xml-sdk