PDF-Datei erzeugen

Anforderung

Im Zusammenhang mit dem Einsatz eines print2forms-Gateways ist eine der häufigsten Anforderungen die, die Druckausgabe in ein anderes Format, wie zum Beispiel PDF zu konvertieren, um dann die Druckausgabe per E-Mail zu versenden oder an ein Archiv zu übergeben.

Für die Umwandlung einer PCL-Datei in eine PDF-Datei wird ein Programm gebraucht, welches quasi einen Laserdrucker simuliert. Das war in der Vergangenheit ein Programm der amerikanischen Firma Lincoln & Co, was inzwischen nach einem Verkauf der Firma aber nicht mehr am Markt erhältlich ist.

Als Alternative bietet sich das Programm GhostPCL an. Damit lassen sich nicht nur PDF-Dateien erzeugen, sondern auch fast alle Arten von Bilddateien generieren, sodass zur Not auch noch ein Fax-Anschluss realisiert werden könnte. 1)

Realisierung

Das print2forms-Gateway erzeugt für jeden Druckauftrag zwei Dateien: eine mit dem PCL-Datenstrom (Endung '.pcl'), der das gedruckte Dokument erzeugt, und eine Textdatei (Endung '.ctl'), in der die im Druckdatenstrom erkannten Texte mit einem Index entsprechend ihrer Position im Dokument aufgelistet sind. 2) Nachdem beide Dateien erzeugt worden sind, kann vom Gateway über eine Kommandozeile ein Skript aufgerufen werden, das diese Dateien dann weiterverarbeitet. 3)

Im nachfolgenden ist ein Skelett für ein PHP-Skript abgebildet, welches als Gerüst für eigene Entwicklungen dienen kann. Das Skript extrahiert im ersten Schritt aus der Textdatei (mit der Endung '.ctl') eine Kunden- und eine Dokumentnummer.

Im zweiten Schritt wird die Erzeugung der PDF-Datei vorbereitet. Die neueren Versionen von GhostPCL erlauben eine einfache Bestimmung der Meta-Daten (Autor, Erzeuger, Titel) einer PDF-Datei durch die Interpretation eines Vorspanns mit einer PJL-Sequenz. Diese PJL-Sequenz wird erst einmal in eine Datei geschrieben.

Im dritten Schritt erfolgt die Erzeugung der PDF-Datei durch Aufruf des Programms GhostPCL. Die dafür notwendige Kommandozeile enthalt vor der PCL-Datei das Einfügen der eben erzeugten PJL-Sequenz. Eine ausführliche Beschreibung der Kommandozeilen-Parameter ist in der Dokumentation zu GhostPCL zu finden.

Im vierten und letzten Schritt wird die erzeugte PDF-Datei in einem Verzeichnis nach Kundennummern sortiert abgelegt. Falls zu einer Kundenummer noch kein Unterverzeichnis existiert, wird es vorher angelegt.

pdf.php
<?php
// Gateway command line:    "C:\php\php.exe" "%1/pdf.php" "%1" "%2" %4
 
$Script = $argv [1];                                        /* path to script */
$Spool = $argv [2];                               /* path to spooled document */
$Document = $argv [3];                                    /* name of document */
 
$Target = "C:\\temp\\";
 
if ($Script == "" || $Spool == "" || $Document == "") 
  exit (-1);                                               /* wrong arguments */
 
chdir ($Spool);           /* make it current directory to shorten some pathes */
 
$Docno = "0";
$Custno = "0";
 
$Index = fopen ($Document . ".ctl", "r"); 
 
if ($Index)
  {
    while (($Line = fgets ($Index, 4096)) !== false)
      {
        if (preg_match ("/\[010020006F\] *(\d+)/", $Line, $Matches))
          $Docno = trim ($Matches [1]);                    /* document number */
 
        if (preg_match ("/\[010055015F\][^\d]*(\d+)/", $Line, $Matches))
          $Custno = trim ($Matches [1]);                   /* customer number */
 
        if (preg_match ("/\[Page\]/", $Line))
          break;
      }
    fclose ($Index); 
  }
 
$PDFMark = "\x1b%-12345X\x0A" .
           "@PJL DEFAULT PDFMARK = \"[ " .  
           "/Author (Meine Firma) " .
           "/Creator (print2forms) " .
           "/Title (Rechnung " . $Docno . ") " .
           "/DOCINFO pdfmark \"";
 
file_put_contents ("pjl.pjl", $PDFMark);
 
$Output = $Custno . $Subdir . "\\RE" . $Docno . ".pdf";
 
$Cmd = "\"" . $Script . "\\gpcl6win64.exe\"" .
                        " -dNOPAUSE" .
                        " -sDEVICE=pdfwrite" .
                        " -dPDFFitPage" .
                        " -dPDFA=1" .
                        " \"-sOutputFile=" . $Document . ".pdf\"" .
                        " pjl.pjl" .
                        " \"" . $Document . ".pcl\"";
 
system ($Cmd, $Result);                 /* convert the pcl-file to a pdf-file */
 
if ($Result != 0) { exit (-3); }             /* can't convert to PDF document */
 
chdir ($Target);
 
if (! is_dir ($Target . $Custno))
  mkdir ($Target . $Custno);
 
/* Copy PDF to target directory as target might be a network share */
 
if (! copy ($Spool . "\\" . $Document . ".pdf", $Target . $Output))
  exit (-4);                           /* result PDF document can't be copied */
 
chdir ($Spool);           /* make it current directory to shorten some pathes */
 
unlink ($Document . ".ctl");                              /* no longer needed */
unlink ($Document . ".pcl");
unlink ($Document . ".pdf");
 
exit (0); 
?>


Bemerkungen


1)
GhostPCL steht unter einer modifizierten GNU-Lizenz - der AGPL - die auch die kommerzielle Nutzung erlaubt.

2)
Der eigentliche Name der Dateien besteht aus der internen Kennung des Gateways als Hexadezimalzahl, gefolgt von einer laufenden dezimalen Nummer. Er ist in der Regel nicht weiter von Bedeutung, ausser dass er die zusammenge­hörenden '.pcl' und '.ctl' Dateien kennzeichnet.

3)
Der Parameter '%1' wird gegen das Skript-Verzeichnis und der Parameter '%2' gegen das Spool-Verzeichnis ersetzt. Der Parameter '%4' ist der Name der erzeugten Dateien.

4)
Es werden lediglich die beiden Dateien 'gpcl6win64.exe' und 'gpcl6dll64.dll' benötigt!