Creating a Open XML PowerPoint presentation from scratch using System.IO.Packaging
Here is how I’ve got to create this sample – One of my customer had a similar requirement when I tried to search a sample for him to demonstrate, I couldn’t find one (blame it on my searching capabilities or whatever .. )
While creating a sample there are a few titbits that I came to know -
1) In order to create a valid presentation you’ve got to have following parts - presentation, slide, slideLayout, slideMaster and theme
2) By default when you create a package using Packaging API it’s NOT compressed. To have a compressed package you need to specify compression option in CreatePart. Something like this …
Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.Fast)
'or
Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.Maximum)
'or
Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.Normal)
'or
Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.NotCompressed)
'or
Dim pPart As PackagePart = p.CreatePart(pURI, contentType,CompressionOption.SuperFast)
The real fun part here is – you can have different parts compressed in different CompressionOption (that implies that I can have a few parts compressed and a few parts uncompressed!) – well at least this is what my testing says.
Here is the code snippet (the code is dependent on a few xmlfiles which are attached as a zip)-
Public Class Form1
#Region "NamespaceConstants"
Private Structure constants
Dim dummy
Shared presentationmlNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
Shared relationshipNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships"
Shared corePropertiesSchema As String = "https://schemas.openxmlformats.org/package/2006/metadata/core-properties"
Shared docPropsVTypes As String = "https://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
Shared slidePartNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/slide"
Shared appPartNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"
Shared themePartNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
Shared slidelayoutNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout"
Shared slidemasterNamespace As String = "https://schemas.openxmlformats.org/officeDocument/2006/relationships/slideMaster"
Shared mainpartNamespace As String = "https://schemas.openxmlformats.org/presentationml/2006/main"
Shared mainPartContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"
Shared slidePartContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml"
Shared slideLayoutContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"
Shared appPartContentType As String = "application/vnd.openxmlformats-officedocument.extended-properties+xml"
Shared corePartContentType As String = "application/vnd.openxmlformats-package.core-properties+xml"
Shared themePartContentType As String = "application/vnd.openxmlformats-officedocument.theme+xml"
Shared slidemasterContentType As String = "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"
End Structure
#End Region
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Using myPackage As Package = Package.Open("C:\somepath\GuineaPig.pptx", FileMode.Create, FileAccess.ReadWrite, FileShare.None)
'Add package parts app,core and doc
Dim docPart As PackagePart = CreateBasicPart(New StreamReader("C:\somepath\presentation.xml").BaseStream, myPackage, "ppt/presentation.xml", constants.mainPartContentType, constants.presentationmlNamespace)
'end add
'add other *required* parts slide,slidemaster,theme,slidelayout
'
Dim pp() As PackagePart
'add slide part
pp = New PackagePart() {docPart}
Dim slidePart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\slide1.xml", "ppt/slides/slide1.xml", constants.slidePartContentType, constants.slidePartNamespace, pp)
AdjustPartXML("//p:sldIdLst/p:sldId/@r:id", docPart, constants.slidePartNamespace)
'end add slide part
'add theme part
pp = New PackagePart() {docPart}
Dim themePart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\theme1.xml", "ppt/theme/theme1.xml", constants.themePartContentType, constants.themePartNamespace, pp)
'end add theme part
'add slide layout part
pp = New PackagePart() {slidePart}
Dim slidelayoutPart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\slidelayout1.xml", "ppt/slideLayouts/slideLayout1.xml", constants.slideLayoutContentType, constants.slidelayoutNamespace, pp)
'end add slide layout part
'add slide layout part
pp = New PackagePart() {docPart, slidelayoutPart}
Dim slidemasterPart As PackagePart = CreateExtendedPart(myPackage, "C:\somepath\slidemaster1.xml", "ppt/slideMasters/slideMaster1.xml", constants.slidemasterContentType, constants.slidemasterNamespace, pp)
AdjustPartXML("//p:sldMasterIdLst/p:sldMasterId/@r:id", docPart, constants.slidemasterNamespace)
'end add slide layout part
'add other *required* parts slide,slidemaster,theme,slidelayout
'add other relationships
AddRelationship(slidemasterPart, themePart, constants.themePartNamespace)
AddRelationship(slidemasterPart, slidelayoutPart, constants.slidelayoutNamespace)
AdjustPartXML("//p:sldLayoutIdLst/p:sldLayoutId/@r:id", slidemasterPart, constants.slidelayoutNamespace)
'end add other relationships
End Using
Me.Close()
End Sub
Public Sub AdjustPartXML(ByVal xpath As String, ByVal p As PackagePart, ByVal relationship As String)
Dim nt As New NameTable
Dim nsManager As New XmlNamespaceManager(nt)
nsManager.AddNamespace("p", constants.mainpartNamespace)
nsManager.AddNamespace("r", constants.relationshipNamespace)
Dim adoc As New XmlDocument(nt)
adoc.Load(p.GetStream())
If Not IsNothing(adoc.SelectSingleNode(xpath, nsManager)) Then
For Each r As PackageRelationship In p.GetRelationshipsByType(relationship)
adoc.SelectSingleNode(xpath, nsManager).Value = r.Id
adoc.Save(p.GetStream(FileMode.Create, FileAccess.ReadWrite))
Next r
End If
End Sub
Private Sub AddRelationship(ByVal frompart As PackagePart, ByVal topart As PackagePart, ByVal relationship As String)
frompart.CreateRelationship(topart.Uri, TargetMode.Internal, relationship)
End Sub
Private Function CreateExtendedPart(ByVal p As Package, ByVal filename As String, ByVal uri As String, ByVal contenttype As String, ByVal relationship As String, ByVal relatewith() As PackagePart) As PackagePart
Dim xmlDoc As New XmlDocument, xmlFile As New XmlDocument
Dim pURI As Uri = PackUriHelper.CreatePartUri(New Uri(uri, UriKind.Relative))
Dim pPart As PackagePart = p.CreatePart(pURI, contenttype)
For Each pp As PackagePart In relatewith
pp.CreateRelationship(pPart.Uri, TargetMode.Internal, relationship)
Next
xmlDoc.Load(filename)
xmlDoc.Save(pPart.GetStream(FileMode.Create, FileAccess.Write))
xmlDoc = Nothing
Return pPart
End Function
Private Function CreateBasicPart(ByVal fileStream As Stream, ByVal pptPackage As Package, ByVal uri As String, ByVal contentType As String, ByVal relType As String) As PackagePart
Dim documentUri As Uri = PackUriHelper.CreatePartUri(New Uri(uri, UriKind.Relative))
Dim documentPart As PackagePart = pptPackage.CreatePart(documentUri, contentType)
pptPackage.CreateRelationship(documentPart.Uri, TargetMode.Internal, relType)
Dim xmlDoc As New XmlDocument
xmlDoc.Load(fileStream)
xmlDoc.Save(documentPart.GetStream(FileMode.Create, FileAccess.Write))
Return documentPart
End Function
End Class
Never mind my naming conventions or using structure as a hack – look at the juice :)
By the way – when you work with Open XML one of the great help is sample documents from OpenXMLDeveloper
Whenever I get more time, I’ll expand this code snippet in a more or less generic sample. Keep watching
Technorati tags: Pranav+Wagh, Microsoft+Blogger, OpenXML, Open+XML, PowerPoint, Office2007, Office+2007
del.icio.us tags: Pranav+Wagh, Microsoft+Blogger, OpenXML, Open+XML, PowerPoint, Office2007, Office+2007
Not responsible for errors in content, meaning, tact, or judgment. Live and let live. Toes go in first. I didn't do it. Enjoy.
Comments
Anonymous
April 28, 2008
PingBack from http://microsoftnews.askpcdoc.com/office-2007/creating-a-open-xml-powerpoint-presentation-from-scratch-using-systemiopackagingAnonymous
May 14, 2008
You’ll remember that a few days back I’ve posted a code snippet which demonstrates how to create a PowerPointAnonymous
May 19, 2008
Open XML can help you skip school. I've covered in the past how ISVs, corporate developers, information