news 2026/6/7 22:17:23

从零开始: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/6/5 17:00:58

专业仿写Prompt:打造高质量数据库文档工具文章

专业仿写Prompt&#xff1a;打造高质量数据库文档工具文章 【免费下载链接】DBCHM DBCHM修改版本&#xff0c;支持导出数据库字典分组 The modified version of dbchm supports exporting database dictionary groups ( chm/word/markdown/html) 项目地址: https://gitcode.c…

作者头像 李华
网站建设 2026/6/7 13:45:38

面试必备:掌握这些自动化面试题,让你在面试中稳操胜券!

面试时&#xff0c;自动化是软件测试高频面试内容&#xff0c;通过学习和准备面试题&#xff0c;你会对可能遇到的问题有所准备&#xff0c;从而减轻面试时的紧张感&#xff0c;让你在面试中稳操胜券&#xff01;今天&#xff0c;分享一些在面试中可能会遇到的自动化测试面试问…

作者头像 李华
网站建设 2026/6/6 21:22:31

RNFetchBlob终极指南:移动端文件操作与网络传输的完整解决方案

RNFetchBlob终极指南&#xff1a;移动端文件操作与网络传输的完整解决方案 【免费下载链接】rn-fetch-blob 项目地址: https://gitcode.com/gh_mirrors/rn/rn-fetch-blob 在移动应用开发中&#xff0c;文件操作和网络传输是每个开发者都会遇到的挑战。RNFetchBlob作为R…

作者头像 李华
网站建设 2026/6/6 13:35:20

测试文章标题03

测试文章内容这是一篇测试文章

作者头像 李华
网站建设 2026/6/6 5:22:05

面试必问的7大测试分类!一文说清楚!

在日常测试工作中&#xff0c;我们经常会听到“单元测试&#xff0c;集成测试&#xff0c;系统测试”之类的词汇&#xff0c;大家都知道这是按照开发阶段进行测试活动的划分。这种划分完整的分类&#xff0c;其实是分为四种“单元测试&#xff0c;集成测试&#xff0c;系统测试…

作者头像 李华