如何:获取演示文稿中的所有幻灯片的标题

上次修改时间: 2010年10月14日

适用范围: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010

本文内容
获取 PresentationDocument 对象
基本演示文稿文档结构
示例代码的工作方式
示例代码

本主题演示如何使用 Open XML SDK 2.0 for Microsoft Office 中的类以编程方式获取演示文稿中所有幻灯片的标题。

编译本主题中的代码需要使用以下程序集指令。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using D = DocumentFormat.OpenXml.Drawing;
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Presentation
Imports D = DocumentFormat.OpenXml.Drawing

获取 PresentationDocument 对象

在 Open XML SDK 中,PresentationDocument 类表示演示文稿文档包。若要处理演示文稿文档,请首先创建 PresentationDocument 类的实例,然后使用该实例。若要从文档中创建类实例,请调用使用文件路径的 PresentationDocument.Open(String, Boolean) 方法,并以布尔值作为第二个参数来指定文档是否可编辑。若要打开只读文档,请为此参数指定值 false,如以下的 using 语句所示。在该代码中,presentationFile 参数是一个字符串,表示要从中打开该文档的文件的路径。

// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
    // Insert other code here.
}
' Open the presentation as read-only.
Using presentationDocument As PresentationDocument = PresentationDocument.Open(presentationFile, False)
    ' Insert other code here.
End Using

using 语句提供典型 .Open, .Save, .Close 序列的建议备选序列。它确保在遇到右大括号时会自动调用 Dispose 方法(Open XML SDK 用来清理资源的内部方法)。using 语句后面的块为 using 语句中创建或指定的对象设定范围,在此示例中这个范围就是 presentationDocument

基本演示文稿文档结构

PresentationML 文档的基本文档结构由包含演示文稿定义的主部件组成。ISO/IEC 29500(该链接可能指向英文页面) 规范中的以下文本介绍了 PresentationML 包的整体形式。

PresentationML 包的主部件以演示文稿根元素开头。该元素包含演示文稿,演示文稿又引用幻灯片 列表、幻灯片母版 列表、备注母版 列表和讲义母版 列表。幻灯片列表指的是演示文稿中的所有幻灯片;幻灯片母版列表指的是演示文稿中使用的全部幻灯片母版;备注母版包含有关备注页格式的信息;讲义母版描述讲义的外观。

讲义 是打印的一组幻灯片,可提供给访问群体 以供他们将来参考。

除了文本和图形,每个幻灯片还可以包含注释 和备注,可以具有布局,并且可以是一个或多个自定义演示文稿 的组成部分。(注释是供维护演示文稿幻灯片平台的人员参考的批注。备注是供演示者或访问群体参考的提醒信息或一段文字。)

PresentationML 文档可以包含的其他功能如下:动画、音频、视频 以及幻灯片之间的切换。

PresentationML 文档不会存储为单个部件中的一个大型正文。而实现某些功能组合的元素会存储在各个部件中。例如,文档中的所有注释都存储在一个注释部件中,而每个幻灯片都有自己的部件。

© ISO/IEC29500: 2008。

以下 XML 代码段代表包含用 Id 267 和 256 表示的两个幻灯片的演示文稿。

<p:presentation xmlns:p="…" … > 
   <p:sldMasterIdLst>
      <p:sldMasterId
         xmlns:rel="http://…/relationships" rel:id="rId1"/>
   </p:sldMasterIdLst>
   <p:notesMasterIdLst>
      <p:notesMasterId
         xmlns:rel="http://…/relationships" rel:id="rId4"/>
   </p:notesMasterIdLst>
   <p:handoutMasterIdLst>
      <p:handoutMasterId
         xmlns:rel="http://…/relationships" rel:id="rId5"/>
   </p:handoutMasterIdLst>
   <p:sldIdLst>
      <p:sldId id="267"
         xmlns:rel="http://…/relationships" rel:id="rId2"/>
      <p:sldId id="256"
         xmlns:rel="http://…/relationships" rel:id="rId3"/>
   </p:sldIdLst>
       <p:sldSz cx="9144000" cy="6858000"/>
   <p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>

通过使用 Open XML SDK 2.0,您可以利用 PresentationML 元素所对应的强类型类创建文档结构和内容。可以在 DocumentFormat.OpenXml.Presentation 命名空间中找到这些类。下表列出了 sld、sldLayout、sldMaster 和 notesMaster 元素所对应类的类名:

