CosmoCode
  • Great software.

  • Bright people.

  • Happy customers!

CosmoCode GmbH
  • Start
  • Geschäftsfelder
  • Über uns
  • Referenzen
  • Blog
  • Open Source
←
Alle Blogposts
→

Webseiten als PDF exportieren

Die Möglichkeit, Internetinhalte auch als PDF zur Verfügung zu stellen, gehört zu den typischen Aufgabenstellungen bei der Implementation von Websites. Was konzeptionell sich so naheliegend anhört (“Der Inhalt ist doch schon da!”) ist leider technisch häufig eine größere Herausforderung. Denn die Techniken von (HTML-)Web und PDF sind grundverschieden. Nicht nur die Tatsache, dass PDF's auf einem festen Seitenlayout basieren und sich um Seitenumbrüche kümmern müssen, während bei HTML alles “nach…

Jonas J., 13.02.2012 14:32

Webseiten als PDF exportieren

Die Möglichkeit, Internetinhalte auch als PDF zur Verfügung zu stellen, gehört zu den typischen Aufgabenstellungen bei der Implementation von Websites.

Was konzeptionell sich so naheliegend anhört („Der Inhalt ist doch schon da!“) ist leider technisch häufig eine größere Herausforderung. Denn die Techniken von (HTML-)Web und PDF sind grundverschieden. Nicht nur die Tatsache, dass PDF's auf einem festen Seitenlayout basieren und sich um Seitenumbrüche kümmern müssen, während bei HTML alles „nach unten“ fließen kann - vor allem die technologischen Ansätze sind grundverschieden.

Während HTML über CSS und JavaScript in Form gebracht wird, muss man PDF's richtig layouten. Am Desktop kann man das mit Adobe Acrobat erledigen, im Web muss das automatisch geschehen - über Tools und API's, mit denen Inhalte explizit platziert werden. Die Krux hierbei besteht darin, dass die anzuzeigenden Daten in der Regel nicht handlich vorliegen, sondern von Content Management Systemen (CMS) gemanaged werden. Diese verwalten die Inhalte in beliebig komplexen Strukturen in Datenbanken und werten beim Rendering nicht nur die Seiteninhalte, sondern auch Berechtigungen, assoziierte Inhalte und so weiter aus.

Eine Auswertung der Datenbank zum Zwecke einer PDF Generierung ist somit wenig erfolgsversprechend, da man quasi das HTML-Rendering nachprogrammieren muss. Spätestens wenn dann ein CMS mit Plugins eingesetzt wird, gibt man auf.

Eine brauchbare Alternative hierzu ist deswegen der Ansatz, die PDF's direkt aus den HTML Ansichten zu generieren - sogenannte HTML2PDF Konverter. Da HTML heutzutage immer mit CSS und JavaScript daherkommt, benötigt man Tools, die HTML und CSS (und eventuell JavaScript) auswerten können. Für ein schmuckes PDF müsste man dann die vom CMS produzierten HTML und CSS Inhalte manuell nachbereiten und in einen solchen Konverter stecken.

Eine Besonderheit hierbei ist der JavaScript Support. Manche Websites sehen nur mit JavaScript vernünftig aus, da hiermit die Elemente richtig angeordnet werden (jQuery lässt grüßen).

Ob man nun für die PDF Generierung JavaScript Support benötigt oder nicht hängt sicherlich von der konkreten Aufgabe ab. Sinnvoll ist es aber nicht immer - dazu ein Beispiel: Bildergallerien werden heute üblicherweise als eine Mischung aus HTML und JavaScript programmiert. Dabei werden alle Bilder aus SEO Gründen schon direkt im HTML abgelegt und dann versteckt. Mit Hilfe von JavaScript werden nun die Blättern Vorgänge implementiert und jeweils ein anderes Bild angezeigt. Diese Funktionalität ist in PDF Dokumenten nicht praktikabel. Hier müssen die Bilder noch einmal extra mit CSS belegt werden, um eine übersichtliche Ausgabe zu erhalten.

Vorausgesetzt, der CSS Support des Tools erlaubt das… … womit wir von der Theorie zur Praxis kommen. Wie es in der Praxis funktioniert, haben wir uns am Beispiel aktueller HTML2PDF Konverter mal genauer angeschaut.

TCPDF

TCPDF ist eine php Library, die unter anderem auf FPDF basiert. TCPDF ist per LGPL lizensiert, eignet sich also für den Einsatz im Business.

