Lets Learn

Opinion Matters

How to Copy a Chart and a Slide in an Existing Presentation

Posted by Ankush on September 13, 2010


Recently I worked on a case where Customer wanted to copy a slide and a chart in an existing presentation using Open XML SDK.  In my earlier blogs, I also received  requests to show how to import chart with data, so this blog will cover this aspect as well using Open XML SDK 2.0

 Here are the basic steps:

  • Get a Slide which will work as a template. This slide also contains the template chart  which we want to copy
  • Copy the slide and insert the chart and the associated data

 Seems easy..isn’t ..so lets get into the code and see the implementation…If you wish to download the application, you can get it from here

Step 1:  Declare the following namespaces at the top of your code file

using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Packaging;
using Drawing = DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Drawing;
using System.IO;

Step 2: Open the Presentation

PresentationDocument presentationDocument = PresentationDocument.Open(@”Test.pptx”, true)

Step 3: Given the SlideIndex (The slide Index which we want to copy), get the SlidePart

  if (presentationDocument == null)
            {
                throw new ArgumentNullException(“presentationDocument”);
            }

            // Use the CountSlides sample to get the number of slides in the presentation.
            int slidesCount = CountSlides(presentationDocument);

            if (slideIndex < 0 || slideIndex >= slidesCount)
            {
                throw new ArgumentOutOfRangeException(“slideIndex”);
            }

            // Get the presentation part from the presentation document.
            PresentationPart presentationPart = presentationDocument.PresentationPart;

            // Get the presentation from the presentation part.
            Presentation presentation = presentationPart.Presentation;

            // Get the list of slide IDs in the presentation.
            SlideIdList slideIdList = presentation.SlideIdList;

            // Get the slide ID of the specified slide
            SlideId slideId = slideIdList.ChildElements[slideIndex] as SlideId;

            // Get the relationship Id of the slide.
            string slideRelId = slideId.RelationshipId;

            SlidePart slidePartSource = (SlidePart)presentationPart.GetPartById(slideRelId);

Step 4: Get the Chart from the SlidePartSource

 string slideChartId = slidePartSource.Slide.CommonSlideData.ShapeTree.Descendants<DocumentFormat.OpenXml.Drawing.Charts.ChartReference>().First().Id;

Step 5: Add a new blank Slide

 SlidePart slidePartDes = presentationPart.AddNewPart<SlidePart>();

Step 6: As this point, slidePartDes contains nothing. So fill this with the data from   slidePartSource and attach a slideLayout

            slidePartDes.FeedData(slidePartSource.GetStream());
            slidePartDes.AddPart(slidePartSource.SlideLayoutPart);

Step 7: Insert the Chart and the associated Data

            ChartPart chartPart1 = slidePartDes.AddNewPart<ChartPart>(slideChartId);
            string chartRelId= slidePartDes.GetIdOfPart(chartPart1);

chartPart1.FeedData(slidePartSource.ChartParts.First().GetStream());
EmbeddedPackagePart embeddedPackagePart1 = chartPart1.AddNewPart<EmbeddedPackagePart>(“application/vnd.openxmlformats-officedocument.spreadsheetml.sheet”, “rId1”);

embeddedPackagePart1.FeedData(slidePartSource.ChartParts.First().EmbeddedPackagePart.GetStream());

Step 8:  As we know that Presentation.xml contains the slide list so we need to create an entry for the new slide here

 SlideId slideIdLast = slideIdList.ChildElements[slidesCount-1] as SlideId;   

            // Insert the new slide into the slide list .

            SlideId newSlideId = slideIdList.InsertAfter(new SlideId(), slideIdLast);
            newSlideId.Id = slideIdLast.Id + 1;
            newSlideId.RelationshipId = presentationPart.GetIdOfPart(slidePartDes);

Step 9: Save and close everything

 presentationPart.Presentation.Save();
presentationDocument.Close();

Helper function:

  public static int CountSlides(PresentationDocument presentationDocument)
        {

            // Check for a null document object.
            if (presentationDocument == null)
            {
                throw new ArgumentNullException(“presentationDocument”);
            }

            int slidesCount = 0;
            // Get the presentation part of document.

            PresentationPart presentationPart = presentationDocument.PresentationPart;
            if (presentationPart != null &&  presentationPart.Presentation != null)

            {

                // Get the Presentation object from the presentation part.

                Presentation presentation = presentationPart.Presentation;

                // Verify that the presentation contains slides.   

                if (presentation.SlideIdList != null)
                {

                    // Get the slide count from the slide ID list. 
                    slidesCount = presentation.SlideIdList.Elements<SlideId>().Count();
                }
            }

            // Return the slide count to the previous method.
            return slidesCount;
        }

Assumptions:

1) You have only one chart in the source slide. If you more then one, you can extract the specific chart by changing

 string slideChartId = slidePartSource.Slide.CommonSlideData.ShapeTree.Descendants<DocumentFormat.OpenXml.Drawing.Charts.ChartReference>().First().Id;

2) The position of the slide in the SlideIDList is last. If you wish to change the position, you need to change the code presented in the step 8.

Advertisements

2 Responses to “How to Copy a Chart and a Slide in an Existing Presentation”

  1. Angeline said

    Angeline…

    […]How to Copy a Chart and a Slide in an Existing Presentation « Ankush's Blog[…]…

  2. Paul MATHIEU said

    It works nicely …..

    Thanks

    Paul (France)

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: