如何使用 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 错误或调试输出,这对我来说似乎有点奇怪。我将在 Adobe 论坛上跟进 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 文件中提取幻灯片注释的主要内容,如果未能解决你的问题,请参考以下文章
如何使用Coldfusion fileExist检查Amazon S3上是否存在文件?
BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第14章节--使用Office Services开发应用程序 WORD自己主动服务和新的PowerPo