Leider ist der Quellcode miserabel. Hier wird es einem sehr schwer gemacht, Codeverbesserungen und Bugfixes durchzuführen. :-(

Ebenfalls blöd: Man kann keine Base Url setzen. Das bedeutet, das man alle Referenzen von relativen Pfaden auf absolute umstellen muss :-(

Der CSS Support ist ausreichend, allerdings werden einige essentielle Dinge nicht unterstützt. So zum Beispiel die Größenangabe an Bildern mittels CSS Klassen. Das bedeutet, dass man Bilder mit expliziten Größenangaben via width und height versehen muss, um die Ausgabegröße anzupassen :-(

JavaScript wird nicht ausgeführt - siehe hierzu die Erläuterungen im Einleitungstext.

Die Ausgabe des PDF Dokumentes ist sehr gut konfigurierbar, entweder als Datei oder direkt in den Browser output oder als Download oder, oder….

Die Header und Footer können komfortabel konfiguriert werden.

Die Dokumentation ist recht mager. Es gibt eine phpdoc Dokumentation, die aber nicht unbedingt hilfreich ist. Auch Google ist meist ratlos, da TCPDF in jedem größere CMS als Exportschnittstelle benutzt wird und man daher unglaublich viel joomla Hilfe bekommt, aber nichts fundiertes und auch nichts zu TCPDF selbst.

Hier ein kurzes Beispiel, um einen Artikel aus dem Internet herunterzuladen und in ein PDF zu verwandeln:

<?php
require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');

// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);

// set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Jonas Jurczok');
$pdf->SetTitle('CosmoCode BlogExport');
$pdf->SetSubject('CosmoCode Blog Export');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');

// set default header data
$pdf->SetHeaderData('cosmo_logo.gif', PDF_HEADER_LOGO_WIDTH, "Artikel Export", "brought to you by CosmoCode.");

// set header and footer fonts
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

// set default monospaced font
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);

//set margins
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);

//set auto page breaks
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);

//set image scale factor
$pdf->setImageScale(1);

//set some language-dependent strings
global $l;
$pdf->setLanguageArray($l);

$pdf->setJPEGQuality(75);

// ---------------------------------------------------------

// set font
$pdf->SetFont('helvetica', '', 10);

// add a page
$pdf->AddPage();

$html = file_get_contents('http://www.cosmocode.de/de/blog/root/2012-02/13-webseiten-als-pdf-exportieren');

$html = str_replace('<link rel="stylesheet" href="', '<link rel="stylesheet" href="http://www.cosmocode.de/', $html);
$html = str_replace('<link rel="stylesheet" type="text/css" href="', '<link rel="stylesheet" type="text/css" href="http://www.cosmocode.de/', $html);
$html = str_replace(' src="f', ' src="http://www.cosmocode.de/f', $html);
$html = str_replace(' src="u', ' src="http://www.cosmocode.de/u', $html);

// output the HTML content
$pdf->writeHTML($html, true, false, true, false, '');

// reset pointer to the last page
$pdf->lastPage();

//Close and output PDF document
$pdf->Output('export.pdf', 'F');
?>

MPDF

MPDF basierd ebenfalls unter anderem auf FPDF, erweitert allerdings den CSS Support deutlich. So ist nun das Darstellen von Bildern überhaupt kein Problem mehr, dafür erscheinen Bilder komplett ohne Größenangabe sehr groß, da die normale HTML Einengung nicht standardgetreu berechnet wird.

Der Quellcode ist ebenfalls ein einziges Chaos, auch hier sind kleine Anpassungen also praktisch nicht möglich. Die Lizenz ist ebenfalls LGPL - prima.

MPDF bietet die Möglichkeit, eine BaseURL anzugeben - ein friemelige Substitution relativ/absolut entfällt also, auch das ist prima :-)

JavaScript wird auch hier nicht ausgeführt - siehe Anmerkung oben.

Das Ausgeben des Dokumentes, bzw das Abspeichern ist genau so gelöst, wie bei TCPDF. Man ruft die output Funktion auf und übergibt als Parameter einen Namen und einen Typbezeichner, ob das Dokument in den Browser gegeben oder angezeigt werden soll.

Ein gewaltiger Vorteil ist die freie Konfigurierbarkeit der DokumentHeader und -Footer. Dort können entweder unterstützte Parameter für das aktuelle Datum oder die Seitenzahl benutzt werden oder man schreibt sich selbst HTML, um den Header auszufüllen. So lassen sich zum Beispiel Firmenlogos im Header realisieren. Auch gibt es eine Funktion, die den Header automatisch jede Seite alternierend darstellt, um zum Beispiel den Abdruck in einem Buch zu erleichtern.

