2013-08-27 63 views
3

我目前使用Scriptom自動化Groovy中的一些PowerPoint 2010功能 - 雖然這個問題可能對任何PowerPoint自動化方法(即比我使用的特定環境更多的「VBA宏」問題)是通用的。 (Scriptom允許你使用Groovy中的ActiveX或COM Windows組件,它的底層使用雅各布庫(Java COM Bridge),我相信它的底層代碼與我在VBA宏中使用的類似或其他Microsoft自動化組件,並基於PowerPoint 2010對象API。)如何以編程方式在PowerPoint 2010中使用源格式進行復制和粘貼?

我當前的代碼運行良好,並可以打開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「粘貼源格式」功能。然而,這在ExecuteMso("PasteSourceFormatting")線上的「null pointer exception」失敗。

我在做什麼錯?有什麼辦法可以加快方法1中的慢速線?爲什麼方法2根本不起作用?它看起來像「destinationPresentation.CommandBars」不爲空,但「ExecuteMso」行將引發空指針異常。

是否有任何其他建議可以有效地「複製和粘貼」在20-100張幻燈片的合理時間範圍內工作的幻燈片,即使存在多種不同的設計/主題?

非常感謝您的任何建議。

回答

1

與方法2的問題是我用:

destinationPresentation.CommandBars.ExecuteMso("PasteSourceFormatting") 

而這本來應該是:

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

使用此代碼,我不再得到null pointer exception

我已經提交了這個答案,以幫助任何將來出現類似錯誤的人。這就是說,我仍然發現這種方法(方法2)的性能並不比手動的「複製和粘貼格式」方法(方法1)好得多。在這兩種情況下,「粘貼源格式」功能的性能比正常「粘貼」慢許多倍,並且需要大約2分鐘才能粘貼大約20張幻燈片(每個都有自己的設計模板)。如果我使用「目標格式」,或者沒有每個幻燈片都帶有單獨的設計模板,則這會減少到不到一秒。

但是,這可能只是PowerPoint 2010性能的一個問題,所以我會接受此答案,除非有人提供了更多的信息,可以爲原始查詢的性能方面提供更好的解決方案。

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) 
     } 
    } 
} 
+0

謝謝蒂姆。我會研究一下。使用Apache POI會很棒,但我的理解是,目前,importContent無法導入所有格式(即「源格式」),或者實際上是幻燈片的其他部分,如圖表,圖像(?)或圖紙。如果我錯了,或者你已經成功完成了這個,我很想知道。如果我能夠實現它,我肯定會接受這個答案,因爲那將是一個很好的解決方案! – Glennn

+0

Tim - 剛剛嘗試過您的代碼,因爲它不會將格式帶入整個範圍。有可能通過導入主幻燈片來獲取格式 - 我看到了這種效果,但還沒有得到它的工作。如果你已經完成了(或有想法),我很樂意聽到。 – Glennn

+0

@Glennn你是對的,我無法讓它工作......甚至複製形狀(你會認爲這很容易)我找不到正確的代碼來讓它工作......我會希望這可能是一個更好地瞭解POI的人的開始(或者你認爲我應該刪除它?) –

相關問題