PresentationML 元素

Open XML SDK 2.0 类

说明

sld

Slide

演示文稿幻灯片。它是 SlidePart 的根元素。

sldLayout

SlideLayout

幻灯片版式。它是 SlideLayoutPart 的根元素。

sldMaster

SlideMaster

幻灯片母版。它是 SlideMasterPart 的根元素。

notesMaster

NotesMaster

备注母版(或讲义母版)。它是 NotesMasterPart 的根元素。

示例代码的工作方式

该示例代码由方法 GetSlideTitles 的两个重载组成。在第一个重载方法中,通过 using 语句打开演示文稿文件。然后,它将 PresentationDocument 对象传递给第二个重载的 GetSlideTitles 方法,该方法返回代表演示文稿中所有幻灯片标题的列表。

// Get a list of the titles of all the slides in the presentation.
public static IList<string> GetSlideTitles(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument =
        PresentationDocument.Open(presentationFile, false))
    {
        return GetSlideTitles(presentationDocument);
    }
}
' Get a list of the titles of all the slides in the presentation.
Public Shared Function GetSlideTitles(ByVal presentationFile As String) As IList(Of String)
    ' Open the presentation as read-only.
    Using presentationDocument As PresentationDocument = PresentationDocument.Open(presentationFile, False)
        Return GetSlideTitles(presentationDocument)
    End Using
End Function

第二个重载的 GetSlideTitles 方法用于获取幻灯片标题列表。该方法采用传入的 PresentationDocument 对象,循环访问其中的幻灯片并获取该演示文稿中所有幻灯片的幻灯片 ID。对于每个幻灯片 ID,此方法会获取幻灯片部件以传递给 GetSlideTitle 方法。此方法向第一个 GetSlideTitles 方法返回由标题组成的字符串列表,其中每个字符串表示一个幻灯片标题。

// Get a list of the titles of all the slides in the presentation.
public static IList<string> GetSlideTitles(PresentationDocument presentationDocument)
{
    if (presentationDocument == null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Get a PresentationPart object from the PresentationDocument object.
    PresentationPart presentationPart = presentationDocument.PresentationPart;

    if (presentationPart != null &&
        presentationPart.Presentation != null)
    {
        // Get a Presentation object from the PresentationPart object.
        Presentation presentation = presentationPart.Presentation;

        if (presentation.SlideIdList != 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>())
            {
                SlidePart slidePart = presentationPart.GetPartById(slideId.RelationshipId) as SlidePart;

                // Get the slide title.
                string title = GetSlideTitle(slidePart);

                // An empty title can also be added.
                titlesList.Add(title);
            }

            return titlesList;
        }

    }

    return null;
}
' Get a list of the titles of all the slides in the presentation.
Public Shared Function GetSlideTitles(ByVal presentationDocument As PresentationDocument) As IList(Of String)
    If presentationDocument Is Nothing Then
        Throw New ArgumentNullException("presentationDocument")
    End If

    ' Get a PresentationPart object from the PresentationDocument object.
    Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

    If presentationPart IsNot Nothing AndAlso presentationPart.Presentation IsNot Nothing Then
        ' Get a Presentation object from the PresentationPart object.
        Dim presentation As Presentation = presentationPart.Presentation

        If presentation.SlideIdList IsNot Nothing Then
            Dim titlesList As New List(Of String)()

            ' Get the title of each slide in the slide order.
            For Each slideId In presentation.SlideIdList.Elements(Of SlideId)()
                Dim slidePart As SlidePart = TryCast(presentationPart.GetPartById(slideId.RelationshipId), SlidePart)

                ' Get the slide title.
                Dim title As String = GetSlideTitle(slidePart)

                ' An empty title can also be added.
                titlesList.Add(title)
            Next slideId

            Return titlesList
        End If

    End If

    Return Nothing
End Function

方法 GetSlideTitle 用于获取每个幻灯片的标题。它采用传入的幻灯片部件,并为第二个重载的 GetSlideTitles 方法返回一个表示该幻灯片标题的字符串。

