9.2Dokumentenformate
Ein Dokumentenformat ist entweder textuell oder binär und beschreibt Textdokumente. Das Dokumentenformat kann selbst Text sein (wie HTML oder TeX) oder binär sein (wie DOC für Word-Dokumente).
ASCII- bzw. UTF-8-kodierte Texte bilden die einfachste Form. Ihnen ist mit Dateiströmen leicht beizukommen. Das XML-Format wurde im vorangegangenen Kapitel schon ausführlich vorgestellt – widmen wir uns anderen Dokumentenformaten.
9.2.1(X)HTML
Ein Webbrowser bezieht (X)HTML-Seiten aus dem Internet und stellt sie dar. Doch ist (X)HTML nicht nur dort das Standardformat, sondern auch an anderen Stellen anzutreffen, etwa bei den Hilfeseiten von Eclipse oder bei Büchern, die ein Lesegerät wie der Amazon-Kindle darstellt. Sind die HTML-Dokumente als XHTML-Dokumente geschrieben, so lassen sie sich auch einfach einlesen, nämlich über die bekannten XML-Technologien. Und läge dann ein HTML-Dokument als DOM-Baum vor, so hätte das den Vorteil, dass sich das HTML-Dokument einfach untersuchen – etwa mit XPath – oder leicht konvertieren ließe. Beim Schreiben ist es genauso: Ein DOM-Baum mit XHTML ist leicht geschrieben, genauso wie ein StAX-Writer schnell einen XHTML-Strom generiert.
Das Problem dabei ist nur, dass HTML-Dokumente oft nicht XML-konform sind (oder direkt validiertes XHTML sind), also Fehler enthalten. Beim Einlesen von nichtvaliden HTML-Dokumenten würde der strenge XML-Parser Fehler melden und abbrechen. Ein einfaches Erfragen mit XPath ist dann nicht mehr möglich.
JTidy
Für HTML-Dokumente, die nicht ganz XML-rein sind, gibt es mit JTidy (http://jtidy.sourceforge.net/) eine freie Bibliothek, die HTML-Dokumente einliest, Fehler (so weit wie möglich) korrigiert und das XML-Dokument als ordentlichen DOM-Baum repräsentiert. Die Benutzung ist einfach:
// tidy.setMakeClean( true ); // Ohne Störungen
// tidy.setXmlTags( true ); // Eingabe als XML behandeln
org.w3c.dom.Document node = tidy.parseDOM( in, null );
in steht für einen InputStream, der die Daten bereitstellt. Neben parseDOM(…), das ein org.w3c.dom.Document liefert, gibt es auch parse(…), das das Wurzelelement als org.w3c.tidy.Node liefert. Der zweite Parameter von parseDOM(…) – in unserem Beispiel mit null belegt – steht für ein Ausgabe-Objekt. Wird auf dem Tidy-Objekt die Methode parseXXX(in, out) aufgerufen, so schreibt JTidy einen korrekten XML-Strom in das gegebene OutputStream-Objekt. Unter http://jtidy.sourceforge.net/apidocs/index.html ist die API-Dokumentation verfügbar. Die Lizenz von JTidy ist zwar keine übliche, wie GPL oder Apache, aber trotzdem lässt sich die Bibliothek frei verwenden.
CyberNeko HTML Parser
In einigen Fällen zickt auch JTidy und bricht mit vielen Meldungen ab. Für diesen Fall bietet sich eine Alternative an: der CyberNeko HTML Parser (http://tutego.de/go/nekohtml).
org.cyberneko.html.parsers.DOMParser parser = new org.cyberneko.html.parsers.DOMParser();
parser.parse( new InputSource(in) );
Um das XML-Dokument als JDOM-Document weiterzuverarbeiten, nutzen wir einen DOMBuilder:
org.jdom.Document document = builder.build( parser.getDocument() );
HtmlCleaner
Der HtmlCleaner (http://htmlcleaner.sourceforge.net/) ist eine Bibliothek unter der BSD-Lizenz, die mit Zeilen wie den folgenden eine Eingabe in einen String, Ausgabestrom oder DOM-Baum überträgt:
String s = cleaner.getCompactXmlAsString();
cleaner.writeXmlToStream( outputStream );
org.w3c.dom.Document dom1 = cleaner.createDOM();
org.jdom.Document dom2 = cleaner.createJDom();
Der HtmlCleaner kommt zusätzlich mit einem Kommandozeilenprogramm und Ant-Task daher.
9.2.2PDF-Dokumente
Der PDF-Standard ist ein offener Standard, der gut beschrieben ist und für den es unterschiedliche Generatoren und Tools zum Editieren gibt. In Java hat die Open-Source-Bibliothek iText (http://itextpdf.com/) einen guten Ruf, um PDF-Dokumente zu erzeugen, sie zu verschmelzen oder PDF-Formulare zu füllen. Selbst ein Buch gibt es zu iText, und die Bibliothek wurde wegen ihres Erfolges nach .NET portiert. Leider hat iText die Lizenz auf GPL gewechselt und kann somit nicht mehr ohne Lizenzgebühren in geschlossenen Projekten verwendet werden. Bis Version 2.1.7 stand es unter der liberalen MPL, seit 5.x nicht mehr – es gab keine 3er- und 4er-Version dazwischen.
Eine weitere PDF-Bibliothek ist Apache PDFBox (http://pdfbox.apache.org/) mit einem etwas anderen Fokus. Die Stärke von iText ist eher das Erstellen von PDF-Dokumenten nach den neusten PDF-Standards, und die PDFBox kann gut Texte extrahieren und Dokumente modifizieren.
9.2.3Microsoft Office-Dokumente
Auch wenn sich die Welt nach freien und quelloffenen Lösungen sehnt, Microsoft Office ist immer noch eines der bestverkauften Produkte auf diesem Planeten – mit dem MS-Dokumentenformat als Sonne im Mittepunkt. Da die Dokumentation von Microsofts Dateiformaten mittlerweile zugänglich[ 89 ](http://www.microsoft.com/interop/docs/officebinaryformats.mspx) ist, gibt es auch Java-Bibliotheken, die MS-Office-Dokumente einlesen, modifizieren und schreiben. Bekannt dafür ist Apache POI [ 90 ](POI steht für Poor Obfuscation Implementation, weil das Dateiformat so kryptisch ist. Die Kürzel der Komponenten beginnen in der Regel mit »H« was für »Horrible« steht.) (http://poi.apache.org/), das APIs für folgende Formate (Komponenten genannt) bietet:
POI-Komponente | Aufgabe | Grad der Unterstützung |
---|---|---|
HSSF, XSSF | gut | |
HSLF, XSLF | befriedigend | |
HWPF, XWPF | befriedigend | |
HDGF | Visio VSD | rudimentär, nur lesen |
HPBF | Publisher PUB | rudimentär, nur lesen |
HMEF/HSMF | Outlook MSG/Microsoft TNEF (Transport Neutral Encoding Format) | rudimentär, nur lesen |
OpenXML4J | Open Packaging Conventions (OPC)/OOXML | gut |
POIFS | OLE 2 Compound Document (OLE2 Filesystem) | sehr gut |
HPSF | OLE2 Property Sets | sehr gut |
Tabelle 9.1POI-Komponenten nach http://poi.apache.org/overview.html#components
OpenXML4J und POIFS sind keine üblichen Dokumentenformate, aber Archivformate für Microsoft-Dokumente (analog zu ZIP). HPSF erlaubt den Zugriff auf Datei-Metadaten wie Autor, Titel usw.
Neben POI gibt es nicht mehr so viele Alternativen, eher kleinere Bibliotheken, die sich auf ein Format spezialisiert haben. So gibt es etwa Java Excel API (http://jexcelapi.sourceforge.net/) für Excel, das eine sehr einfache und intuitive API hat, aber beim Lesen oft Probleme bereitet. Nur wurde es bisher seit 2 Jahren nicht mehr aktualisiert. Eine kommerzielle und gute Lösung bieten die Aspose.Total for Java (http://tutego.de/go/apose). Der Vorteil jeder gekauften Lösung ist, dass damit auch gleich Support enthalten ist, und die Java-Bibliothek von Aspose hat einen guten Ruf. Die Bibliotheken gibt es auch für .NET.
Für den Zugriff auf MS-Access-Datenbanken gibt es die quelloffene Bibliothek Jackcess (http://jackcess.sourceforge.net/), die auch eine sehr aktuelle Fluent-API hat. Auf MS Access lässt sich seit Java 8 nicht mehr automatisch per ODBC zurückgreifen, weil kein JDBC-ODBC-Treiber mehr zum JDK gehört.
Office Open XML und DOCX, XLSX, PPTX
Das Format Office Open XML definiert ein Dokumentenformat für Microsoft-Office-Dokumente. Im Grunde sind es XML-Dokumente und Ressourcen in ZIP-Archiven. Solche Dokumente sind deutlich einfacher zu verarbeiten als das binäre Format, und es wäre auch mit Bordmitteln möglich, denn Java kann ZIP-Archive und auch XML-Dokumente problemlos auslesen. Doch gibt es einige Bibliotheken, die hier helfen. Zum Beispiel zählt Apache POI wieder dazu und noch einige andere Projekte, etwa das relativ neue Projekt java2word (http://github.com/leonardoanalista/java2word) und docx4j (http://www.docx4java.org/), die über JAXB die ganze XML-Dokumentenstruktur nachstellen. Um DOCX-Objekte wie Vorlagen zu verwenden und automatisch zu füllen gibt es das feine quelloffene XDocReport (http://code.google.com/p/xdocreport/).
9.2.4OASIS Open Document Format
Neben Office Open XML gibt es das OASIS Open Document Format – mit Dateiformaten wie OpenDocument (ODF) für Textdokumente, die etwa von OpenOffice verarbeitet werden. Eine Bibliothek zum Verarbeiten bietet das ODF Toolkit (http://odftoolkit.org/). OpenOffice kann auch mit einer so genannten UNO-Brücke gesteuert werden, doch das ist extrem ressourcenlastig, denn OpenOffice läuft dann komplett im Hintergrund. Das bietet aber zumindest die Möglichkeit, Dokumente in PDF zu konvertieren. Eine andere quelloffene Bibliothek ist jOpenDocument (http://jopendocument.org/) vom französischen Unternehmen ILM Informatique. jOpenDocument kann Texte und Tabellen lesen, modifizieren und schreiben sowie grafisch in einem Swing-Fenster darstellen. Allerdings steht die Bibliothek unter der GPL, was bedeutet, dass für den kommerziellen Einsatz mit geschlossenen Quellen eine Lizenzgebühr zu entrichten ist. Updates sind in letzter Zeit etwas unregelmäßiger geworden.