Die Dokumentation ist sehr ausführlich und bietet viele Beispiele, aber: die Verknüpfung zwischen Webseite und wirklicher example.php ist aber nicht immer einfach, da sich die Namen teilweise deutlich unterscheiden. Hier entsteht meist unnötige Sucherei, zumal der Example Ordner sehr überladen und zugemüllt wirkt.

Auch hierfür nun ein Beispiel für den selben Artikel:

<?php
require_once("MPDF53/mpdf.php");

$pdf = new mPDF('c');

$pdf->SetDisplayMode('fullpage');

// LOAD a stylesheet


$pdf->SetCreator('Jonas Jurczok');
$pdf->SetAuthor('Jonas Jurczok');
$pdf->SetTitle('CosmoCode TestExport');
$pdf->SetSubject('CosmoCode Artikel Export');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
$pdf->SetBasePath('http://www.cosmocode.de');

// set default header data
$pdf->mirrorMargins = 1;

$pdf->defaultheaderfontsize = 10;
$pdf->defaultheaderfontstyle = B;
$pdf->defaultheaderline = 1;

$pdf->defaultfooterfontsize = 12;
$pdf->defaultfooterfontstyle = B;
$pdf->defaultfooterline = 1;
$pdf->SetHeader("CosmoCode Export|Artikel über Html2PDF tools|Erstellt zu Demonstrationszwecken.");
$pdf->SetFooter("{DATE j.m.Y}|{PAGENO}/{nb}|CosmoCode Export");
//set margins
$pdf->SetMargins(15, 27, 15);

//set auto page breaks
$pdf->SetAutoPageBreak(TRUE, 25);
// ---------------------------------------------------------

// set font
$pdf->SetFont('helvetica', '', 10);

// add a page
$pdf->AddPage();

$html = file_get_contents('http://www.cosmocode.de/de/blog/root/2012-02/13-webseiten-als-pdf-exportieren');

// output the HTML content
$pdf->writeHTML($html);

//Close and output PDF document
$pdf->Output('export.pdf', 'F');
?>

Zu beachten ist noch, dass MPDF wirklich einen riesigen Haufen Notices produziert. Diese sollte man ignorieren, da es praktisch keine Möglichkeit gibt herauszufinden wo sie wirlich herkommen und wie man sie behebt.

wkhtmltopdf

Hierbei handelt es sich um eine C library, die man sich entweder selber kompilieren oder aber als Binary herunterladen kann. In den Linux Repositories ist sie ebenfalls vertreten, lässt sich also mit einem einfachen apt-get install installieren. wkhtmltopdf unterscheidet sich stark von den beiden vorgenannten Tools, da es ein echtes Rendering (inklusive JavaScript!) der HTML-Seite durchführt - hierzu ist in dem Tool die WebKit-Engine integriert.

Die Bedienung ist denkbar einfach. Man ruft einfach „wkhtmltopdf <url> <output.pdf>“ in der Konsole auf und ist fertig. Einhergehend damit ist die Konfiguration allerdings auch schwieriger, da man alles über Parameter lösen muss, sofern es denn überhaupt änderbar ist.

Die Dokumentation selbst ist sehr mager, allerdings gibt es einen rege genutzten Bugtracker.

Zu Beachten ist hierbei die große Abhängigkeit zum Betriebssystem! So sah der Output unter Windows 7 extrem schlecht aus. Dort war dann zum Beispiel der Text unsichtbar oder die Formatierung der gesamten Webseite zerrissen. Unter Linux hingegen ist das Ergebnis deutlich positiver. So werden dort die Texte korrekt dargestellt und auch die gesamte Seitenbreite passt plötzlich auf das PDF.

Fazit

Ich persönlich würde MPDF benutzen, da es den besten CSS Support bietet und am einfachsten zu konfigurieren und damit auch zu steuern ist. Die Doku ist gut und die Möglichkeiten vielfältig. Es gibt keine größeren Abhängigkeiten zum System (außer Curl, die sich aber alle libs teilen) und das Ergebnis ist sehr gut nachvollziehbar.

Mehr zum Thema

Kontakt

Wir freuen uns sehr über Ihr Interesse!
Sie erreichen uns hier:

CosmoCode GmbH

Prenzlauer Allee 36G
10405 Berlin

Telefon: +49 30 814 50 40 70

Telefax: +49 30 2809 7093


mail: info@cosmocode.de

CosmoCode GmbH  
   

© CosmoCode 2021 | Impressum | Datenschutz | Cookies verwalten

Schließen
Deutsch Englisch
  • Jobs