Share via


Anleitung: Verschieben eines Absatzes aus einer Präsentation in eine andere Präsentation

Letzte Änderung: Donnerstag, 14. Oktober 2010

Gilt für: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010

Inhalt dieses Artikels
Abrufen eines PresentationDocument-Objekts
Grundlegende Präsentationsdokumentstruktur
Struktur des Formtextkörpers
Funktionsweise des Beispielcodes
Beispielcode

In diesem Thema wird erklärt, wie Sie die Klassen im Open XML SDK 2.0 für Microsoft Office zum programmgesteuerten Verschieben eines Absatzes aus einer Präsentation in eine andere Präsentation verwenden.

Die folgenden Assemblydirektiven sind zum Kompilieren des Codes in diesem Thema erforderlich.

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

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. Rufen Sie zum Erstellen der Klasseninstanz anhand des Dokuments die Open(String, Boolean)-Methode auf, die einen Dateipfad und als zweiten Parameter einen booleschen Wert verwendet, um anzugeben, ob ein Dokument bearbeitet werden kann. Zum Öffnen eines Dokuments mit Lese-/Schreibzugriff geben Sie den Wert true für diesen Parameter an (siehe die folgende using-Anweisung). In diesem Code ist der file-Parameter eine Zeichenfolge, die den Pfad der Datei darstellt, in der Sie das Dokument öffnen möchten.

using (PresentationDocument doc = PresentationDocument.Open(file, true))
{
    // Insert other code here.
}
Using doc As PresentationDocument = PresentationDocument.Open(file, True)
    ' Insert other code here.
End Using

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 doc.

Grundlegende Präsentationsdokumentstruktur

Die grundlegende Dokumentstruktur eines PresentationML-Dokuments besteht aus vielen Teilen, darunter der Hauptteil mit der Präsentationsdefinition. Im folgenden Text aus der ISO/IEC 29500-Spezifikation wird das Gesamtformat eines PresentationML-Pakets erläutert.

Der Hauptteil eines PresentationML-Pakets beginnt mit dem Stammelement der Präsentation. Dieses Element enthält eine Präsentation, die wiederum auf eine Folienliste, eine Folienmasterliste, eine Notizenmasterliste und eine Handzettelmasterliste verweist. Die Folienliste verweist auf alle Folien in der Präsentation. Die Folienmasterliste verweist auf sämtliche in der Präsentation verwendeten Folienmaster. Der Notizenmaster enthält Informationen zur Formatierung der Notizenseiten. Und der Handzettelmaster beschreibt das Aussehen eines Handzettels.

Ein Handzettel ist ein gedruckter Foliensatz, der an eine Zielgruppe zur späteren Bezugnahme 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 Anmerkung der Person, die die Foliengruppe der Präsentation verwaltet. Eine Notiz ist eine Erinnerung oder eine kurze Textstelle, die für den Präsentator oder die Zielgruppe bestimmt ist.

Andere Features, die in einem PresentationML-Dokument enthalten sein können, sind Animationen, Audio, Video und Überblendungen zwischen den 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.

Dieses XML-Codesegment 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="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>

Mit dem Open XML SDK 2.0 können Sie eine Dokumentstruktur und Inhalte erstellen, indem Sie stark typisierte Klassen verwenden, die PresentationML-Elementen entsprechen. Diese Klassen sind im DocumentFormat.OpenXml.Presentation-Namespace enthalten. Die folgende Tabelle enthält die Namen der Klassen, die den Elementen sld, sldLayout, sldMaster und notesMaster entsprechen.

PresentationML-Element

Open XML SDK 2.0-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 Formtextkörpers

Im folgenden Text aus der ISO/IEC 29500-Spezifikation wird die Struktur dieses Elements erläutert.

Mit diesem Element wird das Vorhandensein von Text angegeben, der innerhalb der entsprechenden Form vorhanden sein soll. Der gesamte sichtbare Text und mit sichtbarem Text verbundene Eigenschaften sind innerhalb dieses Elements enthalten. Es können mehrere Absätze und mehrere Textläufe innerhalb von Absätzen vorhanden sein.

© ISO/IEC29500: 2008.

In der folgenden Tabelle sind die untergeordneten Elemente des Formtextkörpers jeweils mit einer Beschreibung aufgeführt.

Untergeordnetes Element

