PDF Generierung in Magento 2

magento-pdf-layout

Die Core Methoden zum Generieren von PDF Dateien sind auch in Magento 2 eher unflexibel. Eine Alternative sind Tools zum Konvertieren von HTML zu PDF.

In unserem aktuellen Magento 2 Projekt, das wir (integer_net) gemeinsam mit der Stämpfli AG entwickeln, gibt es die Anforderung, aus ausgewählten Produkten dynamisch einen PDF Katalog zu erstellen, der im Prinzip das gleiche Layout hat wie die Produktlisten im Shop. Die PDF aufgrund von HTML zu generieren lag also nahe.

In diesem Beitrag stelle ich unsere Lösung vor, die wkhtmltopdf mit dem Magento Layout integriert. Am Ende gibt es auch einen Link zum Basismodul auf Github.

Weiterlesen auf webguys.de

Unit-testen von generierten PDFs mit PHPUnit und PDFBox

Zu den Features, die sich nicht leicht mit Unit Tests prüfen lassen gehört das generieren von PDF-Dateien.

Hilfreich dazu ist das Kommandozeilen-Tool PDFBox mit der Option ExtractText:

PDF

This application will extract all text from the given PDF document.

Das erlaubt uns schon mal, den Text-Inhalt des Dokuments zu testen oder nach bestimmten Strings darin zu suchen.

Interessant wird es mit der Option -html, die das PDF zu HTML konvertiert. Damit sind auch Struktur und Formatierungen ansatzweise testbar.

Leider arbeitet das Tool nicht mit Streams, wir müssen also temporäre Dateien nutzen. Ein einfaches Beispiel für eine Funktion, die ein PDF Dokument als String entgegennimmt, mit PdfBox in HTML konvertiert und das HTML als String zurückgibt:

/**
 * @var string $streamIn binary string with generated PDF
 * @return string HTML string
 */
function htmlFromPdf($streamIn)
{
  $pdf = tempnam();
  file_put_contents($pdf, $streamIn);
  $txt = tempnam();
  exec('java -jar pdfbox-app-x.y.z.jar ExtractText -encoding UTF-8 -html ' . $pdf . ' ' . $txt);
  $streamOut = file_get_contents($txt);
  unlink($pdf);
  unlink($txt);
  return $streamOut;
}

Für Regressionstests oder beim Refaktorisieren kann es mitunter ausreichen, zu testen, dass das generierte PDF sich gegenüber dem Referenz-Dokument nicht geändert hat. Hier bietet sich ein Hash an, die Datei selbst ist aber – vermutlich aufgrund von Timestamps – nicht bei jedem Durchlauf exakt gleich. Ein Hash des nach HTML konvertierten Dokuments dagegen genügt:

        // In PHPUnit test case:
        $converter = new PdfBox();
        $html = $converter->htmlFromPdfStream($pdf);
        $this->assertEquals('336edd9ee49b57e6dba5dc04602765056ce05b91', sha1($html), 'Hash of PDF content');

Continue reading “Unit-testen von generierten PDFs mit PHPUnit und PDFBox”