So erstellen Sie ein PDF aus Ihrer Webanwendung
Veröffentlicht: 2022-03-10Viele Webanwendungen haben die Anforderung, dem Benutzer die Möglichkeit zu geben, etwas im PDF-Format herunterzuladen. Bei Anwendungen (z. B. E-Commerce-Shops) müssen diese PDFs mit dynamischen Daten erstellt werden und dem Benutzer sofort zur Verfügung stehen.
In diesem Artikel werde ich Möglichkeiten untersuchen, wie wir eine PDF-Datei direkt aus einer Webanwendung im laufenden Betrieb generieren können. Es ist keine umfassende Liste von Werkzeugen, sondern ich möchte stattdessen die verschiedenen Ansätze demonstrieren. Wenn Sie ein Lieblingstool oder eigene Erfahrungen haben, die Sie teilen möchten, fügen Sie sie bitte den Kommentaren unten hinzu.
Beginnend mit HTML und CSS
Unsere Webanwendung erstellt wahrscheinlich bereits ein HTML-Dokument mit den Informationen, die unserem PDF hinzugefügt werden. Im Falle einer Rechnung kann der Benutzer die Informationen möglicherweise online anzeigen und dann klicken, um eine PDF-Datei für seine Unterlagen herunterzuladen. Möglicherweise erstellen Sie Lieferscheine; Auch hier sind die Informationen bereits im System gespeichert. Sie möchten das zum Herunterladen und Drucken auf eine schöne Weise formatieren. Daher wäre es ein guter Anfang zu überlegen, ob es möglich ist, dieses HTML und CSS zu verwenden, um eine PDF-Version zu generieren.
CSS hat eine Spezifikation, die sich mit CSS für den Druck befasst, und dies ist das Paged Media-Modul. Ich habe einen Überblick über diese Spezifikation in meinem Artikel „Gestalten für den Druck mit CSS“, und CSS wird von vielen Buchverlagen für ihre gesamte Druckausgabe verwendet. Da CSS selbst Spezifikationen für gedruckte Materialien hat, sollten wir es also doch verwenden können?
Der einfachste Weg, wie ein Benutzer ein PDF generieren kann, ist über seinen Browser. Wenn Sie sich für den Druck im PDF-Format anstelle eines Druckers entscheiden, wird ein PDF generiert. Leider ist dieses PDF meist nicht ganz zufriedenstellend! Zunächst enthält es die Kopf- und Fußzeilen, die automatisch hinzugefügt werden, wenn Sie etwas von einer Webseite drucken. Es wird auch gemäß Ihrem Druck-Stylesheet formatiert – vorausgesetzt, Sie haben eines.
Das Problem, auf das wir hier stoßen, ist die schlechte Unterstützung der Fragmentierungsspezifikation in Browsern; Dies kann bedeuten, dass der Inhalt Ihrer Seiten auf ungewöhnliche Weise unterbrochen wird. Die Unterstützung für Fragmentierung ist lückenhaft, wie ich entdeckte, als ich meinen Artikel „Breaking Boxes With CSS Fragmentation“ recherchierte. Dies bedeutet, dass Sie möglicherweise nicht in der Lage sind, ein suboptimales Umbrechen von Inhalten zu verhindern, wobei Kopfzeilen als letztes Element auf der Seite verbleiben und so weiter.
Außerdem haben wir keine Möglichkeit, den Inhalt in den Seitenrandfeldern zu steuern, z. B. das Hinzufügen einer Kopfzeile unserer Wahl zu jeder Seite oder die Seitennummerierung, um anzuzeigen, wie viele Seiten eine komplexe Rechnung hat. Diese Dinge sind Teil der Paged Media-Spezifikation, wurden jedoch in keinem Browser implementiert.
Mein Artikel „Ein Leitfaden zum Stand von Druck-Stylesheets im Jahr 2018“ ist immer noch genau in Bezug auf die Art der Unterstützung, die Browser für das Drucken direkt aus dem Browser unter Verwendung eines Druck-Stylesheets haben.
Drucken mit Browser-Rendering-Engines
Es gibt Möglichkeiten, mithilfe von Browser-Rendering-Engines in PDF zu drucken, ohne das Druckmenü im Browser zu durchlaufen und Kopf- und Fußzeilen zu erhalten, als ob Sie das Dokument gedruckt hätten. Die beliebtesten Optionen als Antwort auf meinen Tweet waren wkhtmltopdf und das Drucken mit Headless Chrome und Puppeteer.
wkhtmltopdf
Eine Lösung, die auf Twitter mehrfach erwähnt wurde, ist ein Kommandozeilentool namens wkhtmltopdf. Dieses Tool nimmt eine HTML-Datei oder mehrere Dateien zusammen mit einem Stylesheet und wandelt sie in ein PDF um. Dazu wird die WebKit-Rendering-Engine verwendet.
Wir verwenden wkhtmltopdf. Es ist nicht perfekt, obwohl das wahrscheinlich ein Benutzerfehler war, aber gut genug für eine Produktionsanwendung.
– Paul Cardno (@pcardno) 15. Februar 2019
Dieses Tool macht also im Wesentlichen dasselbe wie das Drucken aus dem Browser, Sie erhalten jedoch nicht die automatisch hinzugefügten Kopf- und Fußzeilen. Auf dieser positiven Seite, wenn Sie ein funktionierendes Druck-Stylesheet für Ihre Inhalte haben, sollte es mit diesem Tool auch gut als PDF ausgegeben werden, und so kann ein einfaches Layout sehr gut gedruckt werden.
Leider werden Sie jedoch immer noch auf die gleichen Probleme stoßen wie beim direkten Drucken aus dem Webbrowser, was die fehlende Unterstützung der Paged Media-Spezifikation und der Fragmentierungseigenschaften betrifft, da Sie immer noch mit einer Browser-Rendering-Engine drucken. Es gibt einige Flags, die Sie an wkhtmltopdf übergeben können, um einige der fehlenden Funktionen wieder hinzuzufügen, die Sie standardmäßig mit der Paged Media-Spezifikation hätten. Dies erfordert jedoch einige zusätzliche Arbeit zusätzlich zum Schreiben von gutem HTML und CSS.
Headless-Chrome
Eine weitere interessante Möglichkeit ist die Verwendung von Headless Chrome und Puppeteer zum Drucken in PDF.
Puppenspieler. Dafür ist es erstaunlich.
– Alex Russell (@slightlylate) 15. Februar 2019
Sie sind jedoch erneut durch die Browserunterstützung für ausgelagerte Medien und Fragmentierung eingeschränkt. Es gibt einige Optionen, die an die Funktion page.pdf()
werden können. Wie bei wkhtmltopdf fügen diese einige der Funktionalitäten hinzu, die mit CSS möglich wären, falls Browserunterstützung vorhanden wäre.
Es kann gut sein, dass eine dieser Lösungen alles tut, was Sie brauchen, aber wenn Sie feststellen, dass Sie einen Kampf führen, ist es wahrscheinlich, dass Sie an die Grenzen dessen stoßen, was mit aktuellen Browser-Rendering-Engines möglich ist, und muss nach einer besseren Lösung suchen.
JavaScript Polyfills für ausgelagerte Medien
Es gibt einige Versuche, die Paged Media-Spezifikation im Browser mithilfe von JavaScript im Wesentlichen zu reproduzieren – im Wesentlichen ein Paged Media Polyfill zu erstellen. Dies könnte Ihnen Paged Media-Unterstützung bei der Verwendung von Puppeteer geben. Sehen Sie sich paged.js und Vivliostyle an.
Jawohl. Für einfache Dokumente wie Kurszertifikate können wir Chrome verwenden, das nur eine minimale Unterstützung für @-Seiten bietet. Für alles andere verwenden wir PrinceXML oder das paged.js-Polyfill in Chrome. Hier ist ein WIP-Proof-of-Concept mit paged.js für Bücher: https://t.co/AZ9fO94PT2
– Electric Book Works (@electricbook) 15. Februar 2019
Verwenden eines Druckbenutzeragenten
Wenn Sie bei einer HTML- und CSS-Lösung bleiben möchten, müssen Sie sich nach einem User Agent (UA) umsehen, der zum Drucken aus HTML und CSS entwickelt wurde und über eine API zum Generieren des PDF aus Ihren Dateien verfügt. Diese Benutzeragenten implementieren die Paged Media-Spezifikation und bieten weitaus bessere Unterstützung für die CSS-Fragmentierungseigenschaften; Dadurch erhalten Sie eine bessere Kontrolle über die Ausgabe. Zu den führenden Optionen gehören:
- Prinz
- Antennenhaus
- PDFReactor
Ein Print-UA formatiert Dokumente mit CSS – genau wie ein Webbrowser. Wie bei der Browserunterstützung für CSS müssen Sie die Dokumentation dieser UAs überprüfen, um herauszufinden, was sie unterstützen. Zum Beispiel unterstützt Prince (mit dem ich am besten vertraut bin) zum Zeitpunkt des Schreibens Flexbox, aber kein CSS-Grid-Layout. Wenn Sie Ihre Seiten an das von Ihnen verwendete Tool senden, erfolgt dies normalerweise mit einem bestimmten Stylesheet für den Druck. Wie bei einem normalen Druck-Stylesheet sind die CSS, die Sie auf Ihrer Website verwenden, nicht alle für die PDF-Version geeignet.
Das Erstellen eines Stylesheets für diese Tools ist dem Erstellen eines regulären Druck-Stylesheets sehr ähnlich, bei dem Entscheidungen getroffen werden, was angezeigt oder ausgeblendet werden soll, möglicherweise mit einer anderen Schriftgröße oder Farbe. Sie können dann die Funktionen der Paged Media-Spezifikation nutzen und Fußnoten, Seitenzahlen usw. hinzufügen.
Wenn Sie diese Tools von Ihrer Webanwendung aus verwenden möchten, müssen Sie sie auf Ihrem Server installieren (natürlich nachdem Sie eine Lizenz dafür gekauft haben). Das Hauptproblem bei diesen Tools ist, dass sie teuer sind. Angesichts der Leichtigkeit, mit der Sie dann gedruckte Dokumente damit erstellen können, können sie sich jedoch durch die eingesparte Entwicklerzeit bezahlt machen.
Es ist möglich, Prince über eine API auf Pay-per-Document-Basis über einen Dienst namens DocRaptor zu nutzen. Dies wäre sicherlich ein guter Startpunkt für viele Anwendungen, da es so aussieht, als ob es kostengünstiger wäre, Ihre eigenen zu hosten, da die Entwicklungskosten für einen Wechsel minimal wären.
Eine kostenlose Alternative, die nicht ganz so umfassend ist wie die oben genannten Tools, aber durchaus die gewünschten Ergebnisse erzielen kann, ist WeasyPrint. Es implementiert nicht alle Paged Media vollständig, aber es implementiert mehr als eine Browser-Engine. Unbedingt ausprobieren!
Andere Tools, die behaupten, die Konvertierung von HTML und CSS zu unterstützen, sind PDFCrowd, das kühn behauptet, HTML5, CSS3 und JavaScript zu unterstützen. Ich konnte jedoch keine Details darüber finden, was genau unterstützt wurde und ob dies in der Paged Media-Spezifikation der Fall war. In den Antworten auf meinen Tweet wurde mPDF ebenfalls erwähnt.
Abkehr von HTML und CSS
Es gibt eine Reihe anderer Lösungen, die von der Verwendung von HTML und CSS weggehen und erfordern, dass Sie eine spezifische Ausgabe für das Tool erstellen. Einige JavaScript-Anwärter sind wie folgt:
- jsPDF
- pdfmake
Headless Browser + Speichern in PDF war einst meine erste Wahl, führte aber immer zu unterdurchschnittlichen Ergebnissen für alles andere als ein einseitiges Dokument. Wir haben für mehrseitige Berichte auf https://t.co/3o8Ce23F1t umgestellt, was viel mehr Aufwand gekostet hat, sich aber am Ende gelohnt hat!
– JimmyJoy (@jimle_uk) 15. Februar 2019
Empfehlungen
Abgesehen von den JavaScript-basierten Ansätzen, bei denen Sie eine völlig andere Darstellung Ihrer Inhalte für den Druck erstellen müssten, besteht das Schöne an vielen dieser Lösungen darin, dass sie austauschbar sind. Wenn Ihre Lösung darauf basiert, ein Befehlszeilentool aufzurufen und diesem Tool Ihr HTML, CSS und möglicherweise etwas JavaScript zu übergeben, ist es ziemlich einfach, zwischen den Tools zu wechseln.
Beim Schreiben dieses Artikels habe ich auch einen Python-Wrapper entdeckt, der eine Reihe verschiedener Tools ausführen kann. (Beachten Sie, dass Sie die Tools selbst bereits installiert haben müssen, dies könnte jedoch eine gute Möglichkeit sein, die verschiedenen Tools an einem Beispieldokument zu testen.)
Für die Unterstützung von Paged Media und Fragmentierung werden Prince, Antenna House und PDFReactor die Nase vorn haben. Als kommerzielle Produkte werden sie auch mit Support geliefert. Wenn Sie ein Budget haben, komplexe Seiten zum Drucken in PDF haben und Ihre Entwicklerzeit begrenzt ist, dann werden Sie höchstwahrscheinlich feststellen, dass dies der schnellste Weg ist, damit Ihre PDF-Erstellung gut funktioniert.
In vielen Fällen werden die kostenlosen Tools jedoch gut für Sie funktionieren. Wenn Ihre Anforderungen sehr einfach sind, kann wkhtmltopdf oder eine einfache kopflose Chrome- und Puppeteer-Lösung ausreichen. Es schien sicherlich für viele der Leute zu funktionieren, die auf meinen ursprünglichen Tweet geantwortet haben.
Wenn Sie Schwierigkeiten haben, die gewünschte Ausgabe zu erhalten, sollten Sie sich jedoch bewusst sein, dass dies möglicherweise eine Einschränkung des Browserdrucks ist und nichts, was Sie falsch machen. Falls Sie mehr Unterstützung für Paged Media wünschen, aber nicht in der Lage sind, sich für ein kommerzielles Produkt zu entscheiden, schauen Sie sich vielleicht WeasyPrint an.
Ich hoffe, dies ist eine nützliche Zusammenfassung der verfügbaren Tools zum Erstellen von PDFs aus Ihrer Webanwendung. Nicht zuletzt zeigt es, dass es eine große Auswahl an Möglichkeiten gibt, wenn Ihre ursprüngliche Wahl nicht gut funktioniert.
Bitte fügen Sie Ihre eigenen Erfahrungen und Vorschläge in den Kommentaren hinzu, dies ist eines der Dinge, mit denen sich viele von uns beschäftigen, und der Austausch persönlicher Erfahrungen kann unglaublich hilfreich sein.
Weiterführende Lektüre
Eine Zusammenfassung der verschiedenen Ressourcen und Tools, die in diesem Artikel erwähnt werden, zusammen mit einigen anderen nützlichen Ressourcen für die Arbeit mit PDF-Dateien aus Webanwendungen.
Spezifikationen
- Ausgelagertes Medienmodul
- Zersplitterung
Artikel und Ressourcen
- Druckdesign mit CSS
- Breaking Boxes mit CSS-Fragmentierung
- Ein Leitfaden zum Stand der Druckvorlagen im Jahr 2018
- Erste Schritte mit Headless Chrome und Puppeteer
- print-css.rocks
Werkzeuge
- wkhtmltopdf
- paged.js
- Vivliostyle
- Prinz
- Antennenhaus
- PDFReactor
- DocRaptor
- WeasyPrint
- PDFCrowd
- mPDF
- jsPDF
- pdfmake
- Produce & Publish-Server