Mit PDF direct Print greife ich ein altes Problem auf, das seit Jahren durch die Foren geistert: PDFs direkt aus dem IFS an einen Drucker senden und stelle eine Lösung dafür vor, die für mich gut und komfortabel funktioniert.
1. Vorgeschichte
Mittlerweile erstellen viele meiner Kunden PDF-Dateien für eine Vielzahl von Dokumenten. Mich betrifft das auch, denn ich habe die Rechnungen der letzten 10 Jahre als PDFs im IFS gespeichert. Vor kurzem habe ich mir einen Kyocera Drucker mit direct PDF-Print gekauft und gehofft, dass ich damit PDFs aus dem IFS direkt drucken kann.
Leider funktioniert das nur unter Windows und die Nachfrage bei einem Kunden mit dem gleichen Thema ergab, dass PDF direct Print bei seinen Develop Druckern einwandfrei funktioniert, aber leider bei Kyocera Druckern nicht.
Dann habe ich gefunden, dass direct Print mit JPG-Dateien funktioniert und ein Java-Programm geschrieben, das eine PDF- in eine JPG-Datei konvertiert. Doch werden die JPG-Dateien sehr groß und es dauert einfach zu lange bis der Drucker druckt.
Im Forum habe ich gelesen, dass es mit PSF400 gut funktionieren soll und mittlerweile ist die Software auch kostenlos zu haben. Also Software installiert und gehofft, dass es sofort funktioniert, aber leider ist dem nicht so. Mit Hilfe des IBM-Softwaresupports funktioniert es jetzt sehr gut und schnell. Und damit macht es für mich Sinn, mit Ihnen – verehrte Leser – dieses Wissen zu teilen.
2. Was muss installiert sein
Sie benötigen die mittlerweile kostenlosen Lizenzprogramme:
- 5722IP1 *BASE und Option 1 IBM Infoprint Server für iSeries
- 5770SS1 Option 35 PSF for IBM i 1-55 IPM Printer Support
Das Lizenzprogramm 5722IP1 gibt es nur in der Version V5R3M0, aber keine Sorge, ich habe die Version V7R5 und es ließ sich problemlos installieren. Denken Sie bitte auch daran, sich den Lizenzkey zu besorgen und einzugeben.
3. Die Device für den Kyocera Drucker erstellen
Beim Händler um die Ecke gab es einen neuwertigen ECOSYS M2540dn für kleines Geld, der schnell ist und auch Scannen kann.
Mit dem CRTDEVPRT ist die Device schnell erstellt und die ersten Tests, Spoolfiles aus der IBM i zu drucken, funktionieren einwandfrei.
Quelle: RossDas Command zum Erstellen der Device PRT02 für den Drucker:
CRTDEVPRT DEVD(PRT02) DEVCLS(*LAN) TYPE(3812) MODEL(1) +
LANATTACH(*IP) PORT(9100) ATTACH(*DIRECT) +
ONLINE(*YES) FONT(011 *NONE) +
FORMFEED(*AUTOCUT) SEPDRAWER(*FILE) +
PRTERRMSG(*INQ) MSGQ(*CTLD) ACTTMR(170) +
INACTTMR(*SEC15) LINESPEED(19200) +
WORDLEN(8) PARITY(*NONE) STOPBITS(1) +
TRANSFORM(*YES) MFRTYPMDL(*HP5) +
PPRSRC1(*A4) PPRSRC2(*A4) ENVELOPE(*NONE) +
ASCII899(*NO) IMGCFG(*IMGC02) +
CHRID(*SYSVAL) RMTLOCNAME('172.16.0.151') +
SYSDRVPGM(*HPPJLDRV) PUBLISHINF(*UNKNOWN +
*UNKNOWN *UNKNOWN *UNKNOWN *BLANK +
*UNKNOWN) TEXT('Printer Kyocera M2540dn')
4. Die Konfiguration für PDF to AFP erstellen
Technisch funktioniert es so, dass PSF400 das PDF in einen AFP-Datenstrom konvertiert und dieser dann auf den allermeisten Drucker gedruckt werden kann.
Als erstes wird mit dem Befehl CRTPSFCFG eine PSF-Konfiguration erstellt:
CRTPSFCFG PSFCFG(QUSRSYS/PDF2AFP) IPDSPASTHR(*NO) +
PDFGEN(*STMF) PDFDEVTYPE(*IP40300) +
PDFPPRDWR1(*A4) PDFPPRDWR2(*A4) +
PDFDIR('/PSF400') AFPSAVE(*YES) +
AFPOUTQ(QUSRSYS/PRT02) +
TEXT('Printer PDF to AFP')
Sie sehen, dass in dieser Konfiguration der Drucker PRT02 als AFP-Drucker zugeordnet ist.
Als nächstes benötigen wir den PDF to AFP-Drucker, der mit folgendem Befehl erstellt wird:
CRTDEVPRT DEVD(PDF2AFP) DEVCLS(*LAN) TYPE(*IPDS) +
MODEL(0) LANATTACH(*IP) AFP(*YES) +
PORT(5005) ONLINE(*YES) FONT(11) +
FORMFEED(*AUTOCUT) IMGCFG(*IMGC06) +
RMTLOCNAME('127.0.0.1') +
USRDFNOBJ(QUSRSYS/PDF2AFP *PSFCFG) +
TEXT('Printer PDF to AFP')
Und zu guter Letzt noch ein Printerfile:
CRTPRTF FILE(QUSRSYS/PDF2AFP) DEV(PDF2AFP) +
DEVTYPE(*USERASCII) TEXT('Convert +
PCL/PS/PDF to AFPDS') PAGESIZE(11.69 8.27 +
*UOM) LPI(6) CPI(10) OVRFLW(60) PAGRTT(0) +
OUTQ(*DEV) USRDTA('AFPrespool') +
USRDFNDTA('AFPRESPOOL(*NOPRINT)')
Wichtig ist der Parameter IMGCFG(*IMGC06) beim Erstellen der Device PDF2APF. Hier kann man die Konfiguration für den Drucker einstellen, ob mit oder ohne Rand und die Auflösung beim Drucken:
- *IMGC06 = IPDS-Drucker 300 dpi mit druckfreiem Rand
- *IMGC07 = IPDS-Drucker 600 dpi mit druckfreiem Rand
5. Was ist noch zu tun?
Die neue Device PDF2AFP muss angehängt und gestartet werden.
VRYCFG CFGOBJ(PDF2AFP) CFGTYPE(*DEV) STATUS(*ON)
STRPRTWTR DEV(PDF2AFP)
Und dann den Transfermanager starten
STRTFMMGR
6. Jetzt wird gedruckt
Die IBM empfiehlt für das Drucken ein FTP-Skript, das so aussieht:
FTP RMTSYS(LOCALHOST)
namefmt 1
bin
lcd /home/pdf
cd /qsys.lib/qusrsys.lib
put CustomerList.pdf pdf2afp.file
Das funktioniert, ist aber nicht so richtig komfortabel. Wesentlich besser finde ich ein Programm von Scott Klement, welches ein PDF mit den File APIs liest und direkt in das Printerfile schreibt. Es ist im Internet unter PRTSTMF (Print Streamfile) zu finden.
Das Programm habe ich angepasst, sodass jetzt das PDF direkt in das PDF2AFP Printerfile geschrieben wird.
ctl-opt dftactgrp(*no) alloc(*teraspace);
//------------------------------------------------------------------//
// //
// Print Streamfile //
// //
//----------------- //
// R.Ross 01.2025 * //
//------------------------------------------------------------------//
// Files //
//------------------------------------------------------------------//
dcl-f PDF2AFP printer(132) usage(*output) usropn;
//------------------------------------------------------------------//
// Input Parameter //
//------------------------------------------------------------------//
dcl-pi *n;
PiStmf char(256) const;
end-pi;
//------------------------------------------------------------------//
// Open-File //
//------------------------------------------------------------------//
dcl-pr open int(10) extproc(*dclcase);
Filename pointer value options(*string);
Openflags int(10) value;
Mode uns(10) value options(*nopass);
Fileccsid uns(10) value options(*nopass);
Dataccsid uns(10) value options(*nopass);
end-pr;
//------------------------------------------------------------------//
// Read-File //
//------------------------------------------------------------------//
dcl-pr read int(10) extproc(*dclcase);
Filedesc int(10) value;
Buffer pointer value;
Bytes uns(10) value;
//------------------------------------------------------------------//
// Close-File //
//------------------------------------------------------------------//
dcl-pr close int(10) extproc(*dclcase);
Filedesc int(10) value;
end-pr;
//------------------------------------------------------------------//
// Constants IFS Parameter //
//------------------------------------------------------------------//
dcl-c O_Rdonly 1; // Read Only
//------------------------------------------------------------------//
// Processing //
//------------------------------------------------------------------//
main();
*inlr = *on;
//------------------------------------------------------------------//
// Main //
//------------------------------------------------------------------//
dcl-proc main;
dcl-ds DsLine qualified;
Line char(132);
end-ds;
dcl-s LocBuffer char(132); // Buffer
dcl-s LocFd int(10); // FileDescriptor
open PDF2AFP;
LocFd = open(%trim(PiStmf):O_RDONLY);
If LocFd < *zero;
ReportError();
endif;
LocBuffer = *allx'20';
dow read(LocFd:%addr(LocBuffer):%size(LocBuffer)) > 0;
DsLine.Line = LocBuffer;
write PDF2AFP DsLine;
LocBuffer = *allx'20';
enddo;
callp close(LocFd);
close PDF2AFP;
end-proc;
//------------------------------------------------------------------//
// Report Error //
//------------------------------------------------------------------//
dcl-proc reportError;
dcl-pr get_errno pointer extproc('__errno');
end-pr;
dcl-s LocErr_p pointer; // Error-Pointer
dcl-s LocErrNo int(10) based(LocErr_p); // Error-Number
dcl-pr SndPgmMsg extpgm('QMHSNDPM');
MsgId char(07) const;
MsgFile char(20) const;
Data char(256) const;
DataLength int(10) const;
Type char(10) const;
CStEnt char(10) const;
CStCnt int(10) const;
Key char(04);
Error like(DsApierr);
end-pr;
dcl-ds DsApierr qualified inz; // API-Error
BytesProv int(10) inz(%size(DsApierr)); // Bytes Provided
BytesAvail int(10); // Bytes Avail
MsgId char(07); // ErrorMessageId
*n char(01);
ErrData char(256); // ErrorData
end-ds;
dcl-s LocMsgKey char(04);
dcl-s LocMsgId char(07);
LocErr_p = get_errno();
LocMsgId = 'CPE' + %char(LocErrno);
SndPgmMsg(LocMsgId:'QCPFMSG *LIBL':' ':0:'*ESCAPE':
'*PGMBDY':1:LocMsgKey:DsApierr);
end-proc;
//------------------------------------------------------------------//
Das Programm wird mit folgendem Befehl aufgerufen:
CALL PGM(PRTSTMF) PARM(('/home/pdf/CustomerList.pdf' (*CHAR 256)))
oder Sie erstellen sich dazu ein Command und rufen es damit auf:
/*********************************************************************/
/* */
/* PRINT STREAMFILE - PROGRAM PRTSTMF */
/* */
/****************** */
/* R.ROSS 01.2025 * */
/*********************************************************************/
CMD PROMPT('Print Stream File')
PARM KWD(STMF) TYPE(*CHAR) LEN(256) MIN(1) +
VARY(*NO) CHOICE('IFS PATH') +
PROMPT('Stream File to print')
/*********************************************************************/
Viel Spaß beim Ausprobieren.
Den Autor Rainer Ross erreichen Sie unter:
Rainer Ross IT-Beratung
Bgm.-Hollweck-Str. 6
85599 Parsdorf
Ausgezeichnet mit dem Innovationspreis der IBM und Spezialist für Webservices und Webanwendungen auf IBM i so schnell wie Greenscreen.
Beispiel: www.myhofi.com/myapps/HTML/Myapp.html
Tel. (+49) 151/684 375 53 oder 089/413 252 94,
E-Mail: rainer_ross@web.de
