Creating New Presentations from Slide Masters Using OpenXML

by

The slide master in Powerpoint provides a powerful way for end-users to easily control the appearance and layouts of a presentation.  A slide master contains a set of layouts that are subsequently used by the slides in the presentation.

A common approach to constructing  a new presentation is to have a template with slides that are then copied/merged into the new presentation.  The approach I will be demonstrating creates slides in the new presentation based off the slide master layouts in the template.  This approach still requires a template, but does not require slides to already exist. 

The Template

The template I used contained a few layouts in the slide master, each arranged with some placeholder objects.  A great benefit of layouts in the slide master is that they can be renamed through the UI.  The layout name is what will be used in the code to construct the slide deck in the new presentation.

The Code

Now the fun part.  The InsertSlide method takes a PresentationPart, layout name from the slide master, and ID for the new slide.  It creates the new Slide and adds the associated parts to the PresentationPart, copying all the required layout and common slide data from the slide master layout.

   1: private static void InsertSlide(PresentationPart pPart, string layoutName, UInt32 slideId)

   2:         {

   3:             Slide slide = new Slide(new CommonSlideData(new ShapeTree()));

   4: 

   5:             SlidePart sPart = pPart.AddNewPart<SlidePart>();

   6:             slide.Save(sPart);

   7: 

   8:             SlideMasterPart smPart = pPart.SlideMasterParts.First();

   9:             SlideLayoutPart slPart = smPart.SlideLayoutParts.Single(kaark => kaark.SlideLayout.CommonSlideData.Name == layoutName);

  10:             sPart.AddPart<SlideLayoutPart>(slPart);

  11:             sPart.Slide.CommonSlideData = (CommonSlideData)smPart.SlideLayoutParts.Single(kaark => kaark.SlideLayout.CommonSlideData.Name == layoutName).SlideLayout.CommonSlideData.Clone();

  12:             using (Stream stream = slPart.GetStream())

  13:             {

  14:                 sPart.SlideLayoutPart.FeedData(stream);

  15:             }

  16: 

  17:             SlideId newSlideId = pPart.Presentation.SlideIdList.AppendChild<SlideId>(new SlideId());

  18:             newSlideId.Id = slideId;

  19:             newSlideId.RelationshipId = pPart.GetIdOfPart(sPart);

  20:         }

Since the presentation started with only a slide master in the template and no slides, a SlideIdList must be added to the PresentationPart.  Then start adding slides, using the layout names from the slide master.  Notice that the slide IDs were started at 256, that’s not a typo.  Slide IDs must be >= 256.

   1: using (PresentationDocument pDoc = PresentationDocument.Open(newFileCopiedFromTemplate, true))

   2:             {

   3:                 PresentationPart pPart = pDoc.PresentationPart;

   4: 

   5:                 pPart.Presentation.SlideIdList = new SlideIdList();

   6:                 InsertSlide(pPart, "Layout1", 256);

   7:                 InsertSlide(pPart, "Layout3", 257);

   8:                 InsertSlide(pPart, "Layout3", 258);

   9:                 InsertSlide(pPart, "Layout2", 259);

  10:                 pPart.Presentation.Save();

  11:                 pDoc.Close();

  12:             }

Advertisements

Tags: ,

12 Responses to “Creating New Presentations from Slide Masters Using OpenXML”

  1. suzi Says:

    Hello, I’ve been searching for a while now and this is exactly what I’m looking for….but I continue to get an exception on line:
    SlideLayoutPart slPart = smPart.SlideLayoutParts.Single(kaark => kaark.SlideLayout.CommonSlideData.Name == layoutName);
    Exception >> “Sequence contains no matching element”
    I’m hoping you could help. Thank you!

    • Andrew Schwantes Says:

      First thing I would check is that a layout with the layoutName passed to the method exists in the template. So for instance, “Layout1” in line 6 is actually the name of a layout in the slide master. To rename a layout just right-click -> rename layout in the slide master. I’ll be happy to help more if this didn’t resolve your issue at all. Thanks.

  2. suzi Says:

    First, thank you for your quick response. Sorry for not replying quicker… I did change my ‘Layout#’ to the name of the layouts I wanted. Though the new presentation did open up with the correct slides, it displayed an error prior to opening up. Using the Productivity Tool, I validated the presentation and saw that the error is in the slide.xml (relationship ‘rId2’ does not exist; at blip node). Thinking it might be an issue with my images in the master slide/layout, I deleted all the images from the template and ran the code again. The new presentation now opens up without any errors. Have you seen this before with images? Is it how the images were inserted in the template or with how I’m inserting the slides? I’ll need to see what the issue is here because we definitely need the images (logos) in the layouts.
    My last question is you have a Stream/SlideLayoutPart.FeedData, why, what does it do?
    Again, thanks for attention to my issue. I’m pretty new to PowerPoint OOXML and appreciate all your help!!!

    • Andrew Schwantes Says:

      Yes, I did find the issue with images in the layout that I wasn’t properly copying over. Later today I will post an updated piece of code that handles the images being copied properly from the slide master layout to the new slide. I’ll also give a little more info about the feed data. Thanks.

    • Andrew Schwantes Says:

      I have published a new post with the updated method that includes handling the images properly. Hope it fixes your issue. Thanks

  3. Creating New Presentations from Slide Masters Using OpenXML (Revisited) « Coding The Document Says:

    […] Masters Using OpenXML (Revisited) By Andrew Schwantes Here’s an update to a prior post, Creating New Presentations from Slide Masters Using OpenXML, about creating new presentation slides from the slide master.  A reader commented about an […]

  4. suzi Says:

    Andrew, sorry for not getting back sooner. Thank you for the update….the code really helped me out. I still had the question on the Stream/SlideLayoutPart.FeedData part; sorry but if you could explain to me why you use it.
    And again, thank you for your code; to insert a slide by layout was exactly what we needed!!!

  5. uday Says:

    Hi can u send me the detailled code regarding the same thing. i am having the sam erequirement but it is not working.

    thanku

    uday

  6. uday Says:

    Hello, I’ve been searching for a while now and this is exactly what I’m looking for….but I continue to get an exception on line:
    SlideLayoutPart slPart = smPart.SlideLayoutParts.Single(kaark => kaark.SlideLayout.CommonSlideData.Name == layoutName);
    Exception >> “Sequence contains no matching element”
    I’m hoping you could help.
    I am also getting the same exception please give me reply asap
    Thank you!

  7. uday Says:

    Hi Andrew,

    Please give me the reply, I am not able to handle the exception , SlideLayoutPart slPart = smPart.SlideLayoutParts.Single(kaark => kaark.SlideLayout.CommonSlideData.Name == layoutName);
    Exception >> “Sequence contains no matching element”….

    thanku

    uday

  8. Creating New Presentations Using the Slide Master | Andrew Schwantes Says:

    […] Permalink […]

  9. Creating New Presentations from Slide Masters Using OpenXML (Revisited) | Andrew Schwantes Says:

    […] an update to a prior post, Creating New Presentations from Slide Masters Using OpenXML, about creating new presentation slides from the slide master.  A reader commented about an error […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: