如何:将幻灯片移到演示文稿中的新位置

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

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

本文内容
获取 Presentation 对象
基本演示文稿文档结构
示例代码的工作方式
统计幻灯片的数目
将幻灯片从一个位置移动到另一位置
示例代码

本主题演示如何使用 Open XML SDK 2.0 for Microsoft Office 中的类以编程方式将幻灯片移动到演示文稿中的新位置。

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

using System;
using System.Linq;
using DocumentFormat.OpenXml.Presentation;
using DocumentFormat.OpenXml.Packaging;
Imports System
Imports System.Linq
Imports DocumentFormat.OpenXml.Presentation
Imports DocumentFormat.OpenXml.Packaging

获取 Presentation 对象

在 Open XML SDK 中,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 的根元素。

示例代码的工作方式

若要将演示文稿文件中的特定幻灯片移动到新位置,需要首先知道演示文稿中幻灯片的数目。因此,本主题中的代码分为两部分。第一部分统计幻灯片的数目,第二部分将幻灯片移动到新位置。

统计幻灯片的数目

用于统计幻灯片数目的示例代码由 CountSlides 方法的两个重载组成。第一个重载使用 string 参数,第二个重载使用 PresentationDocument 参数。在第一个 CountSlides 方法中,示例代码在 using 语句中打开演示文稿文档。然后它将 PresentationDocument 对象传递给第二个 CountSlides 方法,该方法返回一个整数,表示演示文稿中幻灯片的数目。

// Pass the presentation to the next CountSlides method
// and return the slide count.
return CountSlides(presentationDocument);
' Pass the presentation to the next CountSlides method
' and return the slide count.
Return CountSlides(presentationDocument)

在第二个 CountSlides 方法中,代码验证传入的 PresentationDocument 对象是否为 null,如果不为 null,则从 PresentationDocument 对象中获取 PresentationPart 对象。通过使用 SlideParts,代码获取并返回 slideCount。

// 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;

// Get the slide count from the SlideParts.
if (presentationPart != null)
{
    slidesCount = presentationPart.SlideParts.Count();
}
// Return the slide count to the previous method.
return slidesCount;
' Check for a null document object.
If presentationDocument Is Nothing Then
    Throw New ArgumentNullException("presentationDocument")
End If

Dim slidesCount As Integer = 0

' Get the presentation part of document.
Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

' Get the slide count from the SlideParts.
If presentationPart IsNot Nothing Then
    slidesCount = presentationPart.SlideParts.Count()
End If
' Return the slide count to the previous method.
Return slidesCount

将幻灯片从一个位置移动到另一位置

将幻灯片移动到新位置需要通过将值 true 指定给布尔参数来打开文件以进行读/写访问,如以下的 using 语句所示。用于移动幻灯片的代码由 MoveSlide 方法的两个重载组成。第一个重载的 MoveSlide 方法采用三个参数:一个表示演示文稿文件名和路径的字符串,和两个分别表示幻灯片的当前索引位置和要将幻灯片移到的索引位置的整数。此方法打开演示文稿文件,获取 PresentationDocument 对象,然后将此对象和两个整数(fromto)传递到执行实际移动操作的第二个重载的 MoveSlide 方法。

// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        MoveSlide(presentationDocument, from, to);
    }
}
' Move a slide to a different position in the slide order in the presentation.
Public Shared Sub MoveSlide(ByVal presentationFile As String, ByVal [from] As Integer, ByVal [to] As Integer)
    Using presentationDocument As PresentationDocument = PresentationDocument.Open(presentationFile, True)
        MoveSlide(presentationDocument, From, [to])
    End Using
End Sub

在第二个重载的 MoveSlide 方法中,将调用 CountSlides 方法以获取演示文稿中的幻灯片数目。代码然后检查基于零的索引(fromto)是否位于范围内并且二者不同。

