C# 使用openxml解析PPTX中的文本内容
目录
一、依赖类库
二、解析步骤
1.引入库
2.读取数据
2.1 直接保存在slide*.xml文件的节点数据
2.2 以oleObject对象的形式存储在word文档中
2.3 以oleObject对象的形式存储在bin文件中
参考资料:
前言
本文讨论的仅针对微软Office 2007以后的(OOXML定义)PowerPoint文档,Office 2007以前的用二进制格式定义的(ppt格式)文档不在本文讨论范围。
一、依赖类库
本文需要依赖两个免费的第三方类库:DocumentFormat.OpenXml和FreeSpire.Doc。
DocumentFormat.OpenXml用于加载解析pptx文档,FreeSpire.Doc用于解析pptx中嵌入的doc文档内容,详见解析嵌入的doc的文本。
二、解析步骤
1.引入库
通过Nuget引入类库
<packages><package id="DocumentFormat.OpenXml" version="2.13.0" targetFramework="net452" /><package id="FreeSpire.Doc" version="7.11.0" targetFramework="net452" />
</packages>
2.读取数据
PPTX中的文本内容主要以三种形式存储。1、直接保存在slide*.xml文件的节点数据;2、以oleObject对象的形式存储在word文档中;3、以oleObject对象的形式存储在bin文件中。接下来针对这三种情况分别分析如何解析获取内容。
首先需要读取pptx文件,解析每一个页面的slide对象
using (var presentationDocument = PresentationDocument.Open(filePath, false))
{var presentationPart = presentationDocument.PresentationPart;var presentation = presentationPart.Presentation;// 先获取页面var slideIdList = presentation.SlideIdList;foreach (var slideId in slideIdList.ChildElements.OfType<SlideId>()){//TODO:解析页面的内容}
2.1 直接保存在slide*.xml文件的节点数据
直接保存在slide*.xml文件的文本数据只需遍历页面中的每一个paragraph对象即可,需要注意的是此处的用到的是DocumentFormat.OpenXml.Drawing.Paragraph。
foreach (var paragraph inslidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
{contentText.Length = 0;foreach (var text in paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>()){contentText.Append(text.InnerText);}
}
2.2 以oleObject对象的形式存储在word文档中
oleObject对象在slide*.xml文件中记录形式如下图:
progId的值为“Word.Document.8”表示嵌入的对象是Office 2007以前的数据格式,值为“Word.Document.12”表示嵌入的对象是Office 2007以后的OOXML定义的数据格式。通过r:id的值获取嵌入的文件对象及其ContentType。值为 "application/vnd.openxmlformats-officedocument.wordprocessingml.document"表示嵌入的对象是word文档,值为"application/vnd.openxmlformats-officedocument.oleObject"标识嵌入的是bin文件。
Office 2007以后的OOXML定义的数据格式直接通过DocumentFormat.OpenXml解析,需要注意的是在解析word中的段落需要用DocumentFormat.OpenXml.Wordprocessing.Paragraph。
foreach (var choice in slidePart.Slide.Descendants<DocumentFormat.OpenXml.AlternateContentChoice>())
{foreach (var oleobject inchoice.Descendants<DocumentFormat.OpenXml.Presentation.OleObject>()){if (oleobject.ProgId.Value == "Word.Document.12"){var part = slidePart.GetPartById(oleobject.Id);if (part.ContentType == "application/vnd.openxmlformats-officedocument.wordprocessingml.document"){using (var stream = part.GetStream(FileMode.Open, FileAccess.Read)){using (var wordDocument = WordprocessingDocument.Open(stream, false)){var mainDocumentPart = wordDocument.MainDocumentPart;var body = mainDocumentPart.Document.Body;foreach (DocumentFormat.OpenXml.Wordprocessing.Paragraph paragraph in body.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>()){ contentText.Length = 0;foreach (var text in paragraph.Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>()){contentText.Append(text.InnerText);}}}}}}}
}
Office 2007以前的数据格式借助FreeSpire.Doc解析
else if (oleobject.ProgId.Value == "Word.Document.8"){var part = slidePart.GetPartById(oleobject.Id);var stream = part.GetStream(FileMode.Open, FileAccess.Read);Spire.Doc.Document doc = new Spire.Doc.Document(stream);foreach (Spire.Doc.DocumentObject child in doc.Sections[0].Body.ChildObjects){if (child is Spire.Doc.Documents.Paragraph)paraList.Add((child as Spire.Doc.Documents.Paragraph).Text);else if (child is Spire.Doc.Table){Spire.Doc.Table table = child as Spire.Doc.Table;foreach (Spire.Doc.TableRow row in table.Rows){foreach (Spire.Doc.TableCell cell in row.Cells){foreach (Spire.Doc.Documents.Paragraph paragraph in cell.Paragraphs){paraList.Add(paragraph.Text);}}}}}stream.Dispose();}
2.3 以oleObject对象的形式存储在bin文件中
这种情况需要通过StgOpenStorage解析oleObject对象提取word数据的文件流:
[DllImport("ole32.dll")]private static extern int StgIsStorageFile([MarshalAs(UnmanagedType.LPWStr)] string pwcsName);[DllImport("ole32.dll")]static extern int StgOpenStorage([MarshalAs(UnmanagedType.LPWStr)] string pwcsName,IStorage pstgPriority,STGM grfMode,IntPtr snbExclude,uint reserved,out IStorage ppstgOpen);public MemoryStream parseOleObject(string fileName){MemoryStream outBuffer=default(MemoryStream);if (StgIsStorageFile(fileName) == 0){IStorage storage = null;if (StgOpenStorage(fileName,null,STGM.DIRECT | STGM.READ | STGM.SHARE_EXCLUSIVE,IntPtr.Zero,0,out storage) == 0){System.Runtime.InteropServices.ComTypes.STATSTG statstg;storage.Stat(out statstg, (uint)STATFLAG.STATFLAG_DEFAULT);IEnumSTATSTG pIEnumStatStg = null;storage.EnumElements(0, IntPtr.Zero, 0, out pIEnumStatStg);System.Runtime.InteropServices.ComTypes.STATSTG[] regelt = { statstg };uint fetched = 0;uint res = pIEnumStatStg.Next(1, regelt, out fetched);if (res == 0){while (res != 1){string strNode = statstg.pwcsName;if (strNode == "Package"){switch (statstg.type){case (int)STGTY.STGTY_STORAGE:{IStorage pIChildStorage;storage.OpenStorage(statstg.pwcsName,null,(uint)(STGM.READ | STGM.SHARE_EXCLUSIVE),IntPtr.Zero,0,out pIChildStorage);}break;case (int)STGTY.STGTY_STREAM:{IStream pIStream;storage.OpenStream(statstg.pwcsName,IntPtr.Zero,(uint)(STGM.READ | STGM.SHARE_EXCLUSIVE),0,out pIStream);outBuffer = pIStream.ReadToMemoryStream();Marshal.FinalReleaseComObject(pIStream);Marshal.FinalReleaseComObject(pIEnumStatStg);Marshal.FinalReleaseComObject(storage);return outBuffer;}break;}}if ((res = pIEnumStatStg.Next(1, regelt, out fetched)) != 1){statstg = regelt[0];}}}}}return outBuffer;}
解析oleObject对象提取word数据的文件流后按照解析word对象的方式解析数据即可。
参考资料:
Office OpenXml SDK 使用 Fallback 图片显示 Ole 元素
reading-compound-documents-in-c-sharp
C# 使用openxml解析PPTX中的文本内容相关推荐
- js中显示一个指定html文档,JS实现选定指定HTML元素对象中指定文本内容功能示例...
本文实例讲述了JS实现选定指定HTML元素对象中指定文本内容功能.分享给大家供大家参考,具体如下: 该功能用处多多,可以灵活运用之!主要函数如下: //选中文本中指定部分 function selec ...
- PHP开发小技巧①⑥—提取富文本字符串中的文本内容
综述 富文本在我们平常的项目中应用已经很广泛了,并逐渐发展成了一个行业.最近在项目中遇到需要提取富文本字符串中的文本内容,本篇博文就是记述如何重富文本字符串中提取出文本内容,欢迎大家相互学习. 富文本 ...
- php 提取文字,如何使用PHP从word文档中提取文本内容?
我想用PHP从word文档中提取文本内容. 我在Microsoft Word for Mac 2011中创建了一个新的单词文档. 编辑:也通过在Windows 7中的Microsoft Word中创建 ...
- 200826-C语言打印文件中的文本内容
1. Description 在桌面上创建一个txt文件,输入一些文本内容,我们的任务是把文本内容打印出来. 在编程之前,关于一些函数的定义我们需要了解下. fopen fopen的函数原型为: FI ...
- C# 读取Word文档中的文本内容
C# 读取Word文档中的文本内容 这篇文章将介绍如何使用C#和Free Spire.Doc组件读取Word文档中的文本内容.Free Spire.Doc提供了两种方法来读取Word文档中的内容,一种 ...
- Free Spire.Doc组件C# 读取Word文档中的文本内容
C# 读取Word文档中的文本内容 这篇文章将介绍如何使用C#和Free Spire.Doc组件读取Word文档中的文本内容.Free Spire.Doc提供了两种方法来读取Word文档中的内容,一种 ...
- openxml html to word,C# Net 使用 openxml 提取word中的文本和图片并转为Html
C# Net Core openxml 提取 提出 取 word 文本 图片 Html Text Drawing C# Net Core openxml 提取 提出 取 word 文本 图片 ...
- itextsharp 获取文本_利用iTextSharp提取PDF文件中的文本内容
最近测试中需要对比两个PDF文件的内容,当然只是文字没有图表的,但是没有现成的工具可用.于是我的想法是先把PDF转换为Text,然后再对比Text的内容.现在问题的关键变成了如何提取PDF中的文本,在 ...
- Java 读取Word文档中的文本内容
这篇文章将介绍如何使用Free Spire.Doc for Java组件在Java应用程序中读取Word文档的文本内容.Free Spire.Doc for Java提供了两种方法来读取Word文档中 ...
- java 网络 xml_java|安卓解析网络中xml的内容
重要:本文最后更新于2018-01-22 12:56:12,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗. 由于以前在写程序的时候条件太宽松,基本上都可以在json和xml中选择一种 ...
最新文章
- python ix loc iloc_pandas中的iloc、loc、ix有什么区别?
- authorization 传 就跨域_JavaScript 使用 headers Authorization 存放 token 出现跨域错误?...
- matlab、python使用小方法收集
- MSN工具条不兼容IE7
- IP选路与动态选路协议(六)
- php旋转数组找出最小的,LeetCode 153 寻找旋转排序数组中的最小值
- PCL: 根据几何规则的曲面剖分-贪婪法表面重建三角网格
- NVIDIA显卡驱动版本,CUDA版本,cudnn版本之间关系及如何选择
- altium designer快捷键大全
- java 数组减除值_java数组操作 - osc_hwpd2zko的个人空间 - OSCHINA - 中文开源技术交流社区...
- 不生效_离婚协议签订后,对方反悔不生效,但证据价值巨大!
- 写题10分钟,写题解8小时,一道头条面试题,真心难。
- 组态王、力控、MCGS、瑞尔、杰控等国内组态软件一点看法
- Android Framework - 学习启动篇
- 1.Spring注解01、组件注册-@Configuration@Bean给容器中注册组件
- php revel,Revel 概念
- Linux修仙之路——RAID技术
- html app下载页功能开发
- thinkphp的I方法
- 通过数据可视化进行足球进球方式分析球员属性