// Get the title string of the slide.
public static string GetSlideTitle(SlidePart slidePart)
{
    if (slidePart == null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Declare a paragraph separator.
    string paragraphSeparator = null;

    if (slidePart.Slide != 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)
        {
            // Get the text in each paragraph in this shape.
            foreach (var paragraph in shape.TextBody.Descendants<D.Paragraph>())
            {
                // 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;
}
' Get the title string of the slide.
Public Shared Function GetSlideTitle(ByVal slidePart As SlidePart) As String
    If slidePart Is Nothing Then
        Throw New ArgumentNullException("presentationDocument")
    End If

    ' Declare a paragraph separator.
    Dim paragraphSeparator As String = Nothing

    If slidePart.Slide IsNot Nothing Then
        ' Find all the title shapes.
        Dim shapes = From shape In slidePart.Slide.Descendants(Of Shape)()
                     Where IsTitleShape(shape)
                     Select shape

        Dim paragraphText As New StringBuilder()

        For Each shape In shapes
            ' Get the text in each paragraph in this shape.
            For Each paragraph In shape.TextBody.Descendants(Of D.Paragraph)()
                ' Add a line break.
                paragraphText.Append(paragraphSeparator)

                For Each text In paragraph.Descendants(Of D.Text)()
                    paragraphText.Append(text.Text)
                Next text

                paragraphSeparator = vbLf
            Next paragraph
        Next shape

        Return paragraphText.ToString()
    End If

    Return String.Empty
End Function

在 GetSlideTitle 方法中调用布尔方法 IsTitleShape,以确定形状是否为标题形状。该方法采用传入的幻灯片部件,如果形状是标题形状,则返回 true;否则返回 false。

// Determines whether the shape is a title shape.
private static bool IsTitleShape(Shape shape)
{
    var placeholderShape = shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.GetFirstChild<PlaceholderShape>();
    if (placeholderShape != null && placeholderShape.Type != null && placeholderShape.Type.HasValue)
    {
        switch ((PlaceholderValues)placeholderShape.Type)
        {
            // Any title shape.
            case PlaceholderValues.Title:

            // A centered title.
            case PlaceholderValues.CenteredTitle:
                return true;

            default:
                return false;
        }
    }
    return false;
}
' Determines whether the shape is a title shape.
Private Shared Function IsTitleShape(ByVal shape As Shape) As Boolean
    Dim placeholderShape = shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.GetFirstChild(Of PlaceholderShape)()
    If placeholderShape IsNot Nothing AndAlso placeholderShape.Type IsNot Nothing AndAlso placeholderShape.Type.HasValue Then
        Select Case CType(placeholderShape.Type, PlaceholderValues)
            ' Any title shape.
            Case PlaceholderValues.Title, PlaceholderValues.CenteredTitle

            ' A centered title.
                Return True

            Case Else
                Return False
        End Select
    End If
    Return False
End Function

示例代码

下面是可用于获取演示文稿文件中幻灯片标题的完整代码示例。例如,可以在程序中使用以下 foreach 语句返回演示文稿文件"Myppt9.pptx"中的所有标题。

foreach (string s in GetSlideTitles(@"C:\Users\Public\Documents\Myppt9.pptx"))
   Console.WriteLine(s);
For Each s As String In GetSlideTitles("C:\Users\Public\Documents\Myppt9.pptx")
   Console.WriteLine(s)
Next

结果将为表示演示文稿中的标题的字符串列表,每个字符串一行。

以下是使用 C# 和 Visual Basic 编写的完整示例代码。

// Get a list of the titles of all the slides in the presentation.
public static IList<string> GetSlideTitles(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument =
        PresentationDocument.Open(presentationFile, false))
    {
        return GetSlideTitles(presentationDocument);
    }
}

// Get a list of the titles of all the slides in the presentation.
public static IList<string> GetSlideTitles(PresentationDocument presentationDocument)
{
    if (presentationDocument == null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Get a PresentationPart object from the PresentationDocument object.
    PresentationPart presentationPart = presentationDocument.PresentationPart;

    if (presentationPart != null &&
        presentationPart.Presentation != null)
    {
        // Get a Presentation object from the PresentationPart object.
        Presentation presentation = presentationPart.Presentation;

        if (presentation.SlideIdList != 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>())
            {
                SlidePart slidePart = presentationPart.GetPartById(slideId.RelationshipId) as SlidePart;

                // 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.
public static string GetSlideTitle(SlidePart slidePart)
{
    if (slidePart == null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

    // Declare a paragraph separator.
    string paragraphSeparator = null;

    if (slidePart.Slide != 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)
        {
            // Get the text in each paragraph in this shape.
            foreach (var paragraph in shape.TextBody.Descendants<D.Paragraph>())
            {
                // 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.
private static bool IsTitleShape(Shape shape)
{
    var placeholderShape = shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.GetFirstChild<PlaceholderShape>();
    if (placeholderShape != null && placeholderShape.Type != null && placeholderShape.Type.HasValue)
    {
        switch ((PlaceholderValues)placeholderShape.Type)
        {
            // Any title shape.
            case PlaceholderValues.Title:

            // A centered title.
            case PlaceholderValues.CenteredTitle:
                return true;

            default:
                return false;
        }
    }
    return false;
}
' Get a list of the titles of all the slides in the presentation.
Public Function GetSlideTitles(ByVal presentationFile As String) As IList(Of String)

    ' Open the presentation as read-only.
    Dim presentationDocument As PresentationDocument = presentationDocument.Open(presentationFile, False)
    Using (presentationDocument)
        Return GetSlideTitles(presentationDocument)
    End Using

End Function
' Get a list of the titles of all the slides in the presentation.
Public Function GetSlideTitles(ByVal presentationDocument As PresentationDocument) As IList(Of String)
    If (presentationDocument Is Nothing) Then
        Throw New ArgumentNullException("presentationDocument")
    End If

    ' Get a PresentationPart object from the PresentationDocument object.
    Dim presentationPart As PresentationPart = presentationDocument.PresentationPart
    If ((Not (presentationPart) Is Nothing) _
       AndAlso (Not (presentationPart.Presentation) Is Nothing)) Then

        ' Get a Presentation object from the PresentationPart object.
        Dim presentation As Presentation = presentationPart.Presentation
        If (Not (presentation.SlideIdList) Is Nothing) Then

            Dim titlesList As List(Of String) = New List(Of String)

            ' Get the title of each slide in the slide order.
            For Each slideId As Object In presentation.SlideIdList.Elements(Of SlideId)()

                Dim slidePart As SlidePart = CType(presentationPart.GetPartById(slideId.RelationshipId.ToString()), SlidePart)

                ' Get the slide title.
                Dim title As String = GetSlideTitle(slidePart)

                ' An empty title can also be added.
                titlesList.Add(title)
            Next
            Return titlesList
        End If
    End If
    Return Nothing
End Function
' Get the title string of the slide.
Public Function GetSlideTitle(ByVal slidePart As SlidePart) As String
    If (slidePart Is Nothing) Then
        Throw New ArgumentNullException("presentationDocument")
    End If

    ' Declare a paragraph separator.
    Dim paragraphSeparator As String = Nothing
    If (Not (slidePart.Slide) Is Nothing) Then

        ' Find all the title shapes.
        Dim shapes = From shape In slidePart.Slide.Descendants(Of Shape)() _
         Where (IsTitleShape(shape)) _
         Select shape

        Dim paragraphText As StringBuilder = New StringBuilder

        For Each shape As Object In shapes

            ' Get the text in each paragraph in this shape.
            For Each paragraph As Object In shape.TextBody.Descendants(Of D.Paragraph)()

                ' Add a line break.
                paragraphText.Append(paragraphSeparator)

                For Each text As Object In paragraph.Descendants(Of D.Text)()
                    paragraphText.Append(text.Text)
                Next

                paragraphSeparator = "" & vbLf
            Next
        Next
        Return paragraphText.ToString
    End If
    Return String.Empty
End Function
' Determines whether the shape is a title shape.
Private Function IsTitleShape(ByVal shape As Shape) As Boolean
    Dim placeholderShape As Object = _
     shape.NonVisualShapeProperties.ApplicationNonVisualDrawingProperties.GetFirstChild(Of PlaceholderShape)()
    If ((Not (placeholderShape) Is Nothing) _
       AndAlso ((Not (placeholderShape.Type) Is Nothing) _
       AndAlso placeholderShape.Type.HasValue)) Then
        Select Case placeholderShape.Type.Value

            ' Any title shape
            Case PlaceholderValues.Title
                Return True

                ' A centered title.
            Case PlaceholderValues.CenteredTitle
                Return True
            Case Else
                Return False
        End Select
    End If
    Return False
End Function

请参阅

引用

Class Library Reference