Kopieren des Inhalts eines Open XML-Paketteils in ein Dokumentteil in einem anderen Paket

In diesem Thema wird gezeigt, wie Sie die Klassen im Open XML SDK für Office verwenden, um den Inhalt eines Open XML Wordprocessing-Dokumentteils programmgesteuert in ein Dokumentteil in einem anderen Textverarbeitungsdokument zu kopieren.


Pakete und Dokumentteile

Ein Open XML-Dokument wird als Paket gespeichert, dessen Format durch die Spezifikation ISO/IEC 29500-2 definiert ist. Das Paket kann mehrere Teile enthalten, die untereinander in Beziehung stehen. Durch die Beziehung zwischen den Teilen wird die Kategorie des Dokuments gesteuert. Ein Dokument kann als Textverarbeitungsdokument definiert sein, falls sein Paketbeziehungselement eine Beziehung zu einem Hauptdokumentteil besitzt. Falls das Paketbeziehungselement eine Beziehung zu einem Präsentationsteil hat, kann es als Präsentationsdokument definiert sein. Falls das Paketbeziehungselement eine Beziehung zu einem Arbeitsmappenteil hat, ist es als Tabellenkalkulationsdokument definiert. In diesem Thema vom Typ "Gewusst wie" wird ein Textverarbeitungsdokument-Paket verwendet.


Abrufen eines WordprocessingDocument-Objekts

Um ein vorhandenes Dokument zu öffnen, instanziieren Sie die WordprocessingDocument-Klasse wie in den folgenden beiden using-Anweisungen gezeigt. In derselben Anweisung öffnen Sie die Textverarbeitungsdatei mit dem angegebenen Dateinamen, indem Sie die Open-Methode mit dem booleschen Parameter verwenden. Für die Quelldatei legen Sie den Parameter auf false fest, um sie mit Schreibschutz zu öffnen. Für die Zieldatei legen Sie den Parameter auf true fest, um die Bearbeitung des Dokuments zu ermöglichen.

    using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
    using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
    {
        // Insert other code here.
    }

