22.08.2009, 13:29 Uhr

Open XML SDK - Office-Dokumente werden programmierbar

Das Open XML SDK stellt eine Klassenhierarchie zur Verfügung, die alle Elemente eines Office-Dokuments abbildet und daher das Erstellen von Office-Dokumente auf eine komfortable Grundlage stellt.
von Peter Monadjemi

Offene Formate sind eine Sache, darauf basierende Dokumente per Programm ansprechen zu können eine andere. Auch wenn der direkte Zugriff auf ein OpenXML-Dokument durch Öffnen des Zip-Archivs und Zugriff per XML-Parser theoretisch denkbar wäre, kommt er aus praktischen Gründen nicht in Frage. Auch die mit .NET 3.0 eingeführten Klassen im Namespace System.IO.Packaging sind nicht besonders komfortabel, da sie lediglich die Dokumentstruktur abbilden, der Dokumentinhalt in Gestalt von XML-Streams untypisiert angesprochen werden muss. Die Lösung bietet das Open XML SDK 2.0, das Dokumentinhalte beinahe so komfortabel ansprechbar macht wie es per Objektmodell (Stichwort: OLE Automation) vor Office 2007 üblich war.

Formalitäten

Das Open XML SDK ist ein separater Download [1]. Es besteht aus der Assembly DocumentFormat.OpenXml.dll, einer umfangreichen Dokumentation in Gestalt einer Windows-Hilfe-Datei und drei kleiner Tools, die schnell zu unentbehrlichen Helfern werden können (Tabelle 1). Das SDK gibt es derzeit in zwei Versionen. In einer bereits offiziell freigegebenen Version 1.1 und einer funktional erweiterten Version 2.0, die aber noch als CTP (Community Technical Preview) vorliegt. Die Version 1.1 ist für jene Entwickler, die mit einer offiziellen Version arbeiten möchten. Die Version 2.0 für jene, die bereits an den erweiterten Funktionalitäten, etwa zur Dokumentvalidierung, interessiert sind. Die Version 2.0 soll mit der Freigabe von Office 2010 offiziell werden.

Einsatzgebiete

Auch ein Office-Dokument, das im OpenXML-Format vorliegt, kann wie gewohnt über das Objektmodell der Anwendung angesprochen werden. Diese Variante besitzt aber gleich vier Einschränkungen: 1. Sie kann nur lokal durchgeführt werden. 2. Sie ist für den Einsatz auf einem (Web-) Server nicht geeignet. 3. Sie ist relativ langsam. 4. Sie setzt eine Office-Lizenz voraus. In Unternehmen wird aber immer häufiger eine performante, serverseitige Verarbeitung gewünscht, etwa, wenn eine große Anzahl an Rechnungen in kurzer Zeit generiert werden soll. Alles das ist nur mit dem Open XML SDK möglich, womit auch sein Einsatzbereich klar definiert wäre.
Ein erstes Beispiel

Die gute Nachricht ist, dass man bei Verwendung des Open XML SDKs relativ wenig über den Aufbau eines OpenXML-Dokuments und das Open Packaging Format (OPC) wissen muss. Die weniger gute ist eventuell, dass es ganz ohne WordML-Grundkenntnisse nicht geht. Da das Klassenmodell alle Elemente eines OpenXML-Dokuments abdeckt, spielt XPath zur Lokalisierung einzelner Knoten keine Rolle mehr. Da alle Elemente, wie z.B. eine Textmarke in einem Word-Dokument, typisiert zur Verfügung gestellt werden, biete es sich an, Dokumentinhalte per LINQ abzufragen. Listing 1 zeigt, wie einfach sich per Open XML SDK 2.0 ein neues Word-Dokument anlegen lässt (das zur besseren Übersichtlichkeit lediglich einen Absatz umfasst). Auf eine Formatierung wurde aus Platzgründen verzichtet (wie so etwas grundsätzlich geht, wurde im DeveloperWorld-Artikel von Jens Häupel bereits beschrieben [2]). Auch wenn solche Zahlenspielereien nicht allgemeingültig sind, das Anlegen von 10.000 dieser Dokumente benötigt auf einem Standard-PC ca. 90 Sekunden. Bei Verwendung von Automatisierung dürfte Wert ein Vielfaches betragen.

