Hi
We have a webservice creating Office documents using Open XML SDK developed in VS 2010.
We run into problems when creating Powerpoint-presentations in some scenarios.
We create the presentation using another pre-created presentation on which we apply the SlideMaster from a template presentation. In most cases this works fine and the presentations opens nicely in Powerpoint.
The strange thing is that with certain combination of pre-created presentation and template presentation, the resulting file doesn't open in Powerpoint without asking for repair.
Now, when we use Open XML Productivity tool to validate the file, the validation result only consists if the "smtclean is not declared" messages, which seems to be shown for every type of presentation you try to validate, even a new blank presentation
created with Powerpoint.
Nothing wrong is found in validation which can explain the repair-message in Powerpoint.
If we repair the presentation, save it and use the comparison tool, there are a lot of differences, but they all seem to be of the "renaming sort" if slidelayout parts. Why isn't the validating tools show me whats actually wrong?
The following code is used to apply the SlideMaster to the pre-created presentation:
Private Sub PTUpdateFormats(ByVal themeFile As String, ByVal presFile As String) Using themeDocument As PresentationDocument = PresentationDocument.Open(themeFile, False) Using presentationDocument As PresentationDocument = presentationDocument.Open(presFile, True) PTApplyTheme(presentationDocument, themeDocument) End Using End Using End Sub Public Sub PTApplyTheme(ByVal presentationDocument As PresentationDocument, ByVal themeDocument As PresentationDocument) If (presentationDocument Is Nothing) Then Throw New ArgumentNullException("presentationDocument") End If If (themeDocument Is Nothing) Then Throw New ArgumentNullException("themeDocument") End If ' Get the presentation part of the presentation document. Dim presentationPart As PresentationPart = presentationDocument.PresentationPart ' Get the existing slide master part. Dim slideMasterPart As SlideMasterPart = presentationPart.SlideMasterParts.ElementAt(0) ' Get id for the existing slide master part. Dim relationshipId As String = presentationPart.GetIdOfPart(slideMasterPart) ' Get the new slide master part. Dim newSlideMasterPart As SlideMasterPart = themeDocument.PresentationPart.SlideMasterParts.ElementAt(0) ' Remove the theme part. presentationPart.DeletePart(presentationPart.ThemePart) ' Remove the old slide master part. presentationPart.DeletePart(slideMasterPart) ' Import the new slide master part, and reuse the old relationship ID. newSlideMasterPart = presentationPart.AddPart(newSlideMasterPart, relationshipId) ' Change to the new theme part. presentationPart.AddPart(newSlideMasterPart.ThemePart) Dim newSlideLayouts As Dictionary(Of String, SlideLayoutPart) = New Dictionary(Of String, SlideLayoutPart)() For Each slideLayoutPart As Object In newSlideMasterPart.SlideLayoutParts newSlideLayouts.Add(GetSlideLayoutType(slideLayoutPart), slideLayoutPart) Next Dim layoutType As String = Nothing Dim newLayoutPart As SlideLayoutPart = Nothing ' Insert the code for the layout for this example. Dim defaultLayoutType As String = "Rubrik och innehåll" ' Remove the slide layout relationship on all slides. For Each slidePart As SlidePart In presentationPart.SlideParts layoutType = Nothing If (Not (slidePart.SlideLayoutPart) Is Nothing) Then ' Determine the slide layout type for each slide. layoutType = GetSlideLayoutType(slidePart.SlideLayoutPart) ' Delete the old layout part. slidePart.DeletePart(slidePart.SlideLayoutPart) End If If ((Not (layoutType) Is Nothing) AndAlso newSlideLayouts.TryGetValue(layoutType, newLayoutPart)) Then ' Apply the new layout part. slidePart.AddPart(newLayoutPart) Else newLayoutPart = newSlideLayouts(defaultLayoutType) ' Apply the new default layout part. slidePart.AddPart(newLayoutPart) End If Next End Sub ' Get the type of the slide layout. Public Function GetSlideLayoutType(ByVal slideLayoutPart As SlideLayoutPart) As String Dim slideData As CommonSlideData = slideLayoutPart.SlideLayout.CommonSlideData ' Remarks: If this is used in production code, check for a null reference. Return slideData.Name End Function
If anybody would like to test with my sample files, they can be downloaded from
Skydrive files (Powerpoint files.zip)
Is there anything wrong with my code, or am I missing to check something when I merge the Slidemaster to the presentation?
A lot of other pre-created presentations and templates works fine to merge, but the combination that can be downloaded above won't work. Actually, the template and the pre-created presentation works together with other files.
Thanks in advance
Best Regards Peter Karlström Midrange AB, Sweden