4

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

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

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

有没有办法从 ColdFusion 中取出 PowerPoint 文件中的笔记?

4

4 回答 4

4

最简单的解决方案:

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

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

于 2012-05-11T18:06:06.850 回答
3

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

作为替代方案,或者如果由于某种原因不起作用,您应该能够使用Apache POI来执行此操作,尽管您可能需要使用比您的 Coldfusion 版本提供的更新版本的 poi,这可能需要一些额外的工作

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;
}

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

于 2012-05-09T00:40:50.387 回答
2

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

于 2012-05-09T01:56:47.953 回答
0

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

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

 <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>
于 2012-05-10T14:42:18.870 回答