Die using-Anweisung stellt eine empfohlene Alternative zu der üblichen Sequenz „.Create, .Save, .Close“ dar. Mit dieser wird sichergestellt, dass die Dispose-Methode (interne vom Open XML SDK zum Bereinigen von Ressourcen verwendete 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. Da die WordprocessingDocument-Klasse im Open XML SDK das Objekt automatisch als Teil seiner System.IDisposable-Implementierung speichert und schließt und Dispose automatisch aufgerufen wird, wenn Sie den Block verlassen, müssen Save und Close nicht explizit aufgerufen werden, solange Sie using verwenden.


Struktur eines WordProcessingML-Dokuments

Die grundlegende Struktur eines WordProcessingML-Dokuments besteht aus den document- und body-Elementen, gefolgt von einem oder mehreren Block-Level-Elementen wie p, das für einen Absatz steht. Ein Absatz enthält ein oder mehrere r-Elemente. r steht für ausführen und meint einen Textbereich mit gemeinsamen Eigenschaften wie Formatierung. Eine Ausführung besteht aus einem oder mehreren t-Elementen. Das t-Element enthält einen Textbereich. Das folgende Codebeispiel zeigt das WordprocessingML-Markup für ein Dokument, das den Text "Beispieltext" enthält.

    <w:document xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
      <w:body>
        <w:p>
          <w:r>
            <w:t>Example text.</w:t>
          </w:r>
        </w:p>
      </w:body>
    </w:document>

Mit dem Open XML SDK können Sie Dokumentstrukturen und -inhalte mit stark typisierten Klassen erstellen, die WordprocessingML-Elementen entsprechen. Diese Klassen sind im DocumentFormat.OpenXml.Wordprocessing -Namespace enthalten. Die folgende Tabelle enthält die Namen der Klassen, die den Elementen document, body, p, r und t entsprechen.

WordprocessingML-Element Open XML SDK-Klasse Beschreibung
document Document Das Stammelement des Hauptdokumentteils.
Text Body Der Container für die Strukturen auf Blockebene, z. B. Absätze, Tabellen, Anmerkungen und andere, die in der Spezifikation ISO/IEC 29500 angegeben sind.
p Paragraph Ein Absatz.
r Run Ein Lauf.
t Text Ein Textbereich.

Weitere Informationen zur Gesamtstruktur der Teile und Elemente eines WordprocessingML-Dokuments finden Sie unter Struktur eines WordprocessingML-Dokuments.


Der Designteil

Der Designteil enthält Informationen zu Farbe, Schriftart und Format eines Dokuments. Sie ist in der SPEZIFIKATION ISO/IEC 29500 wie folgt definiert.

Eine Instanz dieses Teiletyps enthält Informationen zum Design eines Dokuments, einer Kombination aus Farbschema, Schriftartenschema und Formatschema (Letzteres wird auch als Effekte bezeichnet). In einem WordprocessingML-Dokument beeinflusst die Auswahl des Designs unter anderem die Farbe und das Format von Überschriften. In einem SpreadsheetML-Dokument wirkt sich die Auswahl des Designs beispielsweise auf die Farbe und das Format der Zellinhalte und Diagramme aus. In einem PresentationML-Dokument beeinflusst die Auswahl des Designs unter anderem die Formatierung der Folien, Handzettel und Notizen über den zugehörigen Master.

Ein WordprocessingML- oder SpreadsheetML-Paket kann höchstens einen (oder keinen) Designteil enthalten, der das Ziel einer impliziten Beziehung in einem Hauptdokumentteil (§11.3.10) oder Arbeitsmappenteil (§12.3.23) darstellt. Ein PresentationML-Paket kann über eine implizite Beziehung höchstens einen (oder keinen) Designteil pro Handzettelmaster- (§13.3.3), Notizenmaster- (§13.3.4), Folienmaster- (§13.3.10) oder Präsentationsteil (§13.3.6) enthalten.

Beispiel: Das folgende WordprocessingML-Hauptdokumentelement enthält eine Beziehung zum Designteil, der im ZIP-Elementdesign/-theme1.xml gespeichert ist:

    <Relationships xmlns="…">
       <Relationship Id="rId4"
          Type="https://…/theme" Target="theme/theme1.xml"/>
    </Relationships>

© ISO/IEC29500: 2008.


Funktionsweise des Beispielcodes

Zum Kopieren des Inhalts eines Dokumentteils in einem Open XML-Paket in einen Dokumentteil in einem anderen Paket wird der vollständige Pfad jedes Textverarbeitungsdokuments als Parameter an die CopyThemeContent-Methode übergeben. Im Code werden dann beide Dokumente als WordprocessingDocument-Objekte geöffnet und Variablen erstellt, welche die jeweiligen ThemePart-Teile in jedem Paket referenzieren.

    public static void CopyThemeContent(string fromDocument1, string toDocument2)
    {
       using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
       using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
       {
          ThemePart themePart1 = wordDoc1.MainDocumentPart.ThemePart;
          ThemePart themePart2 = wordDoc2.MainDocumentPart.ThemePart;

Der Code liest dann den Inhalt des ThemePart-Quellteils mithilfe eines StreamReader-Objekts und schreibt ihn mithilfe eines StreamWriter-Objekts in den ThemePart-Zielteil.

    using (StreamReader streamReader = new StreamReader(themePart1.GetStream()))
    using (StreamWriter streamWriter = new StreamWriter(themePart2.GetStream(FileMode.Create))) 
    {
        streamWriter.Write( streamReader.ReadToEnd());
    }

Beispielcode

Mit dem folgenden Code wird der Inhalt eines Dokumentteils in einem Open XML-Paket in einen Dokumentteil in einem anderen Paket kopiert. Zum Aufrufen der CopyThemeContent-Methode können Sie das folgende Beispiel verwenden, das den Designteil von "MyPkg4.docx" in "MyPkg3.docx" kopiert.

    string fromDocument1 = @"C:\Users\Public\Documents\MyPkg4.docx";
    string toDocument2 = @"C:\Users\Public\Documents\MyPkg3.docx";
    CopyThemeContent(fromDocument1, toDocument2);

Wichtig

Stellen Sie vor dem Ausführen des Programms sicher, dass für das Quelldokument (MyPkg4.docx) der Designteil festgelegt ist. Andernfalls würde eine Ausnahme ausgelöst. Um einem Dokument ein Design hinzuzufügen, öffnen Sie es in Microsoft Word 2013, klicken Sie auf die Registerkarte Seitenlayout, klicken Sie auf Designs, und wählen Sie eines der verfügbaren Designs aus.

Nachdem Sie das Programm ausgeführt haben, können Sie die Datei "MyPkg3.docx" überprüfen, um das kopierte Design aus der Datei "MyPkg4.docx" zu sehen.

Nachstehend ist der vollständige Beispielcode in C# und Visual Basic aufgeführt.


using DocumentFormat.OpenXml.Packaging;
using System.IO;

CopyThemeContent(args[0], args[1]);

// To copy contents of one package part.
static void CopyThemeContent(string fromDocument1, string toDocument2)
{
    using (WordprocessingDocument wordDoc1 = WordprocessingDocument.Open(fromDocument1, false))
    using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(toDocument2, true))
    {
        ThemePart? themePart1 = wordDoc1?.MainDocumentPart?.ThemePart;
        ThemePart? themePart2 = wordDoc2?.MainDocumentPart?.ThemePart;

        // If the theme parts are null, then there is nothing to copy.
        if (themePart1 is null || themePart2 is null)
        {
            return;
        }

        using (StreamReader streamReader = new StreamReader(themePart1.GetStream()))
        using (StreamWriter streamWriter = new StreamWriter(themePart2.GetStream(FileMode.Create)))
        {
            streamWriter.Write(streamReader.ReadToEnd());
        }
    }
}

Siehe auch