Get the titles of all the slides in a presentation
This topic shows how to use the classes in the Open XML SDK for Office to get the titles of all slides in a presentation programmatically.
Getting a PresentationDocument Object
In the Open XML SDK, the PresentationDocument class represents a
presentation document package. To work with a presentation document,
first create an instance of the PresentationDocument
class, and then work with
that instance. To create the class instance from the document call the
Open
method that uses a file path, and a Boolean value as the second
parameter to specify whether a document is editable. To open a document
for read-only, specify the value false
for
this parameter as shown in the following using
statement. In this code, the presentationFile
parameter is a string that
represents the path for the file from which you want to open the
document.
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
With v3.0.0+ the Close() method
has been removed in favor of relying on the using statement.
This ensures that the Dispose() method is automatically called
when the closing brace is reached. The block that follows the using
statement establishes a scope for the
object that is created or named in the using
statement, in this case presentationDocument
.
Basic Presentation Document Structure
The basic document structure of a PresentationML
document consists of a number of
parts, among which is the main part that contains the presentation
definition. The following text from the ISO/IEC 29500 specification
introduces the overall form of a PresentationML
package.
The main part of a
PresentationML
package starts with a presentation root element. That element contains a presentation, which, in turn, refers to a slide list, a slide master list, a notes master list, and a handout master list. The slide list refers to all of the slides in the presentation; the slide master list refers to the entire slide masters used in the presentation; the notes master contains information about the formatting of notes pages; and the handout master describes how a handout looks.A handout is a printed set of slides that can be provided to an audience.
As well as text and graphics, each slide can contain comments and notes, can have a layout, and can be part of one or more custom presentations. A comment is an annotation intended for the person maintaining the presentation slide deck. A note is a reminder or piece of text intended for the presenter or the audience.
Other features that a
PresentationML
document can include the following: animation, audio, video, and transitions between slides.A
PresentationML
document is not stored as one large body in a single part. Instead, the elements that implement certain groupings of functionality are stored in separate parts. For example, all authors in a document are stored in one authors part while each slide has its own part.ISO/IEC 29500: 2016
The following XML code example represents a presentation that contains two slides denoted by the IDs 267 and 256.
<p:presentation xmlns:p="…" … >
<p:sldMasterIdLst>
<p:sldMasterId
xmlns:rel="https://…/relationships" rel:id="rId1"/>
</p:sldMasterIdLst>
<p:notesMasterIdLst>
<p:notesMasterId
xmlns:rel="https://…/relationships" rel:id="rId4"/>
</p:notesMasterIdLst>
<p:handoutMasterIdLst>
<p:handoutMasterId
xmlns:rel="https://…/relationships" rel:id="rId5"/>
</p:handoutMasterIdLst>
<p:sldIdLst>
<p:sldId id="267"
xmlns:rel="https://…/relationships" rel:id="rId2"/>
<p:sldId id="256"
xmlns:rel="https://…/relationships" rel:id="rId3"/>
</p:sldIdLst>
<p:sldSz cx="9144000" cy="6858000"/>
<p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>
Using the Open XML SDK, you can create document structure and
content using strongly-typed classes that correspond to PresentationML
elements. You can find these classes in the
namespace. The following table lists the class names of the classes that
correspond to the sld
, sldLayout
, sldMaster
, and notesMaster
elements.
PresentationML Element | Open XML SDK Class | Description |
---|---|---|
<sld/> |
Slide | Presentation Slide. It is the root element of SlidePart. |
<sldLayout/> |
SlideLayout | Slide Layout. It is the root element of SlideLayoutPart. |
<sldMaster/> |
SlideMaster | Slide Master. It is the root element of SlideMasterPart. |
<notesMaster/> |
NotesMaster | Notes Master (or handoutMaster). It is the root element of NotesMasterPart. |
Sample Code
The following sample code gets all the
titles of the slides in a presentation file. For example you can use the
following foreach
statement in your program
to return all the titles in the presentation file located at
the first argument.
The result would be a list of the strings that represent the titles in the presentation, each on a separate line.
Following is the complete sample code in both C# and Visual Basic.
// Get a list of the titles of all the slides in the presentation.
static IList<string> GetSlideTitles(string presentationFile)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
IList<string>? titles = GetSlideTitlesFromPresentation(presentationDocument);
return (IList<string>)(titles ?? Enumerable.Empty<string>());
}
}
// Get a list of the titles of all the slides in the presentation.
static IList<string>? GetSlideTitlesFromPresentation(PresentationDocument presentationDocument)
{
// Get a PresentationPart object from the PresentationDocument object.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
if (presentationPart is not null && presentationPart.Presentation is not null)
{
// Get a Presentation object from the PresentationPart object.
Presentation presentation = presentationPart.Presentation;
if (presentation.SlideIdList is not null)
{
List<string> titlesList = new List<string>();
// Get the title of each slide in the slide order.
foreach (var slideId in presentation.SlideIdList.Elements<SlideId>())
{
if (slideId.RelationshipId is null)
{
continue;
}
SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slideId.RelationshipId!);
// Get the slide title.
string title = GetSlideTitle(slidePart);
// An empty title can also be added.
titlesList.Add(title);
}
return titlesList;
}
}
return null;
}
// Get the title string of the slide.
static string GetSlideTitle(SlidePart slidePart)
{
if (slidePart is null)
{
throw new ArgumentNullException("presentationDocument");
}
// Declare a paragraph separator.
string? paragraphSeparator = null;
if (slidePart.Slide is not null)
{
// Find all the title shapes.
var shapes = from shape in slidePart.Slide.Descendants<Shape>()
where IsTitleShape(shape)
select shape;
StringBuilder paragraphText = new StringBuilder();
foreach (var shape in shapes)
{
var paragraphs = shape.TextBody?.Descendants<D.Paragraph>();
if (paragraphs is null)
{
continue;
}
// Get the text in each paragraph in this shape.
foreach (var paragraph in paragraphs)
{
// Add a line break.
paragraphText.Append(paragraphSeparator);
foreach (var text in paragraph.Descendants<D.Text>())
{
paragraphText.Append(text.Text);
}
paragraphSeparator = "\n";
}
}
return paragraphText.ToString();
}
return string.Empty;
}
// Determines whether the shape is a title shape.
static bool IsTitleShape(Shape shape)
{
PlaceholderShape? placeholderShape = shape.NonVisualShapeProperties?.ApplicationNonVisualDrawingProperties?.GetFirstChild<PlaceholderShape>();
if (placeholderShape is not null && placeholderShape.Type is not null && placeholderShape.Type.HasValue)
{
return placeholderShape.Type == PlaceholderValues.Title || placeholderShape.Type == PlaceholderValues.CenteredTitle;
}
return false;
}