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

相关推荐
ajassi20008 小时前
开源 C# 快速开发(十)通讯--http客户端
开发语言·开源·c#
张人玉11 小时前
C# TCP - 串口转发
开发语言·tcp/ip·c#
ajassi200011 小时前
开源 C# 快速开发(四)自定义控件--波形图
开发语言·开源·c#
追烽少年x11 小时前
C# MVVM模式和Qt中MVC模式的比较
c#
ajassi200012 小时前
开源 C# 快速开发(九)通讯--Tcp客户端
开发语言·开源·c#
大飞pkz12 小时前
【设计模式】中介者模式
开发语言·设计模式·c#·中介者模式
lfq76120413 小时前
C#对称加密(AES)的简单代码
安全·c#·加密·对称加密
ajassi200013 小时前
开源 C# 快速开发(一)基础知识
开源·c#
虚行1 天前
C#上位机 通过ProfitNet连接西门子PLC教程--系统模拟环境搭建
学习·c#·plc
雪域迷影1 天前
C++/C#游戏开发引擎和2D/3D图形库
c++·3d·c#