目录

一、依赖类库

二、解析步骤

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中的文本内容相关推荐

  1. js中显示一个指定html文档,JS实现选定指定HTML元素对象中指定文本内容功能示例...

    本文实例讲述了JS实现选定指定HTML元素对象中指定文本内容功能.分享给大家供大家参考,具体如下: 该功能用处多多,可以灵活运用之!主要函数如下: //选中文本中指定部分 function selec ...

  2. PHP开发小技巧①⑥—提取富文本字符串中的文本内容

    综述 富文本在我们平常的项目中应用已经很广泛了,并逐渐发展成了一个行业.最近在项目中遇到需要提取富文本字符串中的文本内容,本篇博文就是记述如何重富文本字符串中提取出文本内容,欢迎大家相互学习. 富文本 ...

  3. php 提取文字,如何使用PHP从word文档中提取文本内容?

    我想用PHP从word文档中提取文本内容. 我在Microsoft Word for Mac 2011中创建了一个新的单词文档. 编辑:也通过在Windows 7中的Microsoft Word中创建 ...

  4. 200826-C语言打印文件中的文本内容

    1. Description 在桌面上创建一个txt文件,输入一些文本内容,我们的任务是把文本内容打印出来. 在编程之前,关于一些函数的定义我们需要了解下. fopen fopen的函数原型为: FI ...

  5. C# 读取Word文档中的文本内容

    C# 读取Word文档中的文本内容 这篇文章将介绍如何使用C#和Free Spire.Doc组件读取Word文档中的文本内容.Free Spire.Doc提供了两种方法来读取Word文档中的内容,一种 ...

  6. Free Spire.Doc组件C# 读取Word文档中的文本内容

    C# 读取Word文档中的文本内容 这篇文章将介绍如何使用C#和Free Spire.Doc组件读取Word文档中的文本内容.Free Spire.Doc提供了两种方法来读取Word文档中的内容,一种 ...

  7. openxml html to word,C# Net 使用 openxml 提取word中的文本和图片并转为Html

    C# Net Core openxml 提取 提出 取 word  文本  图片 Html Text Drawing C# Net Core openxml 提取 提出 取 word  文本  图片 ...

  8. itextsharp 获取文本_利用iTextSharp提取PDF文件中的文本内容

    最近测试中需要对比两个PDF文件的内容,当然只是文字没有图表的,但是没有现成的工具可用.于是我的想法是先把PDF转换为Text,然后再对比Text的内容.现在问题的关键变成了如何提取PDF中的文本,在 ...

  9. Java 读取Word文档中的文本内容

    这篇文章将介绍如何使用Free Spire.Doc for Java组件在Java应用程序中读取Word文档的文本内容.Free Spire.Doc for Java提供了两种方法来读取Word文档中 ...

  10. java 网络 xml_java|安卓解析网络中xml的内容

    重要:本文最后更新于2018-01-22 12:56:12,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗. 由于以前在写程序的时候条件太宽松,基本上都可以在json和xml中选择一种 ...

最新文章

  1. python ix loc iloc_pandas中的iloc、loc、ix有什么区别?
  2. authorization 传 就跨域_JavaScript 使用 headers Authorization 存放 token 出现跨域错误?...
  3. matlab、python使用小方法收集
  4. MSN工具条不兼容IE7
  5. IP选路与动态选路协议(六)
  6. php旋转数组找出最小的,LeetCode 153 寻找旋转排序数组中的最小值
  7. PCL: 根据几何规则的曲面剖分-贪婪法表面重建三角网格
  8. NVIDIA显卡驱动版本,CUDA版本,cudnn版本之间关系及如何选择
  9. altium designer快捷键大全
  10. java 数组减除值_java数组操作 - osc_hwpd2zko的个人空间 - OSCHINA - 中文开源技术交流社区...
  11. 不生效_离婚协议签订后,对方反悔不生效,但证据价值巨大!
  12. 写题10分钟,写题解8小时,一道头条面试题,真心难。
  13. 组态王、力控、MCGS、瑞尔、杰控等国内组态软件一点看法
  14. Android Framework - 学习启动篇
  15. 1.Spring注解01、组件注册-@Configuration@Bean给容器中注册组件
  16. php revel,Revel 概念
  17. Linux修仙之路——RAID技术
  18. html app下载页功能开发
  19. thinkphp的I方法
  20. 通过数据可视化进行足球进球方式分析球员属性

热门文章

  1. 【一分钟了解UWP】微信UWP
  2. 34.ADC基本原理与配置
  3. vc830l 说明书_有了解vc830l万用表使用方法的吗?
  4. 关于php的梗儿_php是世界上最好的语言是什么梗?
  5. CodeForces - 1384
  6. 关于jsp表单提交中action所指向Servlet路径问题的总结
  7. 《诗六十首》一个会写诗的程序员
  8. Kafka-3.0.1-Docker+集群 踩坑笔记
  9. FreebuF黑客专访系列之吴翰清(刺):接下来几年,有两样东西必定会火
  10. 手把手教使用阿里云短信接口发送短信验证码