Anwenden eines Designs auf eine Präsentation
In diesem Thema wird gezeigt, wie Sie die Klassen im Open XML SDK für Office verwenden, um das Design programmgesteuert von einer Präsentation auf eine andere Präsentation anzuwenden.
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 Open -Methode auf, die einen Dateipfad verwendet, und einen booleschen Wert als zweiten Parameter, um anzugeben, ob ein Dokument bearbeitet werden kann. Geben Sie zum Öffnen eines Dokuments mit Schreibschutz den Wert false für diesen Parameter an. Geben Sie zum Öffnen eines Dokuments mit Lese-/Schreibzugriff den Wert true für diesen Parameter an. In der folgenden using-Anweisung werden zwei Präsentationsdateien geöffnet: die Zielpräsentation, auf die ein Design angewendet werden soll, und die Quellpräsentation, auf die das Design bereits angewendet wurde. Die Quellpräsentationsdatei wird mit Schreibschutz geöffnet, und die Zielpräsentationsdatei wird mit Lese-/Schreibzugriff geöffnet. In diesem Code ist der themePresentation-Parameter eine Zeichenfolge, die den Pfad für das Quellpräsentationsdokument darstellt, und der presentationFile-Parameter ist eine Zeichenfolge, die den Pfad für das Zielpräsentationsdokument darstellt.
using (PresentationDocument themeDocument = PresentationDocument.Open(themePresentation, false))
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
Mit v3.0.0 und höher wurde die Close() -Methode entfernt, um sich auf die using-Anweisung zu verlassen.
Dadurch wird sichergestellt, dass die Dispose() -Methode automatisch aufgerufen wird, wenn die schließende Klammer erreicht ist. Der Block, der auf die using
-Anweisung folgt, richtet einen Bereich für das Objekt ein, das in der using
-Anweisung erstellt oder benannt wird, in diesem Fall themeDocument
und presentationDocument
.
Grundlegende Präsentationsdokumentstruktur
Die grundlegende Dokumentstruktur eines PresentationML
Dokuments besteht aus einer Reihe von Teilen, darunter der Standard Teil, der die Präsentationsdefinition enthält. Der folgende Text aus der SPEZIFIKATION ISO/IEC 29500 stellt die Gesamtform eines Pakets vor PresentationML
.
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 Text in einem einzelnen Teil gespeichert. Die Elemente, mit deren Hilfe bestimmte Funktionsgruppierungen erfolgen, sind stattdessen in mehreren Teilen gespeichert. Beispielsweise werden alle Autoren in einem Dokument in einem Autorenteil gespeichert, während jede Folie über einen eigenen Teil verfügt.ISO/IEC 29500: 2016
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 -Namespace. In der folgenden Tabelle sind die Klassennamen der Klassen aufgeführt, die den sld
Elementen , 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. |
Struktur des Hyperlinkelements
Die folgenden Informationen aus der SPEZIFIKATION ISO/IEC 29500 können bei der Arbeit mit diesem Element nützlich sein.
Dieses Element definiert den komplexen Typ auf Stammebene, der einem freigegebenen Stylesheet (oder Design) zugeordnet ist. Es enthält alle verschiedenen Formatierungsoptionen, die für ein Dokument über ein Design verfügbar sind, und es definiert das gesamte Aussehen und Verhalten des Dokuments, wenn Objekte mit Designs innerhalb des Dokuments verwendet werden. [Beispiel: Betrachten Sie die folgende Abbildung als Beispiel für verschiedene Designs, die auf eine Präsentation angewendet werden. In diesem Beispiel können Sie sehen, wie sich ein Design auf Schriftart, Farben, Hintergründe, Füllungen und Effekte für verschiedene Objekte in einer Präsentation auswirken kann. Ende des Beispiels]
In diesem Beispiel wird gezeigt, wie ein Design die Schriftart, Farben, Hintergründe, Füllungen und Effekte für verschiedene Objekte in einer Präsentation beeinflussen kann. Ende des Beispiels]
© ISO/IEC 29500: 2016
In der folgenden Tabelle sind die möglichen untergeordneten Typen der Theme-Klasse aufgeführt.
PresentationML-Element | Open XML SDK-Klasse | Beschreibung |
---|---|---|
custClrLst | CustomColorList | Benutzerdefinierte Farbliste |
extLst | ExtensionList | Erweiterungsliste |
extraClrSchemeLst | ExtraColorSchemeList | Liste zusätzlicher Farbschemata |
objectDefaults | ObjectDefaults | Objektstandardwerte |
themeElements | ThemeElements | Designelemente |
Das folgende XML-Schemafragment definiert vier Teile des Designelements. Das themeElements-Element enthält die wichtigste Formatierung, die innerhalb des Designs definiert ist. Die anderen Teile stellen Überschreibungen, Standardwerte und Ergänzungen zu den Informationen in themeElements bereit. Der komplexe Typ, mit dem ein Design definiert ist (CT_OfficeStyleSheet) wird wie folgt definiert:
<complexType name="CT_OfficeStyleSheet">
<sequence>
<element name="themeElements" type="CT_BaseStyles" minOccurs="1" maxOccurs="1"/>
<element name="objectDefaults" type="CT_ObjectStyleDefaults" minOccurs="0" maxOccurs="1"/>
<element name="extraClrSchemeLst" type="CT_ColorSchemeList" minOccurs="0" maxOccurs="1"/>
<element name="custClrLst" type="CT_CustomColorList" minOccurs="0" maxOccurs="1"/>
<element name="extLst" type="CT_OfficeArtExtensionList" minOccurs="0" maxOccurs="1"/>
</sequence>
<attribute name="name" type="xsd:string" use="optional" default=""/>
</complexType>
Dieser komplexe Typ umfasst auch ein CT_OfficeArtExtensionList-Element, das für die zukünftige Erweiterbarkeit dieses komplexen Typs verwendet wird.
Funktionsweise des Beispielcodes
Der Beispielcode besteht aus zwei Überladungen der ApplyThemeToPresentation-Methode und der GetSlideLayoutType-Methode. Das folgende Codesegment zeigt die erste überladene Methode, in der die beiden Präsentationsdateien themePresentation und presentationFile geöffnet und an die zweite überladene Methode als Parameter übergeben werden.
// Apply a new theme to the presentation.
static void ApplyThemeToPresentation(string presentationFile, string themePresentation)
{
using (PresentationDocument themeDocument = PresentationDocument.Open(themePresentation, false))
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
ApplyThemeToPresentationDocument(presentationDocument, themeDocument);
}
}
In der zweiten überladenen Methode überprüft der Code zunächst, ob eine der Präsentationsdateien leer ist. In diesem Fall wird eine Ausnahme ausgelöst. Der Code ruft dann den Präsentationsteil des Präsentationsdokuments ab, indem ein PresentationPart-Objekt deklariert und auf den Präsentationsteil des übergebenen PresentationDocument-Zielobjekts festgelegt wird. Anschließend wird die Folie master Teile aus den Präsentationsteilen beider übergebenen Objekten abgerufen und die Beziehungs-ID der Folie master Teil der Zielpräsentation abgerufen.
// Apply a new theme to the presentation.
static void ApplyThemeToPresentationDocument(PresentationDocument presentationDocument, PresentationDocument themeDocument)
{
// Get the presentation part of the presentation document.
PresentationPart presentationPart = presentationDocument.PresentationPart ?? presentationDocument.AddPresentationPart();
// Get the existing slide master part.
SlideMasterPart slideMasterPart = presentationPart.SlideMasterParts.ElementAt(0);
string relationshipId = presentationPart.GetIdOfPart(slideMasterPart);
// Get the new slide master part.
PresentationPart themeDocPresentationPart = themeDocument.PresentationPart ?? themeDocument.AddPresentationPart();
SlideMasterPart newSlideMasterPart = themeDocPresentationPart.SlideMasterParts.ElementAt(0);
Der Code entfernt dann den vorhandenen Designteil und den Folienmasterteil aus der Zielpräsentation. Durch die Wiederverwendung der alten Beziehungs-ID wird der neue Folienmasterteil aus der Quellpräsentation der Zielpräsentation hinzugefügt. Zudem wird der Designteil der Zielpräsentation hinzugefügt.
if (presentationPart.ThemePart is not null)
{
// Remove the existing theme part.
presentationPart.DeletePart(presentationPart.ThemePart);
}
// Remove the old slide master part.
presentationPart.DeletePart(slideMasterPart);
// Import the new slide master part, and reuse the old relationship ID.
newSlideMasterPart = presentationPart.AddPart(newSlideMasterPart, relationshipId);
if (newSlideMasterPart.ThemePart is not null)
{
// Change to the new theme part.
presentationPart.AddPart(newSlideMasterPart.ThemePart);
}
Der Code durchläuft alle Folienlayoutteile im Folienmasterteil und fügt sie der Liste der neuen Folienlayouts hinzu. Er gibt den Standardlayouttyp an. Für dieses Beispiel lautet der Code für den Standardlayouttyp Title and Content.
Dictionary<string, SlideLayoutPart> newSlideLayouts = new Dictionary<string, SlideLayoutPart>();
foreach (var slideLayoutPart in newSlideMasterPart.SlideLayoutParts)
{
string? newLayoutType = GetSlideLayoutType(slideLayoutPart);
if (newLayoutType is not null)
{
newSlideLayouts.Add(newLayoutType, slideLayoutPart);
}
}
string? layoutType = null;
SlideLayoutPart? newLayoutPart = null;
// Insert the code for the layout for this example.
string defaultLayoutType = "Title and Content";
Der Code durchläuft alle Folienteile in der Zielpräsentation und entfernt die Folienlayoutbeziehung in allen Folien. Er verwendet die GetSlideLayoutType-Methode, um nach dem Layouttyp des Folienlayoutteils zu suchen. Für jede Folie mit vorhandenem Folienlayoutteil wird ein neuer Folienlayoutteil entsprechend dem Typ hinzugefügt, der zuvor vorhanden war. Für jede Folie ohne vorhandenen Folienlayoutteil wird ein neuer Folienlayoutteil entsprechend dem Standardtyp hinzugefügt.
// Remove the slide layout relationship on all slides.
foreach (var slidePart in presentationPart.SlideParts)
{
layoutType = null;
if (slidePart.SlideLayoutPart is not null)
{
// Determine the slide layout type for each slide.
layoutType = GetSlideLayoutType(slidePart.SlideLayoutPart);
// Delete the old layout part.
slidePart.DeletePart(slidePart.SlideLayoutPart);
}
if (layoutType is not null && newSlideLayouts.TryGetValue(layoutType, out newLayoutPart))
{
// Apply the new layout part.
slidePart.AddPart(newLayoutPart);
}
else
{
newLayoutPart = newSlideLayouts[defaultLayoutType];
// Apply the new default layout part.
slidePart.AddPart(newLayoutPart);
}
}
Zum Abrufen des Folienlayouttyps verwendet der Code die GetSlideLayoutType-Methode, die den Folienlayoutteil als Parameter enthält, und gibt an die zweite überladene ApplyThemeToPresentation-Methode eine Zeichenfolge zurück, die den Namen des Folienlayouttyps darstellt.
// Get the slide layout type.
static string? GetSlideLayoutType(SlideLayoutPart slideLayoutPart)
{
CommonSlideData? slideData = slideLayoutPart.SlideLayout?.CommonSlideData;
return slideData?.Name;
}
Beispielcode
Es folgt der vollständige Beispielcode, den Sie zum Kopieren eines Designs aus einer Präsentation in eine andere verwenden können. Zur Verwendung des Programms müssen Sie zwei Präsentationen erstellen: eine Quellpräsentation mit dem Design, das Sie kopieren möchten (z. B. Myppt9-theme.pptx), und eine Zielpräsentation (z. B. Myppt9.pptx). Für den Kopiervorgang können Sie den folgenden Aufruf im Programm verwenden.
ApplyThemeToPresentation(args[0], args[1]);
Nach Durchführung dieses Aufrufs können Sie die Datei Myppt2.pptx überprüfen, und es sollte dasselbe Design angezeigt werden wie in der Datei Myppt9-theme.pptx.
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;
using System.Collections.Generic;
using System.Linq;
ApplyThemeToPresentation(args[0], args[1]);
// Apply a new theme to the presentation.
static void ApplyThemeToPresentation(string presentationFile, string themePresentation)
{
using (PresentationDocument themeDocument = PresentationDocument.Open(themePresentation, false))
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
ApplyThemeToPresentationDocument(presentationDocument, themeDocument);
}
}
// Apply a new theme to the presentation.
static void ApplyThemeToPresentationDocument(PresentationDocument presentationDocument, PresentationDocument themeDocument)
{
// Get the presentation part of the presentation document.
PresentationPart presentationPart = presentationDocument.PresentationPart ?? presentationDocument.AddPresentationPart();
// Get the existing slide master part.
SlideMasterPart slideMasterPart = presentationPart.SlideMasterParts.ElementAt(0);
string relationshipId = presentationPart.GetIdOfPart(slideMasterPart);
// Get the new slide master part.
PresentationPart themeDocPresentationPart = themeDocument.PresentationPart ?? themeDocument.AddPresentationPart();
SlideMasterPart newSlideMasterPart = themeDocPresentationPart.SlideMasterParts.ElementAt(0);
if (presentationPart.ThemePart is not null)
{
// Remove the existing theme part.
presentationPart.DeletePart(presentationPart.ThemePart);
}
// Remove the old slide master part.
presentationPart.DeletePart(slideMasterPart);
// Import the new slide master part, and reuse the old relationship ID.
newSlideMasterPart = presentationPart.AddPart(newSlideMasterPart, relationshipId);
if (newSlideMasterPart.ThemePart is not null)
{
// Change to the new theme part.
presentationPart.AddPart(newSlideMasterPart.ThemePart);
}
Dictionary<string, SlideLayoutPart> newSlideLayouts = new Dictionary<string, SlideLayoutPart>();
foreach (var slideLayoutPart in newSlideMasterPart.SlideLayoutParts)
{
string? newLayoutType = GetSlideLayoutType(slideLayoutPart);
if (newLayoutType is not null)
{
newSlideLayouts.Add(newLayoutType, slideLayoutPart);
}
}
string? layoutType = null;
SlideLayoutPart? newLayoutPart = null;
// Insert the code for the layout for this example.
string defaultLayoutType = "Title and Content";
// Remove the slide layout relationship on all slides.
foreach (var slidePart in presentationPart.SlideParts)
{
layoutType = null;
if (slidePart.SlideLayoutPart is not null)
{
// Determine the slide layout type for each slide.
layoutType = GetSlideLayoutType(slidePart.SlideLayoutPart);
// Delete the old layout part.
slidePart.DeletePart(slidePart.SlideLayoutPart);
}
if (layoutType is not null && newSlideLayouts.TryGetValue(layoutType, out newLayoutPart))
{
// Apply the new layout part.
slidePart.AddPart(newLayoutPart);
}
else
{
newLayoutPart = newSlideLayouts[defaultLayoutType];
// Apply the new default layout part.
slidePart.AddPart(newLayoutPart);
}
}
}
// Get the slide layout type.
static string? GetSlideLayoutType(SlideLayoutPart slideLayoutPart)
{
CommonSlideData? slideData = slideLayoutPart.SlideLayout?.CommonSlideData;
return slideData?.Name;
}