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.

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);}
}


This was first published in September 2002

Dig deeper on iSeries CL programming

0 comments

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

SearchEnterpriseLinux

SearchDataCenter

Close