HTML zu PDF umwandeln, endlich “einfach” (Plattformunabhängig)
Geschrieben von: Michael, in phpMal wieder auf der Suche nach einer sinnvollen HTML2PDF Lösung, bin ich auf wkhtmltopdf gestoßen.
Das Tool nutzt Webkit im internen Backend und kann sogar CSS3 rendern. Die Installation unter MaxOSX und Linux ist absolut simpel: runterladen, ablegen, fertig. Unter Windows wird hier noch ein Installationsprozess durchgeführt, über den ich aktuell leider nichts sagen kann (bisher nicht getestet).
Um das Tool auf einer Webseite zu nutzen, habe ich mir ne kleine Klasse geschrieben, die HTML-Code als Input akzeptiert und mir den Pfad der fertigen PDF-Datei zurückliefert.
class HtmlToPdf { const TMP = '/tmp/'; const EXEC = '/usr/local/bin/wkhtmltopdf-amd64'; //anpassen! private $executable; private $htmlcode; private $tmphtmlfile; private $targetFilename; private $options = array( '--ignore-load-errors' ); //Kommandozeilenoptionen für wkhtmltopdf public function __construct($targetFilename = ''){ $this->targetFilename = $targetFilename; } public function setHtmlCode($htmlcode){ $this->htmlcode = $htmlcode; } public function setTargetFilename($targetFilename){ $this->targetFilename = $targetFilename; } public function generate(){ $this->createTempHtmlFile(); $this->convertHtmlfileToPdf(); return self::TMP.$this->targetFilename; } private function createTempHtmlFile(){ $filename = tempnam(self::TMP); File::move($filename, $filename.'.html'); //nötig, damit die Datei als Input akzeptiert wird $filename .= '.html'; file_put_contents($filename, $this->htmlcode); $this->tmphtmlfile = $filename; } private function convertHtmlfileToPdf(){ if(!$this->targetFilename){ $this->generateTargetFilename(); } $cmd = self::EXEC.' '.implode(' ', $this->options).' '.$this->tmphtmlfile.' '.self::TMP.$this->targetFilename; shell_exec($cmd); File::delete($this->tmphtmlfile); } private function generateTargetFilename(){ $this->targetFilename = uniqueid().'.pdf'; } } |
Und so nutzt man das Ganze:
$converter = new HtmlToPdf('output.pdf'); $converter->setHtmlCode($htmlcodeWithCSS); $pdfFile = $converter->generate() |
Sehr praktisch ist es, wenn man eine Templateengine (z.B. Smarty) nutzt, hier kann man erst den kompletten Code generieren und ihn dann via $smarty->fetch() in den Konverter übergeben. Über einen Parameter kann man dann noch dafür sorgen, dass der CSS Style nicht ausgelagert, sondern im head-Block ausgegeben wird, da das Tool sonst nicht damit klarkommt.
Oktober 26th, 2010 at 11:51
Sehr schön, aber wo kommt die File Classe her?
Oktober 26th, 2010 at 11:54
Oh sorry, klar.
Ist eigentlich nur ein einfacher Wrapper….
File::delete($file) macht unlink($file)
File::move($file) macht copy($file) und unlink($file)
Nur, dass hier noch ein paar Checks sind (is_file und sowas) und das Teil Exceptions wirft, statt Warnings oder Fatals
Mai 11th, 2011 at 19:46
Coole Sache, das mit wkhtmltopdf funktioniert super.
Meine komplexe Testseite wurde sofort richtig als pdf erstellt, hatte schon mehrere Tools ausprobiert, aber die Ergebnisse waren nicht brauchbar.
Danke für den Tip, arbeite selbst mit smarty und xajax, da lassen sich die pdfs sehr einfach mit wkhtmltopdf erstellen.