本主题演示如何使用 Open XML SDK for Office 中的类以编程方式获取演示文稿中所有幻灯片的标题。
获取 PresentationDocument 对象
在 Open XML SDK 中 PresentationDocument , 类表示演示文稿文档包。 若要处理演示文稿文档,请先创建 类的 PresentationDocument
实例,然后使用该实例。 若要从文档创建类实例, Open 请调用使用文件路径的方法,并使用布尔值作为第二个参数来指定文档是否可编辑。 若要打开只读文档,请指定此参数的值 false
,如以下 using
语句所示。 在此代码中 presentationFile
, 参数是一个字符串,表示要从中打开文档的文件的路径。
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
在 v3.0.0+ 中, Close() 已删除 方法,转而依赖于 using 语句。
这可确保在 Dispose() 到达右大括号时自动调用 方法。 语句后面的 using
块为在 语句中创建 using
或命名的对象建立作用域,在本例 presentationDocument
中为 。
基本演示文稿文档结构
文档的基本文档结构PresentationML
由多个部分组成,其中包括包含表示定义的main部分。
ISO/IEC 29500 规范中的以下文本介绍了包的整体PresentationML
形式。
包的main部分
PresentationML
以演示文稿根元素开头。 该元素包含演示文稿,演示文稿又引用幻灯片 列表、幻灯片母版 列表、备注母版 列表和讲义母版 列表。 幻灯片列表指的是演示文稿中的所有幻灯片;幻灯片母版列表指的是演示文稿中使用的全部幻灯片母版;备注母版包含有关备注页格式的信息;讲义母版描述讲义的外观。讲义 是可提供给访问群体 的一组打印的幻灯片。
除了文本和图形,每个幻灯片还可以包含注释 和备注,可以具有布局,并且可以是一个或多个自定义演示文稿 的组成部分。 注释是供维护演示文稿幻灯片平台的人员参考的批注。 备注是供演示者或访问群体参考的提醒信息或一段文字。
文档可以包括以下其他功能
PresentationML
: 动画、 音频、 视频和幻灯片之间的 切换 效果。文档
PresentationML
不作为一个大正文存储在单个部件中。 而实现某些功能组合的元素会存储在各个部件中。 例如,文档中的所有作者都存储在一个作者部件中,而每个幻灯片都有自己的部分。ISO/IEC 29500:2016
以下 XML 代码示例代表包含用 ID 267 和 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>
使用 Open XML SDK,可以使用对应于 PresentationML 元素的强类型类创建文档结构和内容。 可以在 命名空间中找到 DocumentFormat.OpenXml.Presentation 这些类。 下表列出了对应于 、、 sldLayout
sldMaster
和 notesMaster
元素的类的sld
类名。
PresentationML 元素 | Open XML SDK 类 | 说明 |
---|---|---|
<sld/> |
Slide | 演示文稿幻灯片。 它是 SlidePart 的根元素。 |
<sldLayout/> |
SlideLayout | 幻灯片版式。 它是 SlideLayoutPart 的根元素。 |
<sldMaster/> |
SlideMaster | 幻灯片母版。 它是 SlideMasterPart 的根元素。 |
<notesMaster/> |
NotesMaster | 备注母版(或讲义母版)。 它是 NotesMasterPart 的根元素。 |
示例代码
以下示例代码获取演示文稿文件中幻灯片的所有标题。 例如,可以在程序中使用以下 foreach
语句返回位于第一个参数的演示文稿文件中的所有标题。
foreach(string title in GetSlideTitles(args[0]))
{
Console.WriteLine(title);
}
结果将为表示演示文稿中的标题的字符串列表,每个字符串一行。
以下是使用 C# 和 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;
}