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;
}

  封面内容替换的程序运行效果如下所示,表格复制内容都是相同的,就不再重复截图。

参考文献:

1https://github.com/dotnet/Open-XML-SDK

2https://learn.microsoft.com/zh-cn/office/open-xml/open-xml-sdk

相关推荐
三声三视1 小时前
Word 转 Markdown 报“保真率 98%“,可那张表散了
word·word转markdown·格式转换·开发者工具·tri-docx2md·结构保真
格林威2 小时前
C# 相机Burst模式图像采集:使用相机内存配合OpenCvSharp和Halcon实现短时间的高速采集的方法
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
J总裁的小芒果3 小时前
参数过多-分批传参
c#
典典分享指南3 小时前
短视频分镜提示词:让 AI 出片的产品口播
java·c#·bash·composer·symfony
Z5998178414 小时前
c#软件开发学习笔记--WPF(Canvas、数据绑定、MVVM模式、值转换器)
笔记·学习·c#
淡海水6 小时前
05-03-栈队列-PriorityQueue-TElement-TPriority-NET6优先队列语义与四叉堆实现
服务器·前端·c#·priorityqueue·clr·telement
课件帮8 小时前
从Word教案到带讲解微课:课件帮一键成片全流程实操
word
2601_949950639 小时前
Word、PDF、Excel题目怎么快速整理?
pdf·word·excel
leonkay19 小时前
C# 特性(Attribute)——【1】基础讲解
开发语言·青少年编程·面试·c#·.net·个人开发
CSDN_RTKLIB20 小时前
数据库七大符号表
c#