Mehrseitige PDFs aus Fluid-Templates generieren
Wieso haben wir uns für mPDF entschieden?
Nach diversen Tests u.a. auch mit FPDM haben wir uns für die PHP-Bibliothek mPDF entschieden. Bei der Entscheidung haben uns vor allem folgende Features überzeugt:
- UTF-8 encoded HTML wird als Standard-Input akzeptiert
- CSS stylesheets
- Bilder (JPG, GIF, PNG, SVG, BMP und WMF)
- Orientierung (Landscape/Portrait)
- Support von HTML-Tags und Attributen
- Seitennummerierung
Wie wir mPDF integriert haben...
Unser Projekt wurde mit einer composer-basierten TYPO3 v9 umgesetzt. Dort konnten wir dann ganz einfach die mPDF-Bibliothek integrieren.
In unserer composer.json haben wir einfach mPDF und unsere eigene Extension hinzugefügt:
"require": {
"mpdf/mpdf": "^7.1",
"werkraum/wr_extension": "dev-master"
}
Danach wird einfach im Controller ein neues Objekt ($mpdf = new \Mpdf\Mpdf($mpdfConfig);) mit der gewünschten Konfiguration erzeugt.
**
* Sets variables for event PDF Output
*
* @param \Werkraum\WrExtension\Domain\Model\Event $event
* @return void
*/
public function generatePdfForEventAction(\Werkraum\WrExtension\Domain\Model\Event $event = null)
{
$this->view->assign('event', $event);
$renderedHtml = $this->view->render();
$date = $event->getStartDate();
$startdate = $date->format('d.m.Y - H.i') . ' Uhr';
$topic = $event->getTopic();
$topicTitle = $topic->getTitle();
$pdfTitle = $startdate . ' - Daten aller Teilnehmer';
$this->generatePdf($renderedHtml, $startdate, $topicTitle, $pdfTitle);
}
public function generatePdf($renderedHtml, String $startdate, String $topicTitle, String $pdfTitle, String $orientation = 'P')
{
$currentPath = PATH_site . 'typo3temp/pdf/';
if (!is_dir($currentPath) && !mkdir($currentPath, 0777, true) && !is_dir($currentPath)) {
// this is an error!
}
/**
* @see https://mpdf.github.io
*/
$mpdfConfig = [
'tempDir' => $currentPath,
'orientation' => $orientation,
'format' => 'A4',
'margin_left' => 0,
'margin_right' => 0,
'margin_top' => 0,
'margin_bottom' => 0,
];
try {
$mpdf = new \Mpdf\Mpdf($mpdfConfig);
$mpdf->WriteHTML($renderedHtml);
$mpdf->SetTitle($startdate . ' - ' . $topicTitle . ' - Zeugnisse');
$mpdf->SetAuthor('\'Name des Autors');
$mpdf->SetCreator('Name des Erstellers');
$mpdf->SetSubject($topicTitle . ' - ' . $startdate);
$mpdf->Output($startdate . ' - ' . $pdfTitle . '.pdf', true); // dest === true ? 'download' : 'write to file'
exit;
} catch (\Mpdf\MpdfException $e) { // Note: safer fully qualified exception name used for catch
// Process the exception, log, print etc.
echo $e->getMessage();
}
}
Beispiel aus dem Fluid-Template
<div class="container container-is-first">
<f:render partial="PdfTemplates/LogoHeader" arguments="{_all}"/>
<div class="col-xs-12">
<h1>{participant.event.topic.title}</h1>
</div>
<div class="row">
<div class="col-xs-3">
<p>Name / Geb.Datum:</p>
<p>Anschrift:</p>
</div>
<div class="col-xs-7">
<p>{participant.name} /
<f:format.date format="%d.%m.%Y">{participant.birthday}</f:format.date>
</p>
<p>{participant.address}, {participant.zip} {participant.city}</p>
</div>
</div>
</div>
So werden mehrere Seiten verknüpft und mit CSS versehen
<f:be.container pageTitle="Alle Zertifikate für einen Termin" includeCssFiles="{
0:'{f:uri.resource(path:\'Css/bootstrap.min.css\')}',
1:'{f:uri.resource(path:\'Css/Be_custom.css\')}'}">
<f:for each="{event.participants}" as="participant" iteration="iter">
<f:render partial="Backend/PdfTemplates/PageOne" arguments="{_all}"/>
<pagebreak/>
<f:render partial="Backend/PdfTemplates/PageTwo" arguments="{_all}"/>
<pagebreak/>
<f:render partial="Backend/PdfTemplates/PageThree" arguments="{_all}"/>
<f:if condition="!{iter.isLast}">
<pagebreak/>
</f:if>
</f:for>
</f:be.container>
Hat dir der Artikel gefallen?
Werkraum News:

Toller Podcast zu Künstliche Intelligenz von Sascha Lobo
Wir von werkraum träumen ja schon seit langem vom eigenen Podcast, wäre das nicht immer so viel spannende Projekte, die es zu erledigen gibt. Solange hören wir einfach andere…
Matomo im DDEV installieren
Ich zeige euch wie man eine lokale Matomo Instanz im DDEV nutzen kann.
Strukturierte Daten - schema.org
Suchmaschinen mit den richtigen Daten füttern ist einfacher als man denkt.