Jens HäupelSr. Application Development ManagerMicrosoft Deutschland GmbH These postings are provided "AS IS" with no warranties, and confer no rights. Use of included code samples are subject to the terms specified at Microsoft - Information on Terms of Use
Wie viele von Ihnen sicherlich schon wissen, möchten wir nach der ECMA Standardisierung, dass Open XML auch ISO Standard wird. Wir glauben, dass kein Format allen Belangen von Anwendern hundertprozentig genügen kann und der Anwender eine Wahl haben soll, ein Format zu verwenden, welches seinen Anforderungen genügt. Einige Bereiche der Wirtschaft erfordern aber Standards, anderenfalls wird eine Technologie nicht einmal in Erwägung gezogen. Standard zu sein bedeutet auch, wirklich alles offenlegen zu müssen. Über die kleinste Änderung muss entschieden werden. So können keine versteckten Details entstehen, an die veilleicht keiner dachte. Das ist im Sinner der Anwender, das wirklich jeder auf dem gleichen Stand ist.
Sind Sie Softwarehersteller (ISV) oder setzen in irgendeiner anderen Form auf Open XML? Und denken Sie, dass Open XML in der Zukunft möglicherweise ein wesentlicher Bestandteil Ihres Geschäfts werden könnte oder gar schon ist? Halten Sie Open XML für wichtig? Dann schauen Sie einmal bei der Open XML Community vorbei und machen Sie mit. Wollen Sie gar Ihre Stimme für Open XML einsetzen (z.B. in einem Brief an das nationale Standardisierungskommitee) oder haben Sie eine coole Lösung und würden daraus eine Case Study machen, dann melden Sie sich bei mir (Blogkontakt).
Open XML ist ein offener Standard für Textverarbeitungs-, Tabellenkalkulations- und Präsentationsdokumente, welcher frei und ohne Lizenzgebühren in jeglicher Anwendung implementiert werden kann. Auf jeder Plattform, jedem Betriebssystem.
Open XML bringt den Anwendern Vorteile, wie:
Viele Firmen haben neben Microsoft schon ihre Unterstützung angekündigt bzw. unterstützen das Format bereits in existierenden Anwendungen (Novell OpenOffice, Corel WordPerfect, PalmOS, etc.).
Wer mit OpenXML zu tun hat, benötigt natürlich auch die entsprechenden Unterlagen, die den Standard beschreiben. Zu finden sind die Unterlagen bei der ECMA unter folgenden Link: OpenXML Standard. Es handelt sich um Dateien im Format OpenXML bzw. PDF. Die eigentliche Formatbeschreibung ist Part 4, welcher mit 5200+ Seiten verdammt lang ist. Ein großer Teil der Dokumentation beschäftigt sich allerdings mit der Rückwärtskompatibilität zu älteren Bestandteilen von Office-Dateien. Wenn Sie reine Office 2007 bzw. OpenXML Dateien erzeugen wollen, so brauchen Sie diese Teile nicht zu berücksichtigen.
Ziel von Microsoft war es, sämtliche Microsoft Office Dokumente in OpenXML abbilden zu können, und zwar möglichst ohne Verluste. Denn was macht es für einen Sinn, wenn Sie zwar neue Dokumente in diesem Format mit Office 2007 erzeugen können, aber Ihre Office Dokumente aus Versionen kleiner als 2007 nach der Konvertierung völlig anders aussehen bzw. gar Teile fehlen würden? Rückwärtskompatibilität ist notwendig, wenn man eine breite installierte Basis hat.
Wohl keiner. Aus diesem Grunde haben sich einige meiner Kollegen hingesetzt und mit Hilfe von WPF eine interaktive Anwendung gebaut, die uns Entwicklern zur Seite steht, wenn es wieder einmal darum geht, die richtige Technologie zu finden. Es geht hier zwar nur (wieso eigentlich nur?) um Office Developer Technologien, aber das ist inzwischen auch sehr weit gefasst, umfasst es doch ebenfalls Windows Server, SQL Server, Datenzugriffstechnologien, Workflow Foundation, ASP.NET, Sharepoint, IIS, Security, Exchange, und, und , und. Sehr cool. Unbedingt ausprobieren. Hier geht's zur WebSeite.
Für alle, die es noch nicht gesehen haben: für FireFox gibt es ein AddOn, mit dem ClickOnce unterstützt wird. Unterstützte Versionen: FireFox 1.5 .. 2.0.
Zum Download
Wie versprochen hier die Beispielcodes aus den WebCasts der OpenXML-Reihe.
Folgende Samples stehen zur Verfügung:
Text aus Word-Datei extrahieren:
Wenn die im Zip-Container enthaltene Datei document.xml in ein XMLDocument geladen ist, können mit einem XPathNavigator alle Paragraph-Elemente des Dokumentes herausgeholt und verarbeitet werden:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable); nsmgr.AddNamespace("w", wordprocessingML);
XPathNavigator nav = xDoc.CreateNavigator(); XPathNodeIterator iter = nav.Select("//w:p", nsmgr);
...
while(iter.MoveNext()) { string s = iter.Current.Value; .. }
Bilder aus Word-Dokument extrahieren:
Ausgehend vom Main Document Part werden innerhalb einer Schleife die Beziehungen herausgeholt, die auf eine Bild-Beziehung hinweisen:
string imageRelationshipType = @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
foreach (PackageRelationship imageRel in docPart.GetRelationshipsByType(imageRelationshipType)) { ... if (imageRel.TargetMode == TargetMode.External) { ... } ... }
Wenn TargetMode = External, dann befindet sich das Bild nicht im Dokument und es muß ermittelt werden, ob die imageUrl "http://" oder "file://" enthält und der entsprechenden Lademechanismus muß gestartet werden:
Image.FromStream(WebRequest.Create(URL).GetResponse().GetResponseStream())
Custom XML Data Store auslesen
Angenommen, der auszulesende Custom XML Part schaut folgendermaßen aus:
<Books xmlns="http://contoso.com/2007/Books"> <Title>OpenXML für Alle</Title> <Author>Dan Appleman</Author> </Books>
Ebenfalls wieder ausgehend von Main Document Part werden die CustomXML Beziehungen ermittelt, der Part geladen und dann am ersten Child-Element die NamespaceUri mit dem Namespace unserer Custom Data Stores verglichen:
customXmlRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
foreach (PackageRelationship customXmlRel in docPart.GetRelationshipsByType(customXmlRelationshipType)) { customXMLUri = PackUriHelper.ResolvePartUri(new Uri(baseUri, UriKind.Relative), customXmlRel.TargetUri); PackagePart customPart = zipPack.GetPart(customXMLUri); XmlDocument xDoc = new XmlDocument(); xDoc.Load(customPart.GetStream(FileMode.Open));
// entspricht gefundener Part dem gesuchten Schema? if (xDoc.FirstChild.NamespaceURI == customBookSchema) { XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable); nsmgr.AddNamespace("ns0", customBookSchema); XmlNode xn = xDoc.SelectSingleNode("ns0:Books/ns0:Title", nsmgr); tbTitle.Text = xn.InnerText; xn = xDoc.SelectSingleNode("ns0:Books/ns0:Author", nsmgr); tbAuthor.Text = xn.InnerText; } }
Word-Datei erzeugen
Zuerst einmal muß die Document.xml erzeugt werden, die den Inhalt des Dokuments (WordML) enthält. Das ist pures XML. Minimal sollte diese so aussehen:
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> <w:body> <w:p> <w:r> <w:t>Beispieltext</w:t> </w:r> </w:p> </w:body> </w:document>
Dann müssen die Content Types und Relationships erzeugt und die Struktur (Document Parts) erstellt werden. Dazu gibt es in System.IO.Packaging entsprechende Klassen:
string mainContentType = @"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
string mainRelationship = @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
ZipPack.CreatePart(mainUri, mainContentType);
zipPack.CreateRelationship(mainUri, TargetMode.Internal, mainRelationship, "rId1");
CreatePart erzeugt nicht nur den DocumentPart, sondern trägt auch den entsprechenden Content Type (2. Parameter) im Container ein.
Excel-Datei erzeugen
Eigentlich ähnlich wie beim Erzeugen von Word-Dateien, nur komplizierter, da Excel-Arbeitsmappen einzelne Tabellenblätter enthalten, die in sich (fast) abgeschlossen sind. Außerdem werden Strings in einer sharedString Table abgelegt und in den Zellen nur verlinkt. Auch sind Zellen i.d.R. dazu da, neben Strings Formeln zu enthalten. Zum Glück kann man Strings auch als sog. Inline Strings, also in den Zellen ablegen. Excel wird diese dann selbsttätig in shared Strings umwandeln.
Erzeugen muß mal also die Workbook.xml, die die Beschreibung der enthaltenen Tabellenblättern enthält:
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <sheets> <sheet name="Sheet1" sheetId="1" r:id="rId1"/> </sheets> </workbook>
Und desweiteren die Worksheet.xml, die den Inhalt der Tabelle enthält:
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> <sheetData> <row r="1"> <c r="A1" t="inlineStr"> <is> <t>Sample Text</t> </is> </c> </row> </sheetData> </worksheet>
Dabei könnte eine Zelle mit Formel so aussehen:
<c r="A1"> <f>A2+A3</f> <v>67</> </c>
Der <v> Tag muß nicht unbedingt vorhanden sein. Er enthält das berechnete Ergebnis der Formel und ist wichtig, wenn selbiger Wert offline, also außerhalb von Excel ausgelesen werden soll. Wenn Excel die Tabelle öffnet und der Value-Tag fehlt oder leer ist, berechnet Excel das Ergebnis neu.
Das Erzeugen dieser Dateien ist ebenfalls wieder reines XML, das Zusammenbauen ein Fall von System.IO.Packaging - CreatePart bzw. CreateRelationship (oder eben entsprechender API befreundeter Technologien, wie Java ;-)).
Für mehr Details einfach mal die Samples ansehen oder bei OpenXMLDevelop.org vorbeischauen.
Microsoft Deutschland hat nun eine zentrale Webseite, um Entwicklern, Partnern und Kunden die Vorteile des neuen Dateiformats, Möglichkeiten und Chancen aufzuzeigen und generelle Informationen zu diesem sehr wichtigen Thema zu kommunizieren: www.msdn-online.de/office/openxml.
Neben Fachartikeln, Events, Trainings und Links gibt es auch Videos zu Entwicklerthemen.