FPDF ist eine PHP-Library, mit Hilfe derer man relativ einfach direkt aus PHP heraus PDFs erstellen kann und definitiv einen Blick wert.

Im Rahmen eines Projektes wollte ich den Benutzern einen Klick sparen und direkt beim Anzeigen des gerade erstellten PDFs den Druck-Dialog des Systems öffnen lassen.

Die Jungs von FPDF haben eine interessante Erweiterung, die das Einbinden von JavaScript in das PDF erlaubt und den Druckdialog dann per (ins PDF eingebettete) JavaScript aufruft.
Aber eigentlich bietet das PDF-Format auch nativ die Möglichkeit, das Anzeige-Programm zum direkten Ausdruck zu drängen.

Folgenden PHP-Code in eine neue Datei abspeichern (z.B. als fpdf_print.php) und in das PDF-Erstellungs-Skript einbinden:

<?php

class FPDI_PRINT extends FPDF { // <-- Falls die Template-Klasse fpdf_tpl.php nicht verwendet wird
//class FPDI_PRINT extends FPDI { // <-- Falls die Template-Klasse fpdf_tpl.php mit verwendet verwendet wird

    var $nr;

    function _putresources() {
        parent::_putresources();
        $this->_newobj();
        $this->nr=$this->n;
        $this->_out('<<');
        $this->_out('/S/Named');
        $this->_out('/Type/Action');
        $this->_out('/N/Print');
        $this->_out('>>');
        $this->_out('endobj');
        }

    function _putcatalog() {
        parent::_putcatalog();
        $this->_out('/OpenAction '.$this->nr.' 0 R');
        }
}

?>

Der Skript-Code zur PDF-Erstellung bleibt wie gehabt. Nach allen anderen Skripten einfach im Kopf noch die oben gezeigte Klasse mit einem

require_once('fpdf_print.php');
einbinden.
Statt
$pdf = new FPDI();
oder
$pdf = new FPDF();
ist
$pdf = new FPDI_PRINT();
zu verwenden.

Beispiel:

<?php
define('FPDF_FONTPATH','fonts/');
require_once('fpdf.php');
require_once('fpdi.php');
require_once('fpdf_tpl.php');
require_once('fpdf_print.php'); // <-- Unsere neue Klasse

$pdf = new FPDI_PRINT(); // <-- Name unserer neuen Klasse
$pdf->AddPage();
$pdf->setSourceFile("template.pdf");
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 0, 0, 210);
$pdf->AddFont('Dinot-Regular', '', 'DINOT-Regular.php');
$pdf->SetFont('Dinot-Regular');
$pdf->SetTextColor(255, 0, 0);
$pdf->SetXY(30, 30);
$pdf->Write(0, 'Dies ist ein Test');
$pdf->Output();
?>

Öffnet man das daraus resultierende PDF in Adobe Acrobat oder betrachtet es im Browser mit Acrobat-Plugin, wird sich sofort der Druck-Dialog öffnen.

JavaScript-Workaround für Safari

Das ganze funktioniert recht gut in Adobe Acrobat und Browsern wie Chrome und Firefox, allerdings weder in der Vorschau von MacOS X noch in Safari, welches (optimalerweise) dieselbe PDF-Anzeige-Engine wie die Vorschau verwendet.

Zumindest was den direkten Ausdruck von Safari aus angeht, kann hier ein kleiner JavaScript-Workaround Abhilfe schaffen.

In folgendem Snippet wird nach einem Klick auf den Button das per FPDF erstellte PDF abgerufen und der Druckerdialog aufgerufen:

<input type='button' name='drucken' value='Drucken' onClick='printPdf();'>

<script type='text/javascript'>
function printPdf() {
        // Wir brauchen zur Hilfe einen iFrame, in den wir das PDF laden
        // iFrame (durch vorherige Verwendung) bereits vorhanden?
        if (!document.getElementById("helper_iframe")) {
                iframe = document.createElement('iframe');
                iframe.id = "helper_iframe";
                document.body.appendChild(iframe);

                iframe.style.display = 'none';
                iframe.onload = function() {
                        setTimeout(function() {
                                iframe.focus();
                                iframe.contentWindow.print();
                                }, 1);
                        }
                }
        // Jetzt das PDF laden
        document.getElementById("helper_iframe").src = "fpdf/pdferstellung.php";
        }
</script>

Bei meiner Recherche bin ich noch oft über die Frage gestolpert, ob man das PDF nicht auch direkt – ohne Druckerdialog – ausdrucken könne.
Zum Glück ist so etwas natürlich nicht möglich. Man stelle sich nur vor, jede beliebige Seite könnte ohne nachzufragen 10'000 Seiten auf den heimischen Drucker senden.