印刷の結果を PDF としてブラウザに表示する方法

印刷の結果としてのスプールを PDF 化してブラウザに戻す方法について解説します。
ここに示すサンプルは 出力を *PDF と指定された場合は、
印刷スプールを CVTSPLF コマンドで PDF 化します。
ブラウザへ PDF を戻すための HTTP サーバーが必要となりますが、
Spoolライター の HTTP サーバーがこの役に立ちます。

【 サンプル 】PGM106: 商品マスター 一覧表
                         商品マスター一覧表  (PGM106)          
                                                               
選択項目を入力して,実行キーを押してください。                 
                                                               
品種コード  . . . . . . . . . .                  から          
                                  9999           まで          
商品コード  . . . . . . . . . .                  から          
                                  9999999999     まで          
出力  . . . . . . . . . . . . .   *PDF          *PRINT, *PDF   
【 PGM106: CMD 】
0001.00              CMD        PROMPT(' 商品マスター一覧表 ')                 
0002.00              PARM       KWD(HNSFROM) TYPE(*CHAR) LEN(4) CHOICE(*PGM) + 
0003.00                           CHOICEPGM(QTROBJ/PGM106P) +                  
0004.00                           PROMPT(' 品種コード ')                       
0005.00              PARM       KWD(HNSEND) TYPE(*CHAR) LEN(4) DFT(9999) +     
0006.00                           CHOICE(*PGM) CHOICEPGM(QTROBJ/PGM106P)       
0007.00              PARM       KWD(SHFROM) TYPE(*CHAR) LEN(10) CHOICE(*PGM) + 
0008.00                           CHOICEPGM(QTROBJ/PGM106P) +                  
0009.00                           PROMPT(' 商品コード ')                       
0010.00              PARM       KWD(SHEND) TYPE(*CHAR) LEN(10) +               
0011.00                           DFT(9999999999) CHOICE(*PGM) +               
0012.00                           CHOICEPGM(QTROBJ/PGM106P)                    
0013.00              PARM       KWD(OUTPUT) TYPE(*CHAR) LEN(8) RSTD(*YES) +    
0014.00                           DFT(*PDF) VALUES(*PRINT *PDF) +              
0015.00                           PROMPT(' 出力 ')                             
【 サンプルCLP: PGM106CL 】
0001.00              PGM        PARM(&HNSFROM &HNSEND &SHFROM &SHEND &OUTPUT)  
0002.00 /*-------------------------------------------------------------------*/
0003.00 /*   PGM106CL :   商品マスター一覧表                                 */
0004.00 /*                                                                   */
0005.00 /*   この CLP:PGM106CL はコマンド PGM106 から呼び出されて            */
0006.00 /*   実行されます。                                                  */
0007.00 /*                                                                   */
0008.00 /*   この適用業務は 5250 環境 / AUTOWEB 環境のどちらでも             */
0009.00 /*   実行することができます。                                        */
0010.00 /*                                                                   */
0011.00 /*   5250 環境で実行した場合は印刷出力イメージは OUTQ に保管され     */
0012.00 /*   ますが AUTOWEB 環境で実行した場合や PDF が指定された場合は      */
0013.00 /*   PDF がブラウザ上に表示されます。                                */
0014.00 /*   ブラアザへの表示は SPOOL ライターの HTTP サーバーによって       */
0015.00 /*   リダイレクトされて表示されます。                                */
0016.00 /*                                                                   */
0017.00 /*   [ 注 ] PDF 変換には SPOOL ライターが導入されている必要が        */
0018.00 /*          あります。                                               */
0019.00 /*-------------------------------------------------------------------*/
0020.00              DCL        VAR(&HNSFROM) TYPE(*CHAR) LEN(4)               
0021.00              DCL        VAR(&HNSEND) TYPE(*CHAR) LEN(4)                 
0022.00              DCL        VAR(&SHFROM) TYPE(*CHAR) LEN(10)                
0023.00              DCL        VAR(&SHEND) TYPE(*CHAR) LEN(10)                 
0024.00              DCL        VAR(&SHEND) TYPE(*CHAR) LEN(10)                 
0025.00              DCL        VAR(&OUTPUT) TYPE(*CHAR) LEN(8)                 
0026.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                  
0027.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                  
0028.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                  
0029.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)               
0030.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)               
0031.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                   
0032.00              DCL        VAR(&TOMSGQ) TYPE(*CHAR) LEN(10)                
0033.00       /*( PDF 出力に必要な変数 )*/                                      
0034.00              DCL        VAR(&DEV) TYPE(*CHAR) LEN(10)                   
0035.00              DCL        VAR(&OPT) TYPE(*CHAR) LEN(4) VALUE(X'00000002') 
0036.00              DCL        VAR(&ERR) TYPE(*CHAR) LEN(1)                    
0037.00              DCL        VAR(&USER) TYPE(*CHAR) LEN(10)                  
0038.00              DCL        VAR(&JOB) TYPE(*CHAR) LEN(10)                   
0039.00              DCL        VAR(&JOBNBR) TYPE(*CHAR) LEN(6)                 
0040.00              DCL        VAR(&PDF_FILE) TYPE(*CHAR) LEN(48)              
0041.00              DCL        VAR(&PCCMD) TYPE(*CHAR) LEN(123)                
0042.00              DCL        VAR(&IPADDR) TYPE(*CHAR) LEN(15)            
0043.00       /*( IFS の削除に必要な変数 )*/                                
0044.00              DCL        VAR(&DATE) TYPE(*CHAR) LEN(6)               
0045.00              DCL        VAR(&TIME) TYPE(*CHAR) LEN(6)               
0046.00              DCL        VAR(&HH) TYPE(*DEC) LEN(2 0)                
0047.00              DCL        VAR(&HHC) TYPE(*CHAR) LEN(2)                
0048.00              DCL        VAR(&MM) TYPE(*DEC) LEN(2 0)                
0049.00              DCL        VAR(&MMC) TYPE(*CHAR) LEN(2)                
0050.00              DCL        VAR(&SS) TYPE(*DEC) LEN(2 0)                
0051.00              DCL        VAR(&SSC) TYPE(*CHAR) LEN(2)                
0052.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))     
0053.00                                                                     
0054.00              RTVJOBA    JOB(&JOB) TYPE(&TYPE)                       
0055.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */ 
0056.00              CHGVAR     VAR(&TOMSGQ) VALUE('*SYSOPR   ')            
0057.00              ENDDO      /*  バッチ  */                              
0058.00              ELSE       CMD(DO) /*  対話式  */                      
0059.00              CHGVAR     VAR(&TOMSGQ) VALUE('*TOPGMQ   ')            
0060.00              ENDDO      /*  対話式  */                              
0061.00                                                                     
0062.00              RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE)                 
0063.00              RTVSYSVAL  SYSVAL(QTIME) RTNVAR(&TIME)                 
0064.00              CHGJOB     STSMSG(*NORMAL)                             
0065.00                                                                     
0066.00              IF         COND(%SWITCH(XXXXXXX0)) THEN(DO)            
0067.00     /*( 作業進行中メッセージの表示 )*/                              
0068.00              SNDPGMMSG  MSGID(CPF9800) MSGF(QSYS/QCPFMSG) +         
0069.00                           MSGDTA(' 商品一覧表を印刷中。 ') +        
0070.00                           TOPGMQ(*EXT) MSGTYPE(*STATUS)             
0071.00              ENDDO                                                  
0072.00 /*-------------------------------------------------------------*/   
0073.00 /*( 1 )  印刷プログラム PGM106 を呼び出して実行する            */   
0074.00 /*-------------------------------------------------------------*/   
0075.00              IF         COND(&OUTPUT *EQ '*PDF    ') THEN(DO)       
0076.00              OVRPRTF    FILE(QPRINT) HOLD(*YES) SECURE(*YES) +      
0077.00                           OVRSCOPE(*JOB)                            
0078.00              ENDDO                                                  
0079.00              OVRDBF     FILE(SHOHINL1) TOFILE(QTRFIL/SHOHINL1) +    
0080.00                           SECURE(*YES) OVRSCOPE(*JOB)               
0081.00              CALL       PGM(QTROBJ/PGM106) PARM(&HNSFROM &HNSEND +  
0082.00                           &SHFROM &SHEND)                           
0083.00              DLTOVR     FILE(SHOHINL1) LVL(*JOB)                    
0084.00 /*-------------------------------------------------------------------*
0085.00 /*   *PDF が要求された場合 PDF に変換して                              */
0086.00 /*   さらに PDF を WEB 表示する                                            */
0087.00 /*-------------------------------------------------------------------*
0088.00              IF         COND(&OUTPUT *EQ '*PDF      ') THEN(DO)       
0089.00 /*-------------------------------------------------------------*/     
0090.00 /*( 2 )  QPRTJOB の JOB 番号を検索する                         */     
0091.00 /*-------------------------------------------------------------*/     
0092.00              RTVJOBA    JOB(&JOB) USER(&USER) NBR(&JOBNBR)            
0093.00              CALL       PGM(ASNET.COM/PRTJOBNO) PARM(&USER &JOBNBR)   
0094.00 /*-------------------------------------------------------------*/     
0095.00 /*( 3 )  SPOOL ライターによって PDF に変換して IFS に保管する  */     
0096.00 /*-------------------------------------------------------------*/     
0097.00              CHGVAR     VAR(&PDF_FILE) VALUE('PDF' *CAT &JOBNBR +     
0098.00                           *TCAT '.PDF')                               
0099.00              /*------------------------------------------------*/     
0100.00              /*   印刷 PDF の場合は PDF を表示しないで         */     
0101.00              /*   そのまま印刷する                             */     
0102.00              /*------------------------------------------------*/     
0103.00              IF         COND(&OUTPUT *EQ '*PRINT  ') THEN(DO)         
0104.00              SPOOLWTR/CVTSPLF SPLF(QPRINT) JOB(&JOBNBR/&USER/&JOB) +  
0105.00                           SPLNO(*LAST) OUTPUT(*PDF) OPTION(*PRINT) +   
0106.00                           TOSTMF(&PDF_FILE) +                          
0107.00                           TODIR('/SPOOLWTR/TEMP')                      
0108.00              ENDDO                                                     
0109.00              /*------------------------------------------------*/      
0110.00              /*   表示 PDF の場合は IFS に保管した PDF を      */      
0111.00              /*   PC オーガナイザーで表示する。                */      
0112.00              /*------------------------------------------------*/      
0113.00              ELSE       CMD(DO)                                        
0114.00              SPOOLWTR/CVTSPLF SPLF(QPRINT) JOB(&JOBNBR/&USER/&JOB) +   
0115.00                           SPLNO(*LAST) OUTPUT(*PDF) OPTION(*IFS) +     
0116.00                           TOSTMF(&PDF_FILE) +                          
0117.00                           TODIR('/SPOOLWTR/TEMP')                      
0118.00              ENDDO                                                     
0119.00              DLTSPLF    FILE(QPRINT) JOB(&JOBNBR/&USER/&JOB) +         
0120.00                           SPLNBR(*LAST)                                
0121.00 /*-------------------------------------------------------------*/      
0122.00 /*( 4 ) IFS に保存されている PDF を表示する                    */      
0123.00 /*-------------------------------------------------------------*/      
0124.00              /* GETIPADDR  IBM iの IP アドレスの取得  */          
0125.00              /* エラーがあれば E に 'E' が入る */                      
0126.00              CHGVAR     VAR(&DEV) VALUE(&JOB)                        
0127.00              CALL       PGM(SPOOLWTR/GETIPADDR) PARM(&DEV &IPADDR +  
0128.00                           &MSG &ERR &OPT)                            
0129.00              IF         COND(&ERR *EQ 'E') THEN(DO)                  
0130.00              GOTO       SNDMSG                                       
0131.00              ENDDO                                                   
0132.00              CHGVAR     VAR(&PCCMD) VALUE('START HTTP://' *CAT +     
0133.00                           &IPADDR *TCAT ':3007/SPOOLWTR/TEMP/' *CAT +
0134.00                           &PDF_FILE)                                 
0135.00              /**************************************************/    
0136.00              /*  PDF 印刷出力の場合は *PRINT を付加しておくと  */    
0137.00              /*  VT5250 が印刷 PDF であると判断する            */    
0138.00              /**************************************************/    
0139.00              IF         COND(&OUTPUT *EQ '*PRINT  ') THEN(DO)        
0140.00              CHGVAR     VAR(&PCCMD) VALUE(&PCCMD *TCAT ' *PRINT')    
0141.00              ENDDO                                                   
0142.00              STRPCO     PCTA(*NO)                                    
0143.00              MONMSG     MSGID(IWS4010)                               
0144.00              STRPCCMD   PCCMD(&PCCMD) PAUSE(*NO)                     
0145.00 /*-------------------------------------------------------------*/    
0146.00 /*( 5 ) 10 分後に PDF を削除するように SBMJOB する             */    
0147.00 /*-------------------------------------------------------------*/       
0148.00              CHGVAR     VAR(&HH) VALUE(%SST(&TIME 1 2))                 
0149.00              CHGVAR     VAR(&MM) VALUE(%SST(&TIME 3 2))                 
0150.00              CHGVAR     VAR(&SS) VALUE(%SST(&TIME 5 2))                 
0151.00              CHGVAR     VAR(&MM) VALUE(&MM + 10)                        
0152.00              IF         COND(&MM >= 60) THEN(DO)                        
0153.00              CHGVAR     VAR(&HH) VALUE(&HH + 1)                         
0154.00              CHGVAR     VAR(&MM) VALUE(1)                               
0155.00              ENDDO                                                      
0156.00              CHGVAR     VAR(&HHC) VALUE(&HH)                            
0157.00              CHGVAR     VAR(&MMC) VALUE(&MM)                            
0158.00              CHGVAR     VAR(&SSC) VALUE(&SS)                            
0159.00              CHGVAR     VAR(&TIME) VALUE(&HHC *CAT &MMC *CAT &SSC)      
0160.00              SBMJOB     CMD(RMVLNK OBJLNK(&PDF_FILE)) JOB(DLTPDF) +     
0161.00                           SCDDATE(&DATE) SCDTIME(&TIME) MSGQ(*NONE)     
0162.00              ENDDO                                                      
0163.00 /*-------------------------------------------------------------------*/ 
0164.00 /*  5250 エミュレータで実行されている場合は完了メッセージを出力して  */ 
0165.00 /*   終了する。                                                                        */ 
0166.00 /*-------------------------------------------------------------------*/ 
0167.00              ELSE       CMD(DO)                                         
0168.00              SNDPGMMSG  MSG(' 商品マスター一覧表を出力しました。 ') +   
0169.00                           MSGTYPE(*DIAG)                                
0170.00              ENDDO                                                      
0171.00              RETURN                                                     
0172.00                                                                         
0173.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +             
0174.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +   
0175.00                           MSGFLIB(&MSGFLIB)                             
0176.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                   
0177.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +     
0178.00                           TOMSGQ(&TOMSGQ) MSGTYPE(*ESCAPE)              
0179.00              ENDDO                                                      
0180.00              ELSE       CMD(DO)                                         
0181.00              SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +            
0182.00                           MSGDTA(&MSGDTA) TOMSGQ(&TOMSGQ) +             
0183.00                           MSGTYPE(*ESCAPE)                              
0184.00              ENDDO                                                      
0185.00              ENDPGM                                                     
【 解説 】
  1. OVRPRTF コマンドで印刷ファイルを *HOLD に一時変更して、
    プリンターに出力されてしまうのを防止します。
  2. 印刷出力プログラムを実行します。
    ここでは Spoolライター の API プログラム: PRTJOBNO によってユーザー名とジョブ番号を
    検索して受け取っていますが、これが対話式で実行されるプログラムであれば、
    PRTJOBNO による検索は必要ありません。
    ただし PRTJOBNO とは、このジョブがバッチ・ジョブとして投入されて実行されるのであれば、
    ジョブ名は QPRTJOB となり、ジョブ番号も QPRTJOB 別の独自の番号が発生します。
    PRTJOBNO の呼出しはこのようなバッチ・ジョブの場合にも想定されています。
    対話式での実行ではこの処理は必要ありません。
  3. Spoolライターの CVTSPLF コマンドを使って最後に出力された印刷スプールを、
    PDF に変換して IFS に保存します。
  4. IFS に保存されている PDF を表示するために HTTP リクエストを作成します。
    このときこの例では Spoolライター の API であるプログラム GETIPADDR によって、
    IBM i の IP アドレスを取得していますが、一般的に社内使用するのであれば、
    IPアドレス : &IPADDR に直接、IBM i の IP アドレスを設定してください。
    またこのとき &IPADDR に PORT : 3007 を指定していることに注目してください。
    3007 は Spoolライター の PORT 番号です。
    Spoolライター のサーバーは On the Web 機能として Spoolライター の管理に使われますが、
    同時に HTTP サーバーでもあります。
    したがってここでは、Spoolライター のサーバーを HTTP サーバーとして利用しています。
  5. 10分後に IFS に保管した PDF が自動消去されるようにバッチ・ジョブに命令を投入します。