public static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
    if (presentationDocument == null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

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

    // Verify that both from and to positions are within range and different from one another.
    if (from < 0 || from >= slidesCount)
    {
        throw new ArgumentOutOfRangeException("from");
    }

    if (to < 0 || from >= slidesCount || to == from)
    {
        throw new ArgumentOutOfRangeException("to");
    }
Public Shared Sub MoveSlide(ByVal presentationDocument As PresentationDocument, ByVal [from] As Integer, ByVal [to] As Integer)
    If presentationDocument Is Nothing Then
        Throw New ArgumentNullException("presentationDocument")
    End If

    ' Call the CountSlides method to get the number of slides in the presentation.
    Dim slidesCount As Integer = CountSlides(presentationDocument)

    ' Verify that both from and to positions are within range and different from one another.
    If
        From < 0 OrElse
        From >= slidesCount Then
        Throw New ArgumentOutOfRangeException("from")
    End If

    If [to] < 0 OrElse
        From >= slidesCount OrElse [to] =
        From Then
        Throw New ArgumentOutOfRangeException("to")
    End If

将声明并设置 PresentationPart 对象,使它等于传入的 PresentationDocument 对象的演示文稿部件。PresentationPart 对象用于创建 Presentation 对象,然后从 Presentation 对象中创建表示演示文稿中的幻灯片列表的 SlideIdList 对象。将获取源幻灯片(要移动的幻灯片)的幻灯片 ID,然后确定目标幻灯片(幻灯片顺序中要将源幻灯片移到其后面的幻灯片)的位置。

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

// The slide count is not zero, so the presentation must contain slides.            
Presentation presentation = presentationPart.Presentation;
SlideIdList slideIdList = presentation.SlideIdList;

// Get the slide ID of the source slide.
SlideId sourceSlide = slideIdList.ChildElements[from] as SlideId;

SlideId targetSlide = null;

// Identify the position of the target slide after which to move the source slide.
if (to == 0)
{
    targetSlide = null;
}
if (from < to)
{
    targetSlide = slideIdList.ChildElements[to] as SlideId;
}
else
{
    targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
}
' Get the presentation part from the presentation document.
Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

' The slide count is not zero, so the presentation must contain slides.            
Dim presentation As Presentation = presentationPart.Presentation
Dim slideIdList As SlideIdList = presentation.SlideIdList

' Get the slide ID of the source slide.
Dim sourceSlide As SlideId = TryCast(slideIdList.ChildElements(From), SlideId)

Dim targetSlide As SlideId = Nothing

' Identify the position of the target slide after which to move the source slide.
If to = 0 Then
    targetSlide = Nothing
End If
If From < to Then
    targetSlide = TryCast(slideIdList.ChildElements(to), SlideId)
Else
    targetSlide = TryCast(slideIdList.ChildElements(to - 1), SlideId)
End If

首先使用 SlideID 对象的 Remove 方法从当前位置移除源幻灯片,然后使用 SlideIdList 对象的 InsertAfter 方法在目标幻灯片后面的索引位置插入源幻灯片。最后,保存修改的演示文稿。

// Remove the source slide from its current position.
sourceSlide.Remove();

// Insert the source slide at its new position after the target slide.
slideIdList.InsertAfter(sourceSlide, targetSlide);

// Save the modified presentation.
presentation.Save();
' Remove the source slide from its current position.
sourceSlide.Remove()

' Insert the source slide at its new position after the target slide.
slideIdList.InsertAfter(sourceSlide, targetSlide)

' Save the modified presentation.
presentation.Save()

示例代码

下面是可用于将幻灯片从一个位置移动到同一演示文稿文件中的另一位置的完整示例代码。例如,您可以在您的程序中使用以下调用在名为"Myppt11.pptx"的演示文稿文件中将幻灯片从位置 0 移动到位置 1。

MoveSlide(@"C:\Users\Public\Documents\Myppt11.pptx", 0, 1);
MoveSlide("C:\Users\Public\Documents\Myppt11.pptx", 0, 1)

运行程序后,请检查您的演示文稿文件以查看幻灯片的新位置。

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

// Counting the slides in the presentation.
 public static int CountSlides(string presentationFile)
{
    // Open the presentation as read-only.
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
    {
        // Pass the presentation to the next CountSlides method
        // and return the slide count.
        return CountSlides(presentationDocument);
    }
}

// Count the slides in the presentation.
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;

    // Get the slide count from the SlideParts.
    if (presentationPart != null)
    {
        slidesCount = presentationPart.SlideParts.Count();
    }

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

// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
    using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
    {
        MoveSlide(presentationDocument, from, to);
    }
}
// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
    if (presentationDocument == null)
    {
        throw new ArgumentNullException("presentationDocument");
    }

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

    // Verify that both from and to positions are within range and different from one another.
    if (from < 0 || from >= slidesCount)
    {
        throw new ArgumentOutOfRangeException("from");
    }

    if (to < 0 || from >= slidesCount || to == from)
    {
        throw new ArgumentOutOfRangeException("to");
    }

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

    // The slide count is not zero, so the presentation must contain slides.            
    Presentation presentation = presentationPart.Presentation;
    SlideIdList slideIdList = presentation.SlideIdList;

    // Get the slide ID of the source slide.
    SlideId sourceSlide = slideIdList.ChildElements[from] as SlideId;

    SlideId targetSlide = null;

    // Identify the position of the target slide after which to move the source slide.
    if (to == 0)
    {
        targetSlide = null;
    }
    if (from < to)
    {
        targetSlide = slideIdList.ChildElements[to] as SlideId;
    }
    else
    {
        targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
    }

    // Remove the source slide from its current position.
    sourceSlide.Remove();

    // Insert the source slide at its new position after the target slide.
    slideIdList.InsertAfter(sourceSlide, targetSlide);

    // Save the modified presentation.
    presentation.Save();
}
' Count the slides in the presentation.
Public Function CountSlides(ByVal presentationFile As String) As Integer

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

        ' Pass the presentation to the next CountSlide method
        ' and return the slide count.
        Return CountSlides(presentationDocument)
    End Using
