Mal 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.

3 Antworten zu “HTML zu PDF umwandeln, endlich “einfach” (Plattformunabhängig)”

  1. Na says:

    Sehr schön, aber wo kommt die File Classe her?

  2. Michael says:

    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

  3. Jochen says:

    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.

Hinterlasse einen Kommentar.

Network-wide options by YD - Freelance Wordpress Developer