news 2026/4/18 9:26:00

从零开始:C# 解析docx提取文本-无需安装office软件且完美支持aot

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零开始:C# 解析docx提取文本-无需安装office软件且完美支持aot

docx格式了解

docx 文件是 Microsoft Office Word 使用的基于 XML 的文件格式,Open XML。Open XML 格式使用 zip 压缩技术来存储文档,从而节省潜在的成本。 在打开文件时,Office程序会自动对文件进行解压。 在保存文件时,会再次对文件自动进行压缩。 比如可以把任意docx,pptx文件后缀改为.zip,可以看到压缩包中有多个xml格式文件和图片素材。

pptxZip

微软官方提供了Open XML SDK 库来处理符合 Office Open XML 文件格式规范的文档。 Office Open XML 文件格式规范是一个开放的、国际的 ECMA-376、第 5 版 和 ISO/IEC 29500 标准。Open XML SDK 简化了操作 Open XML 包和包中基础 Open XML 架构元素的任务。 Open XML SDK 封装开发人员在 Open XML 包上执行的许多常见任务,因此只需几行代码即可执行复杂的操作。

因此我们首选使用Open XML SDK来解析docx文件,不需要安装任何office软件且完美支持aot编译。

二 文件解析与文本提取

首先需要在项目里去Nuget安装OpenXml, 以下示例中的版本是。DocumentFormat.OpenXml(3.3.0), Net9。

2.1 docx格式文本提取

docx格式文件对应的操作类是WordprocessingDocument, 需要用静态方法来实例化 using var doc = WordprocessingDocument.Open(filePath,isEditable: false),此时OpenXml已经帮我们把xml对象都转成具体类型了。

Document: 文档的根元素,包含了文档的主体内容

Body 元素**: 位于 Document 元素中,包含了文档的主体部分。

如果是纯文本,Document.innerText 或 Body.innerText可以直接提取出所有字符串内容,但是其中表格文本是连在一起即没有任何分隔符的。因此最好还是考虑对内部元素进行遍历。

2.2 OpenXmlElement对象遍历

如果是提取文本,可以在文档的Body.Elements中遍历OpenXmlElement。在方法doc.body.Elements<T>()中T表示继承OpenXmlElement的泛型。我们需要关注的类型主要有:

Paragraph: 段落,可直接获取文本;

Table、TableRow、TableCell: 表格、表行、单元格,需要再次遍历单元格的段落获取文本;

SdtElement: 控件中的显示文本(文本框控件、下拉菜单控件),需要遍历文本框的段落获取文本。

2.4 其他OpenXmlElement对象

其他OpenXmlElement对象我们可以通过检视对象的的ChildElements,找到包含感兴趣文本的类型,然后获取。

OpenXmlElement

2.3 批注提取

批注内容通常存储在 CommentsPart 中,而不是直接存储在文档的主体部分。因此我们需要遍历doc.MainDocumentPart.WordprocessingCommentsPart.Comments容器。

foreach (var p in wordDocument?.MainDocumentPart.WordprocessingCommentsPart.Comments)

{

if (!string.IsNullOrWhiteSpace(p.InnerText))

{

sb.AppendLine(p.InnerText);

}

}

2.4 最小实现的代码

具体代码如下:

using DocumentFormat.OpenXml.Packaging;

using DocumentFormat.OpenXml.Wordprocessing;

using System.Text;

var text = ExtractText(@"d:\reference.docx");

Console.Write(text);

static StringBuilder ExtractText(string filePath)

{

var sb = new StringBuilder();

using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(filePath, isEditable: false))

