Convert spooled files to PDF using Java
The iSeries command SPLTOPDF is presented which converts spooled files to PDF files.
The iSeries command SPLTOPDF is presented which converts spooled files to PDF files.
Continue Reading This Article
Enjoy this article as well as all of our content, including E-Guides, news, tips and more.
The command has the following features:
1. Embedding of true type font of any language. To embed a font, you just have to copy a ttf font file, which is existed in windows font folder environment, to an iSeries folder.
2. Measuring of true type text in order to create the correct width and height of the PDF page, according to the number of rows and columns of the spooled file. Prerequisite is the usage of a fixed characters width font, like Courier.
3. Usage of PDF footer with notes given from the command prompt.
4. Usage of watermark on every PDF page. To embed a watermark, you just have to copy a jpg figure to an iSeries folder.
5. The PDF internal stream objects are compressed and the PDF format is just a canvas where text and graphics are placed without any structure information. This means that text and graphics are read only.
The following two Java libraries are used:
1. The IBM Toolbox for Java access classes.
2. The iText free Java-PDF library that allows generating PDF files on the fly. You can upload the library to iSeries from here. The feature list of the library is plenty, you can add to the PDF Documents Chunks, phrases, paragraphs, anchors, lists, annotations, hypertext links, header footers, chapters, sections, graphics, tables, images, fonts, barcodes and events. There are many advanced features to layout the referenced objects and also you can concat, split, handout and encrypt the PDF files.
Preparation steps:
1. On iSeries create the folder /spltopdf
2. Upload the spltopdf.java into the /spltopdf
3. Upload a courier ttf windows font file into the /spltopdf and name it courier.ttf
4. Upload a small jpg logo-file into the /spltopdf and name it watermark.jpg
5. Upload the iText library com.lowagie... into the /spltopdf
6. Upload the iText.jar, iTextHYPH.jar and iTextXML.jar files into the /spltopdf
7. Be sure that jt400Native.jar exists into the folder /QIBM/ProdData/OS400/jt400/lib
8. Create the spltopdf.class using the crtclasscl CLP
9. Create the command spltopdf using the spltopdfcl CLP and spltopdf CMD
/************************************************************************/ /* Command: */ /* spltopdf */ /* Prompt: */ /* Convert spooled file to PDF */ /* Keywords: */ /* FILE Spooled file Spooled file to convert */ /* JOB Job name Spooled file job */ /* SPLNBR Spooled nbr Spooled file number */ /* PDFPATH Folder path Folder where to create PDF */ /* PDF PDF Name PDF Name */ /* NOTES Notes Notes are written in the PDF Footer */ /* Programmer: */ /* mmariakakis@saraleehbc.gr */ /************************************************************************/ CMD PROMPT('Convert Spooled File to PDF') PARM KWD(FILE) TYPE(*NAME) LEN(10) MIN(1) + PROMPT('Spooled File') PARM KWD(JOB) TYPE(JOB) DFT(*) SNGVAL((*)) + PROMPT('Job name') PARM KWD(SPLNBR) TYPE(*DEC) LEN(6) RSTD(*NO) + RANGE(1 999999) MIN(1) PROMPT('Spooled File + Number') PARM KWD(PDFPATH) TYPE(*PNAME) LEN(96) MIN(1) + EXPR(*YES) PROMPT('To IFS Path') PARM KWD(PDF) TYPE(*SNAME) LEN(10) MIN(1) + PROMPT('PDF Name') PARM KWD(NOTES) TYPE(*CHAR) LEN(50) RSTD(*NO) + MIN(1) PROMPT('Notes') JOB: QUAL TYPE(*NAME) DFT(*) QUAL TYPE(*NAME) LEN(10) PROMPT('User') QUAL TYPE(*CHAR) LEN(6) RANGE(000000 999999) + PROMPT('Number') /************************************************************************/ /* spltopdfcl: */ /* Convert spooled file to PDF */ /* Parameters: */ /* &FILE Spooled file Spooled file to convert */ /* &JOB Job name Spooled file job */ /* &SPLNBR Spooled nbr Spooled file number */ /* &PDFPATH Folder path Folder where to create PDF */ /* &PDF PDF Name PDF Name */ /* &NOTES Notes Notes are written in the PDF Footer */ /************************************************************************/ PGM PARM(&FILE &JOB &SPLNBR &PDFPATH &PDF &NOTES) DCL VAR(&MESSAGE) TYPE(*CHAR) LEN(70) DCL VAR(&JAVA) TYPE(*CHAR) LEN(300) DCL VAR(&MEMBER) TYPE(*CHAR) LEN(10) DCL VAR(&COUNTDEC) TYPE(*DEC) LEN(9) DCL VAR(&COUNTCHAR) TYPE(*CHAR) LEN(9) DCL VAR(&FILE) TYPE(*CHAR) LEN(10) DCL VAR(&JOB) TYPE(*CHAR) LEN(26) DCL VAR(&JOBNAME) TYPE(*CHAR) LEN(10) DCL VAR(&USER) TYPE(*CHAR) LEN(10) DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6) DCL VAR(&SPLNBR) TYPE(*DEC) LEN(6) DCL VAR(&FILENBR) TYPE(*CHAR) LEN(6) DCL VAR(&PDFPATH) TYPE(*CHAR) LEN(96) DCL VAR(&PDF) TYPE(*CHAR) LEN(10) DCL VAR(&NOTES) TYPE(*CHAR) LEN(50) DCL VAR(&LOGFILE) TYPE(*CHAR) LEN(110) DCL VAR(&LENGTH) TYPE(*CHAR) LEN(4) DCL VAR(&WIDTH) TYPE(*CHAR) LEN(4) DCL VAR(&BINNBR) TYPE(*CHAR) LEN(4) DCL VAR(&RCVLEN) TYPE(*CHAR) LEN(4) DCL VAR(&RECEIVER) TYPE(*CHAR) LEN(840) DCL VAR(&STATUS) TYPE(*CHAR) LEN(1) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) /* Prepare spooled file attributes */ CHGVAR VAR(&STATUS) VALUE('1') IF COND(&JOB = '*') THEN( + RTVJOBA JOB(&JOBNAME) USER(&USER) NBR(&JOBNBR)) ELSE (DO) CHGVAR VAR(&JOBNAME) VALUE(%SST(&JOB 1 10)) CHGVAR VAR(&USER) VALUE(%SST(&JOB 11 10)) CHGVAR VAR(&JOBNBR) VALUE(%SST(&JOB 21 6)) ENDDO CHGVAR VAR(&FILENBR) VALUE(&SPLNBR) /* Retreive spooled file attributes */ CHGVAR VAR(%BIN(&BINNBR)) VALUE(&FILENBR) CHGVAR VAR(%BIN(&RCVLEN)) VALUE(840) CALL PGM(QUSRSPLA) PARM(&RECEIVER &RCVLEN + 'SPLA0100' &JOB ' ' ' ' &FILE &BINNBR) CHGVAR VAR(&LENGTH ) VALUE(%BIN(&RECEIVER 425 4)) CHGVAR VAR(&WIDTH ) VALUE(%BIN(&RECEIVER 429 4)) /* Dummy change to see if the spooled file exists */ CHGSPLFA FILE(&FILE) JOB(&JOBNBR/&USER/&JOBNAME) + SPLNBR(&FILENBR) /* Test the path length */ IF COND('0' *BCAT &PDFPATH *eq '0') THEN(SNDPGMMSG + MSGID(CPF9898) MSGF(QCPFMSG) + MSGDTA('Wrong PDF Path') MSGTYPE(*ESCAPE)) /* Dummy change to see if the directory exists */ CHGVAR VAR(&STATUS) VALUE('2') CHGVAR VAR(&PDFPATH) VALUE(&pdfpath *tcat '/') CD DIR(&PDFPATH) /* Test the pdf name length */ IF COND('0' *BCAT &PDF *EQ '0') THEN(SNDPGMMSG + MSGID(CPF9898) MSGF(QCPFMSG) + MSGDTA('Wrong PDF name') MSGTYPE(*ESCAPE)) /* Test the notes length */ IF COND('0' *BCAT &NOTES *EQ '0') THEN(SNDPGMMSG + MSGID(CPF9898) MSGF(QCPFMSG) + MSGDTA('Notes are blank') MSGTYPE(*ESCAPE)) /* Delete the log file */ CHGVAR VAR(&LOGFILE) VALUE(&pdfpath *tcat &pdf + *tcat '.log') RMVLNK OBJLNK(&LOGFILE) MONMSG MSGID(CPFA093 CPFA0A9) /* Create a temp file member to store spooled files */ CHGVAR VAR(&STATUS) VALUE('3') CHKOBJ OBJ(QGPL/TMPSPOOL) OBJTYPE(*FILE) MONMSG MSGID(CPF9801) EXEC(CRTPF + FILE(QGPL/TMPSPOOL) RCDLEN(199) + MBR(M000000000) MAXMBRS(*NOMAX) SIZE(*NOMAX)) /* Add a new member using counter increament */ RTVMBRD FILE(QGPL/TMPSPOOL) MBR(*LAST) RTNMBR(&MEMBER) CHGVAR VAR(&COUNTCHAR) VALUE(%SST(&MEMBER 2 9) ) CHGVAR VAR(&COUNTDEC) VALUE(&COUNTCHAR) CHGVAR VAR(&COUNTDEC) VALUE(&COUNTDEC+1) CHGVAR VAR(&COUNTCHAR) VALUE(&COUNTDEC) CHGVAR VAR(&MEMBER) VALUE('M' *CAT &COUNTCHAR) ADDPFM FILE(QGPL/TMPSPOOL) MBR(&MEMBER) /* Copy spooled file to temp file member */ CHGVAR VAR(&STATUS) VALUE('4') CPYSPLF FILE(&FILE) TOFILE(QGPL/TMPSPOOL) + JOB(&JOBNBR/&USER/&JOBNAME) + SPLNBR(&SPLNBR) TOMBR(&MEMBER) + MBROPT(*REPLACE) CTLCHAR(*FCFC) /* Prepare java call */ CHGVAR VAR(&STATUS) VALUE('5') CD DIR(&PDFPATH) CHKOBJ OBJ(QTEMP/STDOUT) OBJTYPE(*FILE) MONMSG MSGID(CPF9801) EXEC(CRTPF FILE(QTEMP/STDOUT) + RCDLEN(96)) CLRPFM FILE(QTEMP/STDOUT) OVRDBF FILE(STDOUT) TOFILE(QTEMP/STDOUT) CHGVAR VAR(&JAVA) VALUE('java -classpath + /QIBM/ProdData/OS400/jt400/lib/jt400Native.+ jar:/spltopdf/iText.jar:. spltopdf' *BCAT + &PDFPATH *BCAT &PDF *BCAT &LENGTH *BCAT + &WIDTH *BCAT '"' *BCAT &NOTES *BCAT '" + qgpl tmpspool' *BCAT &MEMBER) STRQSH CMD(&JAVA) /* Remove temp file member */ RMVM FILE(QGPL/TMPSPOOL) MBR(&MEMBER) /* If log file exists then the PDF file has created */ RMVLNK OBJLNK(&LOGFILE) MONMSG MSGID(CPFA0A9) EXEC(GOTO CMDLBL(FAILED)) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Spooled + file' *BCAT &FILE *BCAT 'converted to' + *BCAT &PDFPATH *TCAT &PDF *TCAT '.PDF') RETURN FAILED: SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Spooled + file' *BCAT &FILE *BCAT 'conversion failed') RETURN ERROR: IF COND(&STATUS = '1') THEN(CHGVAR + VAR(&MESSAGE) VALUE('Spooled File not exist')) ELSE CMD(IF COND(&STATUS = '2') THEN(CHGVAR + VAR(&MESSAGE) VALUE('PDF Path not exist'))) ELSE CMD(IF COND(&STATUS = '3') THEN(CHGVAR + VAR(&MESSAGE) VALUE('Error in Temporary + File'))) ELSE CMD(IF COND(&STATUS = '4') THEN(CHGVAR + VAR(&MESSAGE) VALUE('Error during Spooled + file Process'))) ELSE CMD(IF COND(&STATUS = '5') THEN(CHGVAR + VAR(&MESSAGE) VALUE('Error during Java + Process'))) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) + MSGDTA(&MESSAGE) MSGTYPE(*ESCAPE) EXIT: ENDPGM /************************************************************************/ /* crtclasscl: */ /* Create spltopdf.class */ /* classpath: */ /* jt400Native.jar : /QIBM/ProdData/OS400/jt400/lib/jt400Native.jar */ /* iText.jar : /SPLTOPDF/iText.jar */ /* iTextXML.jar : /SPLTOPDF/iTextXML.jar */ /* iTextHYPH.jar : /SPLTOPDF/iTextHYPH.jar */ /* iText classes : /SPLTOPDF/com/lowagie/... */ /************************************************************************/ PGM ADDENVVAR ENVVAR(CLASSPATH) + VALUE('/QIBM/ProdData/OS400/jt400/lib/jt400+ Native.jar:/spltopdf/iText.jar:/javapdf/iTe+ xtXML.jar:/spltopdf/iTextHYPH.jar:.') MONMSG MSGID(CPFA980) CD DIR('/spltopdf') QSH CMD('javac /spltopdf/spltopdf.java') ENDPGM // name: spltopdf.java // Parameters: // PDFPATH Folder where to create PDF // PDFNAME The PDF name // ROWS The number of rows of spooled file // COLS The number of columns of spooled file // FOOTERcomments Comments written in PDF footer // LIBRARY The library where the work file belongs // FILE The work file name // MEMBER The member of the work file where has been copied the spooled file import java.io.*; import com.ibm.as400.access.*; // Import the iText Free Java-PDF library, http://www.lowagie.com/iText import com.lowagie.text.*; import com.lowagie.text.pdf.PdfWriter; import com.lowagie.text.pdf.BaseFont; public class spltopdf extends Object{ public static void main(String[] parameters){ if (parameters.length == 8 ){ try { String PDFPATH = parameters[0]; String PDFNAME = parameters[1]; String ROWS = parameters[2]; String COLS = parameters[3]; String FOOTERcomments = parameters[4]; String LIBRARY = parameters[5]; String FILE = parameters[6]; String MEMBER = parameters[7]; int RecordLength = Integer.valueOf(COLS).intValue(); AS400 as400 = new AS400(); // Define the work file (the first field is the control char FCFC) CharacterFieldDescription rFCFC = new CharacterFieldDescription(new AS400Text(1, as400), "rFCFC"); CharacterFieldDescription rLINE = new CharacterFieldDescription(new AS400Text(RecordLength, as400), "rLINE"); RecordFormat TmpSpool = new RecordFormat("TmpSpool"); TmpSpool.addFieldDescription(rFCFC); TmpSpool.addFieldDescription(rLINE); QSYSObjectPathName filename = new QSYSObjectPathName(LIBRARY, FILE, MEMBER, "MBR"); SequentialFile file = new SequentialFile(as400, filename.getPath()); file.setRecordFormat(TmpSpool); file.open(SequentialFile.READ_ONLY, 100, SequentialFile.COMMIT_LOCK_LEVEL_NONE); System.out.println("Start Creation of "+ PDFPATH+PDFNAME+".pdf"); try { // Create the courier.ttf font object BaseFont courier = BaseFont.createFont("courier.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); Font font = new Font(courier, 10f); // The fontsize is 10 float f = courier.getWidthPoint("0123456789", 10f); // length of 10 fixed characters width float Xpoints = Float.valueOf(COLS).floatValue() * f / 10 + 72 ; // the page width in pixels // leading = the space between two lines, that is 1.5 times the fontsize int leading = 15 ; float Ypoints = (Float.valueOf(ROWS).floatValue() + 5) * leading + 72 ; //The page height in pixels // Create the Rectangle object in a certain color and use this as pageSize Rectangle pageSize = new Rectangle(Xpoints, Ypoints); pageSize.setBackgroundColor(new java.awt.Color(0xFF, 0xFF, 0xDE)); Document document = new Document(pageSize,36,36,36,36); // The four margins have 36 pixels (0.5 of inch) // Create an instance of the com.lowagie.text.Document object PdfWriter.getInstance(document, new FileOutputStream(PDFPATH+PDFNAME+".pdf")); document.addTitle("Was created with Java on iSeries"); document.addSubject("Example of fixed width fonts like Courier"); document.addKeywords("SpltoPDF"); document.addCreator("MM"); document.addAuthor("MM"); document.addHeader("Expires", "0"); // Add footer with notes HeaderFooter footer = new HeaderFooter(new Paragraph(leading,FOOTERcomments,font), false); footer.setAlignment(Element.ALIGN_RIGHT); document.setFooter(footer); // Add watermak to the middle right place of the page and scale to fit according to the margin size // Change the layout of the watermark according to the needed standards try { float ImageScale = 36; Watermark watermark = new Watermark(Image.getInstance("watermark.jpg"), Xpoints-ImageScale, (Ypoints-ImageScale)/2); watermark.scaleToFit(ImageScale,ImageScale); document.add(watermark); } catch(Exception e) { System.out.println("watermark.jpg not found"); System.exit(0); } document.open(); Record data = file.readNext(); // Read first record of work file boolean FirstTime = true; String NewPage = "1"; String SpaceBeforeOneLine = "0"; String SpaceBeforeTwoLines = "-"; String fcfc = " "; String linef = ""; while (data != null) { if (FirstTime) FirstTime = false; else fcfc = (String) data.getField("rFCFC"); linef = (String) data.getField("rLINE"); // According to the value of control char FCFC create new line, lines or page if ( fcfc.compareTo(NewPage)==0 ) { document.newPage(); } if ( fcfc.compareTo(SpaceBeforeOneLine)==0 ) { document.add(new Paragraph(leading, " ", font)); } if ( fcfc.compareTo(SpaceBeforeTwoLines)==0 ) { document.add(new Paragraph(leading, " ", font)); document.add(new Paragraph(leading, " ", font)); } document.add(new Paragraph(leading, linef, font)); // add a spooled file line to PDF data = file.readNext(); // Read next record of work file } document.close(); // Create an EventLog file as success sign EventLog myLog = new EventLog(PDFPATH+PDFNAME+".log"); myLog.log("OK"); as400.disconnectAllServices(); } catch(DocumentException de) { System.out.println(de.getMessage()); System.exit(0); } catch(IOException ioe) { System.out.println(ioe.getMessage()); System.exit(0); } } catch (Exception e) { System.out.println("Could not read the work file"); System.out.println(e.getMessage()); System.exit(0); } } else { System.out.println(""); System.out.println("Parameters are not correct."); System.out.println(""); System.out.println("Command syntax is: spltopdf path name rows cols notes library file member"); System.out.println(""); System.out.println("Syntax example is: spltopdf /mypdf order 66 198 Demo qgpl tmpspool m000001"); System.out.println(""); } System.exit(0);} }