C#测试调用OpenXml操作word文档的基本用法

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

相关推荐
almighty277 小时前
C#海康车牌识别实战指南带源码
c#·海康车牌识别·c#实现车牌识别·车牌识别源码·c#车牌识别
vfvfb10 小时前
word文档结尾批量插入图片 docx批量插入图片 指定几张
word·docx插入图片·word批量插入图片·word文档批量插入图片
c#上位机10 小时前
wpf之TextBlock
c#·wpf
almighty2719 小时前
C# WinForm分页控件实现与使用详解
c#·winform·分页控件·c#分页·winform分页
almighty2720 小时前
C#实现导入CSV数据到List<T>的完整教程
c#·csv·格式转换·c#导入数据·csv数据导入
程序猿多布21 小时前
Lua和C#比较
c#·lua
老马啸西风1 天前
sensitive-word 敏感词性能提升14倍优化全过程 v0.28.0
安全·开源·nlp·word·敏感词·sensitive-word
csdn_aspnet1 天前
使用 MongoDB.Driver 在 C# .NETCore 中实现 Mongo DB 过滤器
mongodb·c#·.netcore