End Function
' Count the slides in the presentation.
Public Function CountSlides(ByVal presentationDocument As PresentationDocument) As Integer

    ' Check for a null document object.
    If (presentationDocument Is Nothing) Then
        Throw New ArgumentNullException("presentationDocument")
    End If
    Dim slidesCount As Integer = 0

    ' Get the presentation part of the document.
    Dim presentationPart As PresentationPart = presentationDocument.PresentationPart
    If ((Not (presentationPart) Is Nothing) AndAlso (Not (presentationPart.Presentation) Is Nothing)) Then

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

            ' Get the slide count from the slide ID list.
            slidesCount = presentation.SlideIdList.Elements.Count()

        End If
    End If

    ' Return the slide count to the previous function.
    Return slidesCount
End Function
' Move a slide to a different position in the slide order in the presentation.
Public Sub MoveSlide(ByVal presentationFile As String, ByVal from As Integer, ByVal moveTo As Integer)
    Dim presentationDocument As PresentationDocument = presentationDocument.Open(presentationFile, True)

    Using (presentationDocument)
        MoveSlide(presentationDocument, from, moveTo)
    End Using

End Sub
' Move a slide to a different position in the slide order in the presentation.
Public Sub MoveSlide(ByVal presentationDocument As PresentationDocument, ByVal from As Integer, ByVal moveTo As Integer)
    If (presentationDocument Is Nothing) Then
        Throw New ArgumentNullException("presentationDocument")
    End If

    ' Use the CountSlides sample to get the number of slides in the presentation.
    Dim slidesCount As Integer = CountSlides(presentationDocument)

    ' Verify that both from and to positions are within range and different from one another.
    If ((from < 0) OrElse (from >= slidesCount)) Then
        Throw New ArgumentOutOfRangeException("from")
    End If

    If ((moveTo < 0) _
                OrElse ((from >= slidesCount) _
                OrElse (moveTo = from))) Then
        Throw New ArgumentOutOfRangeException("moveTo")
    End If

    ' Get the presentation part from the presentation document.
    Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

    ' The slide count is not zero, so the presentation must contain slides. 
    Dim presentation As Presentation = presentationPart.Presentation
    Dim slideIdList As SlideIdList = presentation.SlideIdList

    ' Get the slide ID of the source slide.
    Dim sourceSlide As SlideId = CType(slideIdList.ChildElements(from), SlideId)
    Dim targetSlide As SlideId = Nothing

    ' Identify the position of the target slide after which to move the source slide.
    If (moveTo = 0) Then
        targetSlide = Nothing
    End If

    If (from < moveTo) Then
        targetSlide = CType(slideIdList.ChildElements(moveTo), SlideId)
    Else
        targetSlide = CType(slideIdList.ChildElements((moveTo - 1)), SlideId)
    End If

    ' Remove the source slide from its current position.
    sourceSlide.Remove()

    ' Insert the source slide at its new position after the target slide.
    slideIdList.InsertAfter(sourceSlide, targetSlide)

    ' Save the modified presentation.
    presentation.Save()

End Sub

请参阅

引用

Class Library Reference