Beschreibung

bodyPr

Textkörpereigenschaften

lstStyle

Textlistenformate

p

Textabsätze

Das folgende XML-Schemafragment definiert den Inhalt dieses Elements:

<complexType name="CT_TextBody">
   <sequence>
       <element name="bodyPr" type="CT_TextBodyProperties" minOccurs="1" maxOccurs="1"/>
       <element name="lstStyle" type="CT_TextListStyle" minOccurs="0" maxOccurs="1"/>
       <element name="p" type="CT_TextParagraph" minOccurs="1" maxOccurs="unbounded"/>
   </sequence>
</complexType>

Funktionsweise des Beispielcodes

Der Code in diesem Thema enthält die beiden Methoden MoveParagraphToPresentation und GetFirstSlide. Die erste Methode verwendet zwei Zeichenfolgenparameter, von denen einer die Quelldatei darstellt, die den zu verschiebenden Absatz enthält, und eine die Zieldatei, in die der Absatz verschoben wird. Die Methode öffnet beide Präsentationsdateien und ruft anschließend die GetFirstSlide-Methode zum Abrufen der ersten Folie in jeder Datei auf. Anschließend werden die erste TextBody-Form in jeder Folie und der erste Absatz in der Quellform abgerufen. Es erfolgt ein umfassender Klonvorgang, bei dem nicht nur das Paragraph-Quellobjekt selbst, sondern auch der gesamte Inhalt dieses Objekts einschließlich seines Texts kopiert wird. Anschließend wird der geklonte Absatz in die Zieldatei kopiert, der Quellabsatz aus der Quelldatei entfernt und durch einen Platzhalterabsatz ersetzt. Schließlich werden die geänderten Folien in beiden Präsentationen gespeichert.

// Moves a paragraph range in a TextBody shape in the source document
// to another TextBody shape in the target document.
public static void MoveParagraphToPresentation(string sourceFile, string targetFile)
{
    // Open the source file as read/write.
    using (PresentationDocument sourceDoc = PresentationDocument.Open(sourceFile, true))
    {
        // Open the target file as read/write.
        using (PresentationDocument targetDoc = PresentationDocument.Open(targetFile, true))
        {
            // Get the first slide in the source presentation.
            SlidePart slide1 = GetFirstSlide(sourceDoc);

            // Get the first TextBody shape in it.
            TextBody textBody1 = slide1.Slide.Descendants<TextBody>().First();

            // Get the first paragraph in the TextBody shape.
            // Note: "Drawing" is the alias of namespace DocumentFormat.OpenXml.Drawing
            Drawing.Paragraph p1 = textBody1.Elements<Drawing.Paragraph>().First();

            // Get the first slide in the target presentation.
            SlidePart slide2 = GetFirstSlide(targetDoc);

            // Get the first TextBody shape in it.
            TextBody textBody2 = slide2.Slide.Descendants<TextBody>().First();

            // Clone the source paragraph and insert the cloned. paragraph into the target TextBody shape.
            // Passing "true" creates a deep clone, which creates a copy of the 
            // Paragraph object and everything directly or indirectly referenced by that object.
            textBody2.Append(p1.CloneNode(true));

            // Remove the source paragraph from the source file.
            textBody1.RemoveChild<Drawing.Paragraph>(p1);

            // Replace the removed paragraph with a placeholder.
            textBody1.AppendChild<Drawing.Paragraph>(new Drawing.Paragraph());

            // Save the slide in the source file.
            slide1.Slide.Save();

            // Save the slide in the target file.
            slide2.Slide.Save();
        }
    }
}
' Moves a paragraph range in a TextBody shape in the source document
' to another TextBody shape in the target document.
Public Shared Sub MoveParagraphToPresentation(ByVal sourceFile As String, ByVal targetFile As String)
    ' Open the source file as read/write.
    Using sourceDoc As PresentationDocument = PresentationDocument.Open(sourceFile, True)
        ' Open the target file as read/write.
        Using targetDoc As PresentationDocument = PresentationDocument.Open(targetFile, True)
            ' Get the first slide in the source presentation.
            Dim slide1 As SlidePart = GetFirstSlide(sourceDoc)

            ' Get the first TextBody shape in it.
            Dim textBody1 As TextBody = slide1.Slide.Descendants(Of TextBody)().First()

            ' Get the first paragraph in the TextBody shape.
            ' Note: "Drawing" is the alias of namespace DocumentFormat.OpenXml.Drawing
            Dim p1 As Drawing.Paragraph = textBody1.Elements(Of Drawing.Paragraph)().First()

            ' Get the first slide in the target presentation.
            Dim slide2 As SlidePart = GetFirstSlide(targetDoc)

            ' Get the first TextBody shape in it.
            Dim textBody2 As TextBody = slide2.Slide.Descendants(Of TextBody)().First()

            ' Clone the source paragraph and insert the cloned. paragraph into the target TextBody shape.
            ' Passing "true" creates a deep clone, which creates a copy of the 
            ' Paragraph object and everything directly or indirectly referenced by that object.
            textBody2.Append(p1.CloneNode(True))

            ' Remove the source paragraph from the source file.
            textBody1.RemoveChild(Of Drawing.Paragraph)(p1)

            ' Replace the removed paragraph with a placeholder.
            textBody1.AppendChild(Of Drawing.Paragraph)(New Drawing.Paragraph())

            ' Save the slide in the source file.
            slide1.Slide.Save()

            ' Save the slide in the target file.
            slide2.Slide.Save()
        End Using
    End Using
