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文档并获取正文对象的主要代码如下:
csharp
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;
基于标记查找内容控件并输入文本的主要代码如下:
csharp
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];
}
}
}
查找并辅助表格的主要代码如下所示:
csharp
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