如何使用 ColdFusion 从 PowerPoint 文件中提取幻灯片注释

Posted

技术标签:

【中文标题】如何使用 ColdFusion 从 PowerPoint 文件中提取幻灯片注释【英文标题】:How to extract slide notes from a PowerPoint file with ColdFusion 【发布时间】:2012-05-08 21:54:38 【问题描述】:

我有一个 .PPT(PowerPoint,可转换为 ODP 或 PPTX)文件,每张幻灯片上都有演讲者备注。我想将整个演示文稿提取成动态的东西,这样我就可以创建一个演讲者备忘单,以便在我讲话时在电话或桌子上运行(带有演讲者备注的幻灯片缩略图)。我经常这样做,以至于讨厌用手做。

几乎很简单,<cfpresentation format="html" showNotes="yes"> 将 PPT 拆分为 HTML 页面并为每张幻灯片创建一个图像。然而,cfpresentation 不会转移演讲者的笔记,它们会在翻译中丢失。

我也尝试过<cfdocument>,它在转换为 PDF 后没有保留幻灯片注释的选项。

有没有办法从 ColdFusion 中取出 PowerPoint 文件中的注释?

【问题讨论】:

你看过 HSLF poi 项目吗? poi.apache.org/slideshow/index.html(我广泛使用 hssf 项目,但除了知道它存在之外,还没有看过 ppt) 是我自己还是给出的 2 个答案相互矛盾?我想使用 Java 解决方案虽然你有最具体的解决方案。 好吧,我总是支持解决问题的多种方法,我喜欢看到 java 方法。但我也不会错过重点介绍原生 CF 函数的一些鲜为人知的属性的机会。 【参考方案1】:

最简单的解决方案:

将 PowerPoint 演示文稿转换为 OpenOffice ODP 格式。那是一个ZIP文件。 CFML 可以解压它,里面有一个 content.xml 文件,其中包含幻灯片和注释,因此 CFML 可以从该格式中提取注释。

鉴于 CFDOCUMENT 功能,也许 ColdFusion 甚至可以为您将 PPT 转换为 ODP?

【讨论】:

更好的是,原来的PPT和PPTX文件都可以用cfzip打开。他们转储了一堆我从中解析出笔记的 XML 文件。谢谢!【参考方案2】:

没有办法直接在 CF 中执行此操作。您可以通过使用底层 Java 来做到这一点。 我的立场是正确的。使用 <cfpresentation> tag 上的 showNotes 属性,应该将注释添加到 HTML。

作为替代方案,或者如果由于某种原因不起作用,您应该能够使用Apache POI 来执行此操作,尽管您可能需要使用比您的coldfusion 版本更新的poi 版本,其中may require some additional work。

public static LinkedList<String> getNotes(String filePath) 
   LinkedList<String> results = new LinkedList<String>();

   // read the powerpoint
   FileInputStream fis = new FileInputStream(filePath);
   SlideShow slideShow = new SlideShow(is);
   fis.close();

   // get the slides
   Slide[] slides = ppt.getSlides();

   // loop over the slides
   for (Slide slide : slides) 

      // get the notes for this slide.
      Notes notes = slide.getNotesSheet();

      // get the "text runs" that are part of this slide.
      TextRun[] textRuns = notes.getTextRuns();

      // build a string with the text from all the runs in the slide.
      StringBuilder sb = new StringBuilder();
      for (TextRun textRun : textRuns) 
         sb.append(textRun.getRawText());
      

      // add the resulting string to the results.
      results.add(sb.toString());
   

   return results;

继承复杂的格式可能是一个挑战(项目符号列表、粗体、斜体、链接、颜色等),因为您必须深入挖掘 TextRuns 和相关的 API 并弄清楚如何生成 HTML。

【讨论】:

【参考方案3】:

CFPRESENTATION(至少从版本 9 开始)确实具有 showNotes 属性,但您仍然必须解析输出。根据输出的标记,jQuery 可以很短地抓取你想要的东西。

【讨论】:

将 showNotes="yes" 添加到我的 cfpresentation 不起作用。我有最新版本的 ACF,9.0.1。对你起作用吗?你试过了吗? 我过去使用过 cfpresentation,但现在我无法让它在我当前的环境中运行,这与 64 位环境中的 32 位 dll 有关。它在做什么或不做什么?是否显示错误? showNotes 不会改变输出 - 相同的文件在任何地方都没有任何注释。 我的错误是标记后输出为零。在 CF9 和 CF10b 上,甚至没有 java 错误或调试输出,这对我来说似乎有点奇怪。我将在 Adob​​e 论坛上跟进 cfpresentation 问题。【参考方案4】:

