Abrufen des gesamten Texts einer Folie in einer Präsentation
In diesem Thema wird gezeigt, wie Sie die Klassen im Open XML SDK für Office verwenden, um den gesamten Text einer Folie in einer Präsentation programmgesteuert abzurufen.
Abrufen eines PresentationDocument-Objekts
Im Open XML SDK stellt die PresentationDocument-Klasse ein Präsentationsdokumentpaket dar. Zum Arbeiten mit einem Präsentationsdokument müssen Sie zuerst eine Instanz der PresentationDocument-Klasse erstellen und anschließend mit dieser Instanz arbeiten. Um die Klasse instance aus dem Dokument zu erstellen, rufen Sie die PresentationDocument.Open(String, Boolean)-Methode auf, die einen Dateipfad verwendet, und einen booleschen Wert als zweiten Parameter, um anzugeben, ob ein Dokument bearbeitet werden kann. Zum Öffnen eines Dokuments mit Lese-/Schreibzugriff weisen Sie diesem Parameter den Wert true zu, zum Öffnen des Dokuments mit Schreibschutz weisen Sie den Wert false wie in der folgenden using-Anweisung gezeigt zu. In diesem Code ist der file-Parameter eine Zeichenfolge, die den Pfad der Datei darstellt, in dem Sie das Dokument öffnen möchten.
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Insert other code here.
}
Die using-Anweisung ist eine empfohlene Alternative zur herkömmlichen Reihenfolge ".Open, .Save, .Close". Sie stellt sicher, dass die Dispose-Methode (vom Open XML SDK verwendete interne Methode zum Bereinigen von Ressourcen) bei Erreichen der schließenden Klammer automatisch aufgerufen wird. Der auf die using-Anweisung folgende Block richtet einen Bereich für das Objekt ein, das in der using-Anweisung erstellt oder benannt wird, in diesem Fall presentationDocument.
Grundlegende Präsentationsdokumentstruktur
Die grundlegende Dokumentstruktur eines PresentationML-Dokuments besteht aus vielen Teilen, darunter der Hauptteil mit der Präsentationsdefinition. Der folgende Text aus der SPEZIFIKATION ISO/IEC 29500 stellt die Gesamtform eines PresentationML-Pakets vor.
Der Standard Teil eines PresentationML-Pakets beginnt mit einem Präsentationsstammelement. Dieses Element enthält eine Präsentation, die wiederum auf eine Folienliste, eine Folie master Liste, eine Notizen- master Liste und ein Handzettel master Liste verweist. Die Folienliste bezieht sich auf alle Folien in der Präsentation; Die Folie master Liste bezieht sich auf die gesamten Folienmaster, die in der Präsentation verwendet werden; die Notizen master enthält Informationen zur Formatierung von Notizenseiten; und die Handzettel master beschreibt, wie ein Handzettel aussieht.
Ein Handzettel ist ein gedruckter Foliensatz, der an das Publikum verteilt werden kann.
Neben Text und Grafiken kann jede Folie Kommentare und Notizen enthalten, ein Layout aufweisen und Teil mindestens einer zielgruppenorientierten Präsentation sein. Ein Kommentar ist eine an die Person, die die Präsentationsfolien verwaltet, gerichtete Anmerkung. Eine Notiz ist eine Erinnerung oder eine kurze Textstelle, die für den Präsentator oder das Publikum bestimmt ist.
Weitere Features, die ein PresentationML-Dokument umfassen kann: Animation, Audio, Video und Übergänge zwischen Folien.
Ein PresentationML-Dokument wird nicht als ein großer Textkörper in einem einzelnen Teil gespeichert. Die Elemente, mit deren Hilfe bestimmte Funktionsgruppierungen erfolgen, sind stattdessen in mehreren Teilen gespeichert. Beispielsweise sind alle Kommentare in einem Dokument in einem Kommentarteil gespeichert, wobei jede Folie über einen eigenen Teil verfügt.
© ISO/IEC29500: 2008.
Das folgende XML-Codebeispiel stellt eine Präsentation dar, die zwei Folien mit den IDs 267 und 256 enthält.
<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>
Mit dem Open XML SDK können Sie Dokumentstrukturen und -inhalte mithilfe stark typisierter Klassen erstellen, die PresentationML-Elementen entsprechen. Sie finden diese Klassen im DocumentFormat.OpenXml.Presentation-Namespace . Die folgende Tabelle enthält die Namen der Klassen, die den Elementen sld, sldLayout, sldMaster und notesMaster entsprechen.
PresentationML-Element | Open XML SDK-Klasse | Beschreibung |
---|---|---|
Sld | Slide | Präsentationsfolie. Das SlidePart-Stammelement. |
sldLayout | SlideLayout | Das Folienlayout. Das SlideLayoutPart-Stammelement. |
sldMaster | SlideMaster | Der Folienmaster. Das SlideMasterPart-Stammelement. |
notesMaster | NotesMaster | Notizenmaster (oder Handzettelmaster). Das NotesMasterPart-Stammelement. |
Funktionsweise des Beispielcodes
Der Beispielcode besteht aus drei Überladungen der GetAllTextInSlide-Methode. Im folgenden Segment öffnet die erste überladene Methode die Quellpräsentation, die die Folie mit dem abzurufenden Text enthält, und übergibt die Präsentation an die zweite überladene Methode, die den Folienteil abruft. Diese Methode gibt das Array von Zeichenfolgen zurück, das die zweite Methode an sie zurückgibt, von denen jede einen Textabsatz auf der angegebenen Folie darstellt.
// Get all the text in a slide.
public static string[] GetAllTextInSlide(string presentationFile, int slideIndex)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Pass the presentation and the slide index
// to the next GetAllTextInSlide method, and
// then return the array of strings it returns.
return GetAllTextInSlide(presentationDocument, slideIndex);
}
}
Die zweite überladene Methode verwendet das übergebene Präsentationsdokument und ruft einen Folienteil ab, der an die dritte überladene Methode übergeben wird. Sie gibt an die erste überladene Methode das Array von Zeichenfolgen zurück, das die dritte überladene Methode an sie zurückgibt, von denen jede einen Textabsatz auf der angegebenen Folie darstellt.
public static string[] GetAllTextInSlide(PresentationDocument presentationDocument, int slideIndex)
{
// Verify that the presentation document exists.
if (presentationDocument == null)
{
throw new ArgumentNullException("presentationDocument");
}
// Verify that the slide index is not out of range.
if (slideIndex < 0)
{
throw new ArgumentOutOfRangeException("slideIndex");
}
// Get the presentation part of the presentation document.
PresentationPart presentationPart = presentationDocument.PresentationPart;
// Verify that the presentation part and presentation exist.
if (presentationPart != null && presentationPart.Presentation != null)
{
// Get the Presentation object from the presentation part.
Presentation presentation = presentationPart.Presentation;
// Verify that the slide ID list exists.
if (presentation.SlideIdList != null)
{
// Get the collection of slide IDs from the slide ID list.
var slideIds = presentation.SlideIdList.ChildElements;
// If the slide ID is in range...
if (slideIndex < slideIds.Count)
{
// Get the relationship ID of the slide.
string slidePartRelationshipId = (slideIds[slideIndex] as SlideId).RelationshipId;
// Get the specified slide part from the relationship ID.
SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);
// Pass the slide part to the next method, and
// then return the array of strings that method
// returns to the previous method.
return GetAllTextInSlide(slidePart);
}
}
}
// Else, return null.
return null;
}
Das folgende Codesegment zeigt die dritte überladene Methode, die den übergebenen Folienteil übernimmt und an die zweite überladene Methode ein Zeichenfolgenarray mit Textabsätzen zurückgibt. Zunächst überprüft die Methode, ob der übergebene Folienteil vorhanden ist, und erstellt eine verknüpfte Liste mit Zeichenfolgen. Sie durchläuft die Absätze der übergebenen Folie, verkettet alle Textzeilen in einem Absatz mithilfe eines StringBuilder-Objekts und weist jeden Absatz einer Zeichenfolge in der verknüpften Liste zu. Dann gibt sie an die zweite überladene Methode ein Zeichenfolgenarray zurück, das den gesamten Text auf der angegebenen Folie in der Präsentation darstellt.
public static string[] GetAllTextInSlide(SlidePart slidePart)
{
// Verify that the slide part exists.
if (slidePart == null)
{
throw new ArgumentNullException("slidePart");
}
// Create a new linked list of strings.
LinkedList<string> texts = new LinkedList<string>();
// If the slide exists...
if (slidePart.Slide != null)
{
// Iterate through all the paragraphs in the slide.
foreach (var paragraph in slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
{
// Create a new string builder.
StringBuilder paragraphText = new StringBuilder();
// Iterate through the lines of the paragraph.
foreach (var text in paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
{
// Append each line to the previous lines.
paragraphText.Append(text.Text);
}
if (paragraphText.Length > 0)
{
// Add each paragraph to the linked list.
texts.AddLast(paragraphText.ToString());
}
}
}
if (texts.Count > 0)
{
// Return an array of strings.
return texts.ToArray();
}
else
{
return null;
}
}
Beispielcode
Nachstehend ist der vollständige Beispielcode aufgeführt, mit dem Sie den gesamten Text auf einer bestimmten Folie in einer Präsentationsdatei abrufen können. Beispielsweise können Sie die folgende foreach-Schleife in Ihrem Programm verwenden, um das Array von Zeichenfolgen abzurufen, das von der GetAllTextInSlide-Methode zurückgegeben wird, die den Text auf der zweiten Folie der Präsentationsdatei "Myppt8.pptx" darstellt.
foreach (string s in GetAllTextInSlide(@"C:\Users\Public\Documents\Myppt8.pptx", 1))
Console.WriteLine(s);
Nachstehend ist der vollständige Beispielcode in C# und Visual Basic aufgeführt.
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
GetAllTextInSlide(args[0], int.Parse(args[1]));
// Get all the text in a slide.
static string[]? GetAllTextInSlide(string presentationFile, int slideIndex)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Pass the presentation and the slide index
// to the next GetAllTextInSlide method, and
// then return the array of strings it returns.
return GetAllTextInSlideFromPresentation(presentationDocument, slideIndex);
}
}
static string[]? GetAllTextInSlideFromPresentation(PresentationDocument presentationDocument, int slideIndex)
{
// Verify that the slide index is not out of range.
if (slideIndex < 0)
{
throw new ArgumentOutOfRangeException("slideIndex");
}
// Get the presentation part of the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Verify that the presentation part and presentation exist.
if (presentationPart is not null && presentationPart.Presentation is not null)
{
// Get the Presentation object from the presentation part.
Presentation presentation = presentationPart.Presentation;
// Verify that the slide ID list exists.
if (presentation.SlideIdList is not null)
{
// Get the collection of slide IDs from the slide ID list.
DocumentFormat.OpenXml.OpenXmlElementList slideIds = presentation.SlideIdList.ChildElements;
// If the slide ID is in range...
if (slideIndex < slideIds.Count)
{
// Get the relationship ID of the slide.
string? slidePartRelationshipId = ((SlideId)slideIds[slideIndex]).RelationshipId;
if (slidePartRelationshipId is null)
{
return null;
}
// Get the specified slide part from the relationship ID.
SlidePart slidePart = (SlidePart)presentationPart.GetPartById(slidePartRelationshipId);
// Pass the slide part to the next method, and
// then return the array of strings that method
// returns to the previous method.
return GetAllTextInSlideFromPart(slidePart);
}
}
}
// Else, return null.
return null;
}
static string[] GetAllTextInSlideFromPart(SlidePart slidePart)
{
// Verify that the slide part exists.
if (slidePart is null)
{
throw new ArgumentNullException("slidePart");
}
// Create a new linked list of strings.
LinkedList<string> texts = new LinkedList<string>();
// If the slide exists...
if (slidePart.Slide is not null)
{
// Iterate through all the paragraphs in the slide.
foreach (DocumentFormat.OpenXml.Drawing.Paragraph paragraph in
slidePart.Slide.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
{
// Create a new string builder.
StringBuilder paragraphText = new StringBuilder();
// Iterate through the lines of the paragraph.
foreach (DocumentFormat.OpenXml.Drawing.Text text in
paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Text>())
{
// Append each line to the previous lines.
paragraphText.Append(text.Text);
}
if (paragraphText.Length > 0)
{
// Add each paragraph to the linked list.
texts.AddLast(paragraphText.ToString());
}
}
}
// Return an array of strings.
return texts.ToArray();
}