using (WordprocessingDocument wdDoc = WordprocessingDocument.Create(DocPfad, WordprocessingDocumentType.Document))
{
wdDoc.AddMainDocumentPart();
MainDocumentPart mainPart = wdDoc.MainDocumentPart;
mainPart.Document = new Document();
mainPart.Document.Body = new Body();
Paragraph tmPara = new Paragraph(
new Run(
new RunProperties(new Bold(), new Color() { Val="0000FF"}),
new Text(String.Format("Rechnung Nr. {0:0000}", 1000+i))));
mainPart.Document.Body.Append(tmPara);
mainPart.Document.Save();
Listing 1: Ein Word-Dokument wird angelegt
Dokumentinhalte per LINQ ansprechen

Die Elemente eines Word-Dokuments können nach dem Öffnen des Dokuments auf verschiedene Weisen angesprochen werden. Entweder als allgemeines OpenXmlElement oder als spezialisiertes Objekt. Der folgende Befehl fasst alle Elemente eines Dokuments zusammen:

wdDoc.MainDocumentPart.Document.Body.Elements()

Der folgende Befehl spricht nur die Textmarken des Dokuments an:

wdDoc.MainDocumentPart.Document.Body.Elements()

Was liegt näher als diese Collection per LINQ abzufragen, so dass sich Elemente mit bestimmten Eigenschaften herausfischen lassen? Listing 2 zeigt, wie sich jene Textmarken eines Word-Dokuments in einer Collection zusammenfassen lassen, deren Name ,,Betrag" lautet, und deren Textinhalt eine Zahl darstellt, die größer ist als der Inhalt einer Variablen (auf diese Weise ließen sich z.B. Rechnungen aussortieren).

var res = from bm in mainPart.Document.Body.Descendants()
where bm.Name == "Betrag" &&
Double.Parse(bm.NextSibling().InnerText, NumberStyles.Currency) > BetragLimit
select bm;
Listing 2: LINQ-Abfrage gegen den Inhalt eines Word-Dokuments

OpenXML Tools

Das Open XML SDK 2.0 umfasst aktuell knapp 3.000 Klassen. Am Anfang ist es daher eine echte Herausforderung eine Übersicht zu erhalten und z.B. herauszufinden, welche Klasse eine Textmarke in einem Word-Dokument repräsentiert. Mit Hilfe des DocumentReflector, der Teil des Open XML SDK ist, ist das kein Problem. Er zeigt nicht nur die Struktur eines geladenen Dokuments an, sondern auch den C#-Code, der die Struktur mit den Klassen des Open XML-SDKs generiert und leistet daher in etwa das, was früher der Makrorecorder zum ,,Erforschen" des Objektmodells geleistet hat.

Die Tools im Einzelnen:
DocumentReflector -> Zeigt die OpenXML-Klassen an, aus denen ein OpenXML-Dokument besteht.
OpenXMLClassExplorer -> Macht die Klassen des Open XML-SDKs außerhalb von Visual Studio sichtbar.
OpenXMLDiff - >Zeigt Unterschiede zwischen zwei Open XML-Dokumenten an.
Dokumente werden programmierbar

Mit dem Open XML SDK werden Dokumente programmierbar. Die Klassen des SDK bieten deutlich mehr Komfort als es zunächst den Anschein haben könnte. So ist es z.B. kein Problem, neue Absätze in ein Dokument einzufügen, da es dafür generische Methoden wie InsertAfter und InsertBefore gibt. Für Entwickler, denen der Komfort speziell bei Word-Dokumenten immer noch nicht weit genug geht, gibt es seit kurzem ein Community Projekt mit dem Namen DocX, das speziell den Umgang mit Tabellen und Abbildungen deutlich vereinfacht [3]. Die Tools sind da und warten darauf eingesetzt zu werden.

Links
[1] http://www.microsoft.com/downloads/details.aspx?FamilyId=C6E744E5-36E9-45F5-8D8C-331DF206E0D0&displaylang=en
[2] hhttp://www.computerworld.ch/aktuell/developerworld/48249/index.html
[3] http://docx.codeplex.com
Peter Monadiemi



Das könnte Sie auch interessieren