Automatisierte Dokumentenverarbeitung mit Aspose.Words for Python - Erfahrungsbericht
Direkt zu Beginn ein Geständnis: Textverarbeitung mit Maus und Schaltflächen finde ich, na ja, vielleicht nicht grauenhaft, aber etwas in der Art. Schon einige Male in der Vergangenheit habe ich festgestellt, dass ich lieber eine neue Markup-Sprache erlerne (z. B. Markdown und LaTeX) und damit deutlich schneller gewünschte Ergebnisse bekomme als durch Bedienung einer GUI mit einer Maus. Daher war ich mehr als interessiert, als mir in einem Kundenprojekt, in dem es um automatisierte Dokumentenverarbeitung ging, zum ersten Mal Aspose.Words for Python begegnete. Es handelt sich um eine plattformunabhängige Python-Bibliothek, die es möglich macht, DOCX-Dokumente zu verarbeiten und dabei auf andere Produkte (z. B. Microsoft Office) zu verzichten. Durch die Fülle an Möglichkeiten und Werkzeugen und auch durch die angenehme Verwendung hat mir Aspose.Words die Arbeit am Projekt sehr angenehm gemacht und diese Erfahrung möchte ich hier mit Ihnen teilen.
Produktbeschreibung - Was ist Aspose?
Aspose bietet zahlreiche Produkte für die Verarbeitung von verschiedenen Arten von Dokumenten, insbesondere für die Arten, die man aus Microsoft Office kennt. Das Produkt Aspose.Words, mit dem ich am meisten im Projekt zu tun hatte, dient zur Arbeit mit DOCX-Dokumenten, außerdem gibt es Aspose.Cells und Aspose.Slides, die entsprechend für Excel- und PowerPoint-Dokumente entwickelt wurden, Aspose.PDF und Aspose.Imaging und noch einige weitere. Aspose.Total bietet schließlich die gesamte Aspose-Produktfamilie am Stück.
Die Bibliotheken gibt es nicht nur für Python, sondern auch für Java, C++ und andere Programmiersprachen, das variiert von Bibliothek zu Bibliothek.
Um die Funktionalität vollständig nutzen zu können, ist eine kostenpflichtige Lizenz notwendig. Es ist möglich sowohl für einzelne Aspose-Produkte Lizenzen zu erwerben als auch direkt für das Gesamtpaket Aspose.Total. Eine Demo-Version zum Ausprobieren der Features steht kostenfrei zur Verfügung.
Was ich verwendet habe - Aspose.Words for Python via .NET
Im Projekt habe ich zu 99 % mit Python und der entsprechenden Bibliothek Aspose.Words for Python via .NET gearbeitet. Dies ist eine plattformunabhängige Bibliothek, sie kann also unter anderem zur Entwicklung von Applikationen auf Windows und auch Linux genutzt werden. Auf Microsoft Office können wir vollkommen verzichten sowie auf andere Produkte von Drittanbietern. Die Funktionalität von Aspose.Words bietet im Grunde alles, was wir in Microsoft Word mit Tastatur und Maus erreichen würden. Dokumente können erstellt oder geöffnet, geändert und gespeichert werden. Dabei kann Aspose.Words diverse Dokumentformate von und zu DOCX konvertieren, wie z. B. PDF, HTML und Markdown. Die ausführliche Dokumentation mit zahlreichen detaillierten Code-Beispielen unterstützt dabei ungemein. Die Verarbeitung passiert schnell: Laut Homepage lassen sich Tausende von Dokumenten innerhalb von Minuten fertigstellen. Zur Nutzung wird eine Python-Version ab 3.6 benötigt. Die Bibliothek kann am einfachsten via pip installiert werden.
Hello Aspose! - unser erstes Dokument
Traditionell beginnen wir mit einem einfachen Beispiel. Ein Dokument mit dem Inhalt "Hello World!" ist in wenigen Zeilen erstellt:
import aspose.words as aw # Dokument erstellen doc = aw.Document() # virtuellen Cursor initialisieren, dieser befindet sich automatisch # am Anfang des Dokuments builder = aw.DocumentBuilder(doc) # Text ins Dokument schreiben builder.writeln("Hello World!") # Dokument speichern doc.save("HelloAspose.docx")
Die wichtigsten Akteure, die uns hier begegnen und die uns im gesamten Entwicklungsprozess begleiten, sind die Klassen Document
und DocumentBuilder
. Diese wollen wir nun etwas näher kennenlernen.
Dokument als Baum - das DOM von Aspose.Words
Das DOM (Document Object Model) in Aspose.Words ist die In-Memory-Repräsentation eines Word-Dokuments. Das Dokument wird als Objekt-Baum interpretiert, die Objekte können ihrerseits selbst Bäume sein.
Beispielsweise hat ein Dokument (Document
) mindestens einen Abschnitt (Section
), dieser hat genau einen Body (Body
), welcher mehrere Absätze (Paragraph
) beinhalten kann (und mindestens einen beinhalten muss). Eine Tabelle (Table
) hat Zeilen (Row
), diese besitzen Zellen (Cell
), welche wiederum mehrere Absätze haben können.
Als Beispiel habe ich einen Knotenbaum zu einem Dokument mit einer Tabelle erstellt:
Einzelne Objekte heißen Knoten (Node
) und können zueinander verschiedene Beziehungen haben (parent
, child
oder sibling
) - je nachdem, wo sie sich im Dokument-Baum befinden. Wir bearbeiten das Dokument, indem wir von Knoten zu Knoten gehen, um deren Inhalt zu sehen oder zu ändern. Oder wir manipulieren den Baum, indem wir Knoten hinzufügen, verschieben oder entfernen.
Zum Beispiel können wir ein „HelloWorld"-Dokument allein durch Knotenoperationen erstellen:
import aspose.words as aw # Dokument erstellen doc = aw.Document() # Knoten mit neuem Text erstellen hello_world = aw.Run(doc, "Hello World!") # den Knoten in den Dokumentbaum einfügen doc.first_section.body.first_paragraph.runs.add(hello_world) # Dokument speichern doc.save("HelloAsposeWithoutBuilder.docx")
Um jedoch das Dokument ausschließlich durch DOM-Operationen zu verarbeiten, ist ein gutes Verständnis der Baumstruktur notwendig. Ein nützlicher Assistent ist der DocumentBuilder.
DocumentBuilder - Wer braucht schon die Maus?
Der DocumentBuilder führt uns durch das Dokument, er stellt einen virtuellen Cursor dar. Um das Dokument mit seiner Hilfe zu bearbeiten, navigieren wir den DocumentBuilder zu den entsprechenden Knoten und rufen Funktionen auf, welche die beabsichtigten Operationen durchführen. Wir erhalten Informationen (Inhalte und Formatierungen zum Beispiel), schreiben oder ändern den Text (wiederum sowohl den Inhalt als auch die Formatierung), erstellen neue Knoten (beispielsweise Kopf- und Fußzeilen oder Tabellen) oder entfernen welche.
import aspose.words as aw # vorhandenes Dokument öffnen doc = aw.Document("HelloAspose.docx") # virtuellen Cursor initialisieren, dieser befindet sich automatisch # am Anfang des Dokuments builder = aw.DocumentBuilder(doc) # den Cursor zum Ende des Dokuments schicken builder.move_to_document_end() # Schrift an dieser Stelle auf Fett setzen builder.font.bold = True # Text ins Dokument schreiben builder.write("This is the end of the document.") # eine horizontale Linie einfügen, dadurch entsteht # ein neuer Absatz builder.insert_horizontal_rule() # den Cursor zum vorletzten Absatz schicken builder.move_to_paragraph(-2, 0) # nun im Text eine Änderung durchführen builder.current_paragraph.range.replace(" is ", " was ") # Dokument speichern doc.save("HelloBuilder.docx")
Eine unschlagbare Kombination - DOM und DocumentBuilder Hand in Hand
Die Dokumentation zu Aspose.Words besagt, dass die Verarbeitung eines Dokuments vollständig durch Knotenoperationen oder durch die Bedienung des DocumentBuilders geschehen kann, sprich, wir können uns auf eine Methodik festlegen und erreichen letztendlich dieselben Ergebnisse. In den Code-Beispielen der Dokumentation spielt der DocumentBuilder eine zentrale Rolle, die Beispiele zu Knotenoperationen kommen deutlich seltener vor.
In meinem Projekt habe ich jedoch sowohl DOM-Operationen als auch DocumentBuilder-Funktionen genutzt, wobei ich den Fokus auf die Knotenoperationen gelegt habe und der Builder bei mir eher selten zum Einsatz kam.
Niemand ist perfekt - Schwierigkeiten und Herausforderungen
Bei der Nutzung von Aspose.Words habe ich sehr vieles analysiert und ausprobiert, da einige Operationen nicht das erwartete Resultat brachten.
Wird zum Beispiel eine Tabelle um Zellen erweitert, haben die neuen Zellen nicht die Formatierung der restlichen Tabelle, sondern die Standardformatierung. Ich musste mich also nachträglich darum kümmern, die Formatierung auf neue Zellen zu übertragen.
Außerdem habe ich festgestellt, dass sich der Dokument-Baum beim Speichern des Dokuments verändern kann. Ein gespeichertes Dokument hat also unter Umständen eine andere Baumstruktur als vor dem Speichern.
Ein interessanter Effekt ist bei mir aufgetreten, als ich Textstellen kopiert und wieder eingefügt habe: Dabei ist ein Leerzeichen im eingefügten Text erschienen, welches an dieser Stelle überhaupt nicht erwünscht war. Eine zusätzliche Herausforderung war es, die Formatierung des kopierten Textes zu übernehmen. Das hat einige Bearbeitungsschritte abverlangt.
Aufmerksames Lesen der Dokumentation und Nachbauen der Beispiele hat mich an vielen Stellen weitergebracht, jedoch musste ich feststellen, dass einige Codebeispiele fehlerhaft bzw. veraltet waren und nicht funktionierten.
Wenn ich explizit die Arbeitsweise von Aspose.Words mit der manuellen Verarbeitung eines Microsoft Word-Dokuments vergleiche, merke ich, dass die GUI doch einige Schalter mit Funktionalität zur Verfügung stellt, die ich in Aspose.Words nicht in dieser Form gefunden habe. Der Befehl "Split Table" bewirkt im Microsoft Word, dass die Tabelle (in welcher sich der Cursor gerade befindet) in zwei Tabellen aufgeteilt wird. Die Zeile, in welcher der Cursor gerade ist, wird automatisch die erste Zeile der neuen Tabelle. Ist der Cursor bereits in der ersten Zeile der Tabelle, so erscheint durch "Split Table" eine Leerzeile vor der besagten Tabelle. Dafür muss man nur auf den entsprechenden Schalter klicken, beziehungsweise im Makro den Befehl "Table.Split" nutzen. In Aspose.Words scheint es dazu keine Funktion zu geben. In der Dokumentation steht, dass die Tabelle für die Aufteilung in ihre Bestandteile zerlegt und zwei Tabellen daraus gebaut werden müssen, um den Effekt zu erzielen.
Fazit - Aspose.Words hat nun einen Fan mehr
Trotz einiger Schwierigkeiten in der Umsetzung gewisser Funktionalitäten gab es keine Verarbeitungsschritte, die ich nicht implementieren konnte. Das Ergebnis erfüllte alle Anforderungen und das Projekt war ein Erfolg.
Aspose.Words hat mich durch den Umfang an Möglichkeiten, die detaillierte Dokumentation mit vielen Code-Beispielen und eine größtenteils intuitive Bedienung überzeugt. Ist die Baumstruktur eines Dokuments erstmal verstanden, besteht die restliche Arbeit im Nachlesen und Ausprobieren zur Verfügung gestellter Informationen. Das Vorankommen ist flüssig, die Ergebnisse schnell sichtbar. Grundlagenkenntnisse von Python und objektorientierter Programmierung sind ausreichend, um mit der Bibliothek zurechtzukommen. In diesem Artikel habe ich nur die Oberfläche an Möglichkeiten von Aspose.Words gestreift. Von der Verschlüsselung der Dokumente über das Erstellen von verschachtelten Listen bis hin zur Nutzung von benutzerdefinierten Variablen, ist eine Menge an Funktionalität vertreten. Durch die im Projekt gesammelten Erfahrungen bin ich nun um einen Werkzeugkasten reicher und möchte die Demo-Version von Aspose.Words demnächst auch für einen privaten Zweck nutzen.
Und ganz nebenbei: Diesen Blogartikel habe ich komplett mit Aspose.Words geschrieben.
Seminarempfehlung
PYTHON PROGRAMMIERUNG GRUNDLAGEN P-PYTH-01
ZUM SEMINARConsultant bei ORDIX
Bei Updates im Blog, informieren wir per E-Mail.
Kommentare