{

Body? body = wordDocument?.MainDocumentPart?.Document?.Body;

if (body != null)

{

foreach (var p in body.Elements<Paragraph>())

{

if (!string.IsNullOrWhiteSpace(p.InnerText))

{

sb.AppendLine(p.InnerText);

}

}

foreach (var p in wordDocument?.MainDocumentPart.WordprocessingCommentsPart.Comments)

{

if (!string.IsNullOrWhiteSpace(p.InnerText))

{

sb.AppendLine(p.InnerText);

}

}

foreach (Table table in body.Elements<Table>())

{

foreach (TableRow row in table.Elements<TableRow>())

{

foreach (TableCell cell in row.Elements<TableCell>())

{

foreach (Paragraph p in cell.Elements<Paragraph>())

{

if (!string.IsNullOrWhiteSpace(p.InnerText))

{

sb.AppendLine(p.InnerText);

}

}

}

}

}

foreach (var sdt in body.Elements<SdtElement>())

{

foreach (Paragraph p in sdt.Descendants<Paragraph>())

{

if (!string.IsNullOrWhiteSpace(p.InnerText))

{

sb.AppendLine(p.InnerText);

}

}

}

}

wordDocument.Dispose();

}

return sb;

}

以上项目AOT发布后得到的Exe也就19.5MB,启动速度很快。基于进程的调用与通信,可以方便为其他程序调用从而快速提供docx文本解析能力。

三 最后

本文分享了在docx格式文件中提取文本过程。对于如pptx、xlsx等offce格式提取文本的操作也是类似的,但会因文档结构会与docx有较大不同,后续再给大家分享。

如果你对本文建议或想法,欢迎随时交流。请关注我们的公众号萤火初芒,以后会和大家分享更多有趣内容,一起学习交流进步。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 7:13:47

联想拯救者工具箱:游戏本性能调优的终极指南

联想拯救者工具箱&#xff1a;游戏本性能调优的终极指南 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit 还在为官方软件占用…

作者头像 李华
网站建设 2026/4/18 7:29:04

2025年职业院校技能大赛高职组“区块链技术应用”食品安全溯源智能合约开发与测试参考答案

2025年职业院校技能大赛高职组“区块链技术应用”食品安全溯源&智能合约开发与测试参考答案 文章目录 2025年职业院校技能大赛高职组“区块链技术应用”食品安全溯源&智能合约开发与测试参考答案 竞赛试题: 模块二:智能合约开发与测试(30分) 任务2-1:智能合约设计…

作者头像 李华
网站建设 2026/4/18 3:49:12

如何分析测试任务及需求(附分析流程)

测试分析 确认测试范围 根据测试项目的不同需求&#xff0c;有大致几类测试项目类型&#xff1a;商户/平台功能测试、支付方式接入测试、架构调整类测试、后台优化测试、性能测试、基本功能自动化测试。 测试项目需要按照文档要求进行测试需求分析&#xff0c;并给出对应的输…

作者头像 李华
网站建设 2026/4/18 7:01:32

AI 狂飙时代:IT 从业者会被“清理门户”,还是“原地飞升”?

&#x1f32a;️ 前言&#xff1a;暴风眼中的焦虑 “我的代码 AI 写得比我快&#xff0c;还比我 Bug 少。” “Devin 都能自己接单了&#xff0c;我还学 Java 干什么&#xff1f;” 2024-2025 年&#xff0c;IT 行业仿佛经历了一场“三体人”的入侵。从 ChatGPT 到 DeepSeek&am…

作者头像 李华
网站建设 2026/4/18 8:26:47

线代第二章矩阵第四课:方阵的幂

方阵的幂是矩阵运算中的重要内容&#xff0c;只有方阵能定义幂运算&#xff0c;其运算规则和性质有别于普通数的幂运算&#xff0c;下面从定义、核心性质、常用计算方法和典型例题这几个核心方面展开讲解&#xff0c;帮你系统掌握该知识点&#xff1a;基本定义只有 n 阶方阵&am…

作者头像 李华
网站建设 2026/4/18 5:32:32

高效窗口管理新选择:跨平台窗口信息获取工具详解

高效窗口管理新选择&#xff1a;跨平台窗口信息获取工具详解 【免费下载链接】active-win Get metadata about the active window (title, id, bounds, owner, etc) 项目地址: https://gitcode.com/gh_mirrors/ac/active-win 您是否曾经遇到过这样的困扰&#xff1a;在多…

作者头像 李华