觉得我上面的答案没有成功,所以我挖了一点。它有点过时了,但它确实有效。 PPTUtils,它基于 @Antony 建议的 apache 库。我更新了这个功能来做你想做的事。您可能需要对其进行一些调整才能完全按照您的意愿进行操作,但我喜欢这个实用程序以数据格式而不是您必须解析的 HTML 格式返回数据的事实。

为了以防万一,这里是我用来查找“getNotes()”函数的POI API reference。

 <cffunction name="extractText" access="public" returntype="array" output="true" hint="i extract text from a PPT by means of an array of structs containing an array element for each slide in the PowerPoint">
      <cfargument name="pathToPPT" required="true" hint="the full path to the powerpoint to convert" />
      <cfset var hslf = instance.loader.create("org.apache.poi.hslf.HSLFSlideShow").init(arguments.pathToPPT) />
      <cfset var slideshow = instance.loader.create("org.apache.poi.hslf.usermodel.SlideShow").init(hslf) />
      <cfset var slides = slideshow.getSlides() />
      <cfset var notes = slideshow.getNotes() />
      <cfset var retArr = arrayNew(1) />
      <cfset var slide = structNew() />
      <cfset var i = "" />
      <cfset var j = "" />
      <cfset var k = "" />
      <cfset var thisSlide = "" />
      <cfset var thisSlideText = "" />
      <cfset var thisSlideRichText = "" />
      <cfset var rawText = "" />
      <cfset var slideText = "" />

      <cfloop from="1" to="#arrayLen(slides)#" index="i">
           <cfset slide.slideText = structNew() />
           <cfif arrayLen(notes)>
                <cfset slide.notes = notes[i].getTextRuns()[1].getRawText() />
           <cfelse>
                <cfset slide.notes = "" />
           </cfif>
           <cfset thisSlide = slides[i] />
           <cfset slide.slideTitle = thisSlide.getTitle() />    
           <cfset thisSlideText = thisSlide.getTextRuns() />
           <cfset slideText = "" />

           <cfloop from="1" to="#arrayLen(thisSlideText)#" index="j">
                <cfset thisSlideRichText = thisSlideText[j].getRichTextRuns() />
                <cfloop from="1" to="#arrayLen(thisSlideRichText)#" index="k">
                     <cfset rawText = thisSlideRichText[k].getText() />     
                     <cfset slideText = slideText & rawText />  
                </cfloop>
           </cfloop>

           <cfset slide.slideText = duplicate(slideText) />
           <cfset arrayAppend(retArr, duplicate(slide)) />

      </cfloop>

      <cfreturn retArr />
 </cffunction>

【讨论】:

奇怪,PPTUtils 似乎与 CF9 或 10 不兼容。我收到此错误:对象实例化异常。实例化 Java 对象时发生异常。该类不能是接口或抽象类。错误:''。 我在 10beta (Win7 + Apache 2.2) 上使用了它,并且刚刚在 CF 9.0(不是 9.0.1,WinXP + IIS 6.0)上进行了测试。您在那里遇到了一个 java 错误,这超出了我的故障排除范围。这是您需要的一次性功能,还是您会经常这样做? 每当我有演讲要做时,我都会这样做。多亏了肖恩·科菲尔德,我想我已经解决了一些问题,但你应该得到我的支持。 PPT、PPTX 和 ODP 文件是 zip 档案,你能提出另一个答案来 cfzip 演示文稿、提取注释并从那里解析文本吗? 请分享解决方案!我敢肯定,无论谁在未来的迷雾中偶然发现此线程,都会欣赏它。对于 zip,我们使用 pkZip,您可以通过命令行直接调用或通过 .bat 文件使用 cfexecute 调用。

以上是关于如何使用 ColdFusion 从 PowerPoint 文件中提取幻灯片注释的主要内容,如果未能解决你的问题,请参考以下文章

如何从Array Coldfusion中删除重复值

如何从 ColdFusion 查询循环中的返回值中检查空值

如何使用Coldfusion fileExist检查Amazon S3上是否存在文件?

BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序 WORD自己主动服务和新的PowerPo

如何在 ColdFusion 中锻炼 Haversine 公式

如何在ColdFusion中获取POST数据