End Sub

Die GetFirstSlide-Methode verwendet das übergebene PresentationDocument-Objekt, ruft dessen Präsentationsteil ab und ruft anschließend die ID der ersten Folie in der Folienliste ab. Danach ruft sie die Beziehungs-ID der Folie und den Folienteil aus der Beziehungs-ID ab und gibt den Folienteil an die aufrufende Methode zurück.

// Get the slide part of the first slide in the presentation document.
public static SlidePart GetFirstSlide(PresentationDocument presentationDocument)
{
    // Get relationship ID of the first slide
    PresentationPart part = presentationDocument.PresentationPart;
    SlideId slideId = part.Presentation.SlideIdList.GetFirstChild<SlideId>();
    string relId = slideId.RelationshipId;

    // Get the slide part by the relationship ID.
    SlidePart slidePart = (SlidePart)part.GetPartById(relId);

    return slidePart;
}
' Get the slide part of the first slide in the presentation document.
Public Shared Function GetFirstSlide(ByVal presentationDocument As PresentationDocument) As SlidePart
    ' Get relationship ID of the first slide
    Dim part As PresentationPart = presentationDocument.PresentationPart
    Dim slideId As SlideId = part.Presentation.SlideIdList.GetFirstChild(Of SlideId)()
    Dim relId As String = slideId.RelationshipId

    ' Get the slide part by the relationship ID.
    Dim slidePart As SlidePart = CType(part.GetPartById(relId), SlidePart)

    Return slidePart
End Function

Beispielcode

Durch Verwenden dieses Beispielcodes können Sie einen Absatz von einer Präsentation in eine andere verschieben. Sie können im Programm den folgenden Aufruf der MoveParagraphToPresentation-Methode verwenden, um den ersten Absatz aus der Präsentationsdatei Myppt4.pptx in die Präsentationsdatei Myppt12.pptx zu verschieben.

string sourceFile = @"C:\Users\Public\Documents\Myppt4.pptx";
string targetFile = @"C:\Users\Public\Documents\Myppt12.pptx";
MoveParagraphToPresentation(sourceFile, targetFile);
Dim sourceFile As String = "C:\Users\Public\Documents\Myppt4.pptx"
Dim targetFile As String = "C:\Users\Public\Documents\Myppt12.pptx"
MoveParagraphToPresentation(sourceFile, targetFile)

Sehen Sie sich nach Ausführung des Programms den Inhalt der Quell- und der Zieldatei mit dem verschobenen Absatz an.

Es folgt der vollständige Beispielcode in C# und Visual Basic.

