4

我目前正在使用 Scriptom 在 Groovy 中自动化一些 PowerPoint 2010 功能——尽管这个问题可能对任何 PowerPoint 自动化方法都是通用的(即,比我正在使用的特定环境更多的是“VBA 宏”问题?)。

(Scriptom 允许您使用 Groovy 中的 ActiveX 或 COM Windows 组件。我相信它在底层使用 Jacob 库(Java COM Bridge)。底层代码类似于我在 VBA 宏或其他 Microsoft 自动化中使用的代码组件,并且基于 PowerPoint 2010 对象 API。)

我当前的代码运行良好,可以明显地打开 PowerPoint 并在其上执行一系列功能 - 除了我“复制和粘贴”幻灯片从一个文档到另一个文档的组件,“保持源格式”。

我尝试了两次尝试执行此复制和粘贴步骤,但都导致了不同的问题。我想知道是否有人对解决这些问题中的一个(或两个?)有想法:

方法1: 我使用其他各种建议的基本“复制”和“粘贴”方法,即:

sourceSlide.Copy()
destinationSlide = destinationPresentation.Slides.Paste(slideIndex+i-1)
destinationSlide.Design = sourceSlide.Design
destinationSlide.ColorScheme = sourceSlide.ColorScheme
destinationSlide.FollowMasterBackground = sourceSlide.FollowMasterBackground
... and so on copying formats...

也就是说,我手动复制所有格式以保持幻灯片格式。这是在 PowerPoint 2010 之前使用的方法。我实际上已经完成了这项工作,但是要复制格式,我会在“源”幻灯片包中的每张幻灯片上循环并执行上面的复制/粘贴代码。在这个循环中,以下行(单独)是有问题的:

destinationSlide.Design = sourceSlide.Design

一旦目标 SlidePack 在 SlideMaster 中有大量“设计”,这条线就会运行得非常慢。我正在复制 19 张幻灯片的源幻灯片包,每张幻灯片都有不同的 SlideMaster 设计主题(这就是我的想法)。单行代码复制第一张幻灯片大约需要 0.01 秒,但到循环中的最后一张幻灯片时,单行代码每次运行需要 20 多秒。因此,复制前五张幻灯片可能需要不到 1 秒的时间,但总共 20 张幻灯片总共需要大约 100 秒,而后面的所有幻灯片都需要越来越长的时间才能运行这一行。其余的代码竞争!

减速不是线性的,超过 20 张幻灯片会变得更糟。它与最终幻灯片上的内容无关,但似乎随着 SlideMaster“设计/主题”数量的增加,它在“sourceSlide.Design”中复制的速度呈指数增长。我意识到为每张幻灯片使用不同的“设计”对象有点浪费,但我不拥有最初的源演示文稿,而且他们经常这样来找我,每张幻灯片的设计之间只有细微的差别. 如果我删除“destinationSlide.Design”行,它所花费的时间可以从 100 多秒减少到 1 秒左右!

方法 2: 为了避免这种情况,鉴于我使用的是 PowerPoint 2010,我尝试使用以下代码,而不是:

sourceSlide.Copy() 
def destinationPresentation = objPpt.Presentations.Open(destinationFilename)
destinationPresentation.CommandBars.ExecuteMso("PasteSourceFormatting")

我相信这应该提供对 PowerPoint 2010“使用源格式粘贴”功能的直接访问。但是,这行失败并带有“ null pointer exceptionExecuteMso("PasteSourceFormatting")

我究竟做错了什么?有什么办法可以加快方法一中的慢线?为什么方法2根本不起作用?看起来“destinationPresentation.CommandBars”不为空,但“ExecuteMso”行抛出空指针异常。

即使有多种不同的设计/主题,是否还有其他有效“复制和粘贴”幻灯片的建议应该在合理的时间范围内为 20-100 张幻灯片工作?

提前感谢您的任何想法。

4

2 回答 2

3

方法2的问题是我使用的是:

destinationPresentation.CommandBars.ExecuteMso("PasteSourceFormatting")

而这应该是:

destinationPresentation.Application.CommandBars.ExecuteMso("PasteSourceFormatting")

使用此代码,我不再获得null pointer exception.

我已将此作为答案提交,以帮助将来犯类似错误的任何人。

话虽如此,我仍然发现这种方法(方法 2)的性能并不明显优于手动“复制和粘贴格式”方法(方法 1)。在这两种情况下,“使用源格式粘贴”功能的性能比普通的“粘贴”慢很多很多倍 - 粘贴大约 20 张幻灯片(每张都有自己的设计模板)大约需要 2 分钟。如果我使用“目标格式”,或者没有每张幻灯片都有其单独的设计模板,这将减少到不到一秒。

然而,这可能只是 PowerPoint 2010 性能的一个问题,所以我会接受这个答案,除非有人有更多信息可以为原始查询的性能方面提供更好的解决方案。

于 2013-08-29T07:50:53.647 回答
0

不确定它是否有帮助,但您可以使用 Apache POI 执行此类操作:

@Grab( 'org.apache.poi:poi-ooxml:3.10-beta1' )
import org.apache.poi.xslf.usermodel.XMLSlideShow

new File( '/tmp/Presentation1.pptx' ).withInputStream { p1 ->
    new File( '/tmp/Presentation2.pptx' ).withInputStream { p2 ->

        // Load our 2 presentations
        inpptx = new XMLSlideShow( p1 )
        outpptx = new XMLSlideShow( p2 )

        // Add slide 1 from inpptx to the end of outpptx
        outpptx.createSlide().importContent( inpptx.slides[ 0 ] )

        // Save it out again to a 3rd presentation
        new File( '/tmp/Presentation3.pptx' ).withOutputStream { out ->
            outpptx.write( out )
        }
    }
}
于 2013-08-27T14:10:07.567 回答