// Moves a paragraph range in a TextBody shape in the source document
// to another TextBody shape in the target document.
public static void MoveParagraphToPresentation(string sourceFile, string targetFile)
{
    // Open the source file as read/write.
    using (PresentationDocument sourceDoc = PresentationDocument.Open(sourceFile, true))
    {
        // Open the target file as read/write.
        using (PresentationDocument targetDoc = PresentationDocument.Open(targetFile, true))
        {
            // Get the first slide in the source presentation.
            SlidePart slide1 = GetFirstSlide(sourceDoc);

            // Get the first TextBody shape in it.
            TextBody textBody1 = slide1.Slide.Descendants<TextBody>().First();

            // Get the first paragraph in the TextBody shape.
            // Note: "Drawing" is the alias of namespace DocumentFormat.OpenXml.Drawing
            Drawing.Paragraph p1 = textBody1.Elements<Drawing.Paragraph>().First();

            // Get the first slide in the target presentation.
            SlidePart slide2 = GetFirstSlide(targetDoc);

            // Get the first TextBody shape in it.
            TextBody textBody2 = slide2.Slide.Descendants<TextBody>().First();

            // Clone the source paragraph and insert the cloned. paragraph into the target TextBody shape.
            // Passing "true" creates a deep clone, which creates a copy of the 
            // Paragraph object and everything directly or indirectly referenced by that object.
            textBody2.Append(p1.CloneNode(true));

            // Remove the source paragraph from the source file.
            textBody1.RemoveChild<Drawing.Paragraph>(p1);

            // Replace the removed paragraph with a placeholder.
            textBody1.AppendChild<Drawing.Paragraph>(new Drawing.Paragraph());

            // Save the slide in the source file.
            slide1.Slide.Save();

            // Save the slide in the target file.
            slide2.Slide.Save();
        }
    }
}

// Get the slide part of the first slide in the presentation document.
public static SlidePart GetFirstSlide(PresentationDocument presentationDocument)
{
    // Get relationship ID of the first slide
    PresentationPart part = presentationDocument.PresentationPart;
    SlideId slideId = part.Presentation.SlideIdList.GetFirstChild<SlideId>();
    string relId = slideId.RelationshipId;

    // Get the slide part by the relationship ID.
    SlidePart slidePart = (SlidePart)part.GetPartById(relId);

    return slidePart;
}
' Moves a paragraph range in a TextBody shape in the source document
' to another TextBody shape in the target document.
Public Sub MoveParagraphToPresentation(ByVal sourceFile As String, ByVal targetFile As String)

    ' Open the source file.
    Dim sourceDoc As PresentationDocument = PresentationDocument.Open(sourceFile, True)

    ' Open the target file.
    Dim targetDoc As PresentationDocument = PresentationDocument.Open(targetFile, True)

    ' Get the first slide in the source presentation.
    Dim slide1 As SlidePart = GetFirstSlide(sourceDoc)

    ' Get the first TextBody shape in it.
    Dim textBody1 As TextBody = slide1.Slide.Descendants(Of TextBody).First()

    ' Get the first paragraph in the TextBody shape.
    ' Note: Drawing is the alias of the namespace DocumentFormat.OpenXml.Drawing
    Dim p1 As Drawing.Paragraph = textBody1.Elements(Of Drawing.Paragraph).First()

    ' Get the first slide in the target presentation.
    Dim slide2 As SlidePart = GetFirstSlide(targetDoc)

    ' Get the first TextBody shape in it.
    Dim textBody2 As TextBody = slide2.Slide.Descendants(Of TextBody).First()

    ' Clone the source paragraph and insert the cloned paragraph into the target TextBody shape.
    textBody2.Append(p1.CloneNode(True))

    ' Remove the source paragraph from the source file.
    textBody1.RemoveChild(Of Drawing.Paragraph)(p1)

    ' Replace it with an empty one, because a paragraph is required for a TextBody shape.
    textBody1.AppendChild(Of Drawing.Paragraph)(New Drawing.Paragraph())

    ' Save the slide in the source file.
    slide1.Slide.Save()

    ' Save the slide in the target file.
    slide2.Slide.Save()

End Sub
' Get the slide part of the first slide in the presentation document.
Public Function GetFirstSlide(ByVal presentationDoc As PresentationDocument) As SlidePart

    ' Get relationship ID of the first slide.
    Dim part As PresentationPart = presentationDoc.PresentationPart
    Dim slideId As SlideId = part.Presentation.SlideIdList.GetFirstChild(Of SlideId)()
    Dim relId As String = slideId.RelationshipId

    ' Get the slide part by the relationship ID.
    Dim slidePart As SlidePart = CType(part.GetPartById(relId), SlidePart)

    Return slidePart

End Function

Siehe auch

Referenz

Class Library Reference