Upload
duongque
View
213
Download
0
Embed Size (px)
Citation preview
3/18/2012
1
Do-It-Yourself Web
Reports!
By Trevor Seeney
Agenda• Web-enablement on the IBM/i
• A simple web report
• A CL program that converts spool files to HTML
• Using Data-Queues to automate the conversion of
spool files to HTML
• Putting on some style
• Maintaining the page advance when printing
• Using RPG Special files to create Real Time web-
reports
3/18/2012
2
The IBM/I HTTP server
• The IBM/i comes shipped with a default
HTTP server configured named
APACHEDFT
• This HTTP server renders HTML
documents from the IFS directory with the
path “/www/apachedft/htdocs”
• An HTML document is simply a text
document that has ‘tags’ that instruct a
browser to render the text in a specified
manner.
An Example HTML DocumentAn example HTML document :-
<html>
<head>
<title>Hello</title>
</head>
<body>
<b>Hello</b>
</body>
</html>
When opened in a browser, the word
‘Hello’ is rendered in bold face into the browser
http://{your-server}/hello.html
3/18/2012
3
An Example HTML Document (continued)
• Try in a DB2 source file (QHTMLSRC say)
• Using the IFS command Copy To Import File (CPYTOIMPF) command, copy the source member to the aforementioned IFS directory:-
• CPYTOIMPF mylib/QHTMLSRC hello ’/www/apachedft/htdocs/Hello.html’
• Change authority:
• CHGAUT ’/www/apachedft/htdocs/Hello.html’ *RWX
A Simple Web Report
• Generally, browsers treat spaces, new lines,
carriage returns, etc. as ‘white space’ and
compresses them during rendering.
• If this were to occur to ‘green-screen’ reports, all of
the column alignments would be off
• To prevent this, use the HTML tag <PRE> which stands
for ‘preformatted’.
• We will include our entire report between <PRE> and
</PRE> tags and the column spacing and alignment will
be maintained.
3/18/2012
4
An Example Report
Our Sample Report as HTML
<html>
<head>
<title>My First Web Report</title>
</head>
<body>
<img src="ReportLogo.png"> <b>IBM/i Web Reports</b>
<HR>
<pre>
Program-ID My Consulting Group Date: 07/11/11
DEMORPT1 Product Codes by Date Page: 1
First Part Model Wholesale Retail Volume
Ship Date Number Price Price Discount
2001-01-05 00004 AR-99 3.96 4.00 N
2001-01-26 00004 AR-12 1.76 2.00 N
2003-07-01 00004 AR-13 4.35 5.00 Y
2000-06-04 00005 AR-1 2.97 3.00 Y
2001-02-02 00005 AR-10 4.50 5.00 Y
2004-05-17 00005 AR-11 1.78 2.00 Y
2002-07-23 00005 AR-12 3.52 4.00 Y
2001-08-16 00013 AR-1 110.42 124.07 N
2001-04-05 00013 AR-10 158.88 198.60 Y
2003-07-22 00013 AR-11 156.80 198.48 N
2003-10-09 00013 AR-13 153.06 198.78 Y
2000-11-14 00014 AR-1 43.56 44.00 Y
2002-01-11 00014 AR-10 6.30 7.00 N
2000-12-11 00014 AR-13 38.28 44.00 N
</pre><HR></body></html>
3/18/2012
5
Our Sample Report rendered in the browser
Some comments on our report
• Not yet a thing of beauty but it is better
than the ‘green-screen’ equivalent.
• The Header and Footer text could be
standard and reside in their own source
members in QHTMLSRC
(called Header and Footer – say)
3/18/2012
6
A spool-file to HTML conversion routine
/* ****************************************************************/
/* This program converts a spool-file to an .HTML file */
/* ****************************************************************/
PGM PARM(&SPLFILE)
/* Input Parameter */
DCL VAR(&SPLFILE) TYPE(*CHAR) LEN(10)
/* Working Variable Declarative */
DCL VAR(&HTML) TYPE(*CHAR) LEN(200)
/* Format .html file name */
CHGVAR VAR(&HTML) VALUE('/www/apachedft/htdocs/' +
*CAT &SPLFILE *TCAT '.html')
Copy HEADER source */
/* QGPL/HTML /* created using CRTPF FILE(QGPL/HTML) RCDLEN(200) */CPYF FROMFILE(QGPL/QHTMLSRC) TOFILE(QGPL/HTML) +
FROMMBR(HEADER) MBROPT(*REPLACE) +
FMTOPT(*CVTSRC)
/* Copy Spool file records */
CPYSPLF FILE(&SPLFILE) TOFILE(QGPL/HTML) +
SPLNBR(*LAST) MBROPT(*ADD)
/* Copy FOOTER source */
CPYF FROMFILE(QGPL/QHTMLSRC) TOFILE(QGPL/HTML) +
FROMMBR(FOOTER) MBROPT(*ADD) FMTOPT(*CVTSRC)
/* Copy HTML to IFS */
CPYTOIMPF FROMFILE(QGPL/HTML) TOSTMF(&HTML) +
MBROPT(*REPLACE) RCDDLM(*CRLF) DTAFMT(*FIXED)
/* Apply Authority */
CHGAUT OBJ(&HTML) USER(*PUBLIC) DTAAUT(*RWX) +
OBJAUT(*ALL)
RETURN
ENDPGM
A
B
C
D
E
F
G
Automating Report conversion to
HTML using Data-Queues
• There is a little known fact that a data-queue can be attached to an output-queue.
• CRTOUTQ OUTQ(MYOUTQ) DTAQ(MYDTAQLIB/MYDTAQ)
• When a report arrives in the output-queue, an entry
is sent to the data-queue.
• A program can be written to wake-up every time an entry arrives in the data-queue and extract the report and convert it into HTML and transfer it to
the IFS.
3/18/2012
7
Look Mum “No Hands”/* ************************************************************/
/* This program converts spool-files to .HTML files */
/**************************************************************/
/* Working Variable Declaratives */
DCL VAR(&JOB) TYPE(*CHAR) LEN(10)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&NUM) TYPE(*CHAR) LEN(6)
DCL VAR(&SPLFILE) TYPE(*CHAR) LEN(10)
DCL VAR(&SPLFNBR) TYPE(*DEC) LEN(4)
DCL VAR(&SPLFNBRC) TYPE(*CHAR) LEN(4)
DCL VAR(&WAIT) TYPE(*DEC) LEN(5 0) VALUE(-1)
DCL VAR(&HTML) TYPE(*CHAR) LEN(200)
/* Get Data Queue Entry */
RCVDTAQ: CALL PGM(QRCVDTAQ) PARM( 'MYDTAQ' 'MYDTAQLIB' +
200 &DATA &WAIT)
/* Calc Spoolfile info from Data Queue Entry */
CHGVAR VAR(&JOB) VALUE(%SST(&DATA 13 10))
CHGVAR VAR(&USER) VALUE(%SST(&DATA 23 10))
CHGVAR VAR(&NUM) VALUE(%SST(&DATA 33 6))
CHGVAR VAR(&SPLFILE) VALUE(%SST(&DATA 39 10))
CHGVAR VAR(&SPLFNBR) VALUE(%BIN(&DATA 49 4))
CHGVAR VAR(&SPLFNBRC) VALUE(&SPLFNBR) /* Format .html file name */
CHGVAR VAR(&HTML) VALUE('/www/apachedft/htdocs/' +
*CAT &SPLFILE *TCAT '.html')
/* Copy HEADER source */
/* QGPL/HTML created using CRTPF FILE(QGPL/HTML) RCDLEN(200) */CPYF FROMFILE(QGPL/QHTMLSRC) TOFILE(QGPL/HTML) +
FROMMBR(HEADER) MBROPT(*REPLACE) +
FMTOPT(*CVTSRC)
/* Copy Spool file records */
CPYSPLF FILE(&SPLFILE) TOFILE(QGPL/HTML) +
JOB(&NUM/&USER/&JOB) SPLNBR(&SPLFNBRC) +
TOMBR(&SPLFILE) MBROPT(*ADD) /* Copy FOOTER source */
CPYF FROMFILE(QGPL/QHTMLSRC) TOFILE(QGPL/HTML) +
FROMMBR(FOOTER) MBROPT(*ADD) FMTOPT(*CVTSRC)
. . . .
A Bevy of Reports
• Using this technique would result in a bevy of HTML
reports in an IFS directory.
• A little bit of Shell (QSH) code could capture an
inventory of all the HTML reports in an IFS directory
into a DB2 file from which an index could be built.
/*****************************************************************/
/* This program lists the IFS reports directory to a DB2 File */
/*****************************************************************/
PGM
/* Working Variable Declaratives */
DCL VAR(&LSCOMMAND) TYPE(*CHAR) LEN(200)
CHGVAR VAR(&LSCOMMAND) VALUE('LS /www/apachedft/htdocs/' +
> +
/QSYS.LIB/QGPL.LIB/REPORTSPF.FILE/REPORTSPF.MBR')
QSH CMD(&LSCOMMAND)
RETURN
ENDPGM
3/18/2012
8
Putting on the Style• With very little effort one can add some style to the
web-report.
• The first report used the <HR> tag to put a
horizontal line across the page. This tag could be
replaced by an image files that provides a divider
with color and depth.
• By utilizing a language such as RPG, the original
report could be modified to enhance the rendering
of the report such as bolding the heading lines of
the report.
• The appearance of green-bar paper can even be
reproduced or as in my examplethat matter, pink-
bar paper.
Cascading Style Sheets
• There is a client-side web-technology known as
Cascading Style Sheets or just CSS for short.
• CSS is designed primarily to enable the separation
of document content from document presentation,
including elements such as the layout, colors, and
fonts.
• CSS directives are contained within <style> ..
and ..</style> tags and are of the format
element: style;
• For example: background-color: black;
• Using CSS together with the HTML <span> tag the
appearance of pink-bar paper can be created.
3/18/2012
9
Our Report Example with some Style added.
<head>
<title>My Second Web Report</title>
<style>
.color {
background-color: #FEDAE0;
width: 500px;
}
.white {
background-color: #FFFFFF;
width: 500px;
}
</style>
</head>
<body>
<img src="ReportLogo.png"> <b>IBM/i Web Reports</b><br>
<img src="http://www.sentinex.com/i2itopbar.jpg" width=500px; height=15px>
<pre>
<b>Program-ID SENTINEX INCORPORATED Date: 07/11/11</b>
<b>DEMORPT1 Product Codes by Date Page: 1</b>
<b>First Part Model Wholesale Retail Volume</b>
<b>Ship Date Number Price Price Discount</b>
<span class=color>2001-01-05 00004 AR-99 3.96 4.00 N</span>
. . . .. . .
. .. .. .
<span class=white>2000-12-11 00014 AR-13 38.28 44.00 N</span>
</pre>
<img src="http://www.sentinex.com/i2ibottombar.jpg" width=500px height=15px>
</body></html>
The Report with Style
3/18/2012
10
Page Advance
• A key consideration when transitioning green-screen reports to the browser is maintaining the
page advance when printing.
• There is a CSS technique that can be used to control page-advance and it is coded as follows:-
@media print {
p.TOP { page-break-before:always; }
}
• Whenever a page advance is called for in our green-screen report would need to write an additional line of HTML code:-
<p class=TOP> </p>
Reports on the Fly
• To this point we have produced static web-
pages representing reports.
• What about running reports directly in the
browser?
• Again this is surpisingly simple to do!
3/18/2012
11
Kudos to Jon Paris
• A decade or so ago Jon Paris had an “aha
moment” when he realized that RPG
Special files could be used to convert
existing report programs with program-
described printer files to run in the
browser.
The HTTP Server
• It might be necessary to change your HTTP server configuration to run CGI programs to run from your CGI program library, CGILIB (say)
• CGI programs utilize a service program which it is best placed in a binding directory.
• Not within the scope of this presentation, but feel free to contact me if guidance is needed to set this up.
• Reference: PowerPoint by Chris Adair -National Envelope “Getting Started with IBM HTTP Server Powered by Apache and CGI”
3/18/2012
12
RPG Special Files
• Back in the days of RPG II, if a program needed to
interface with a device not native to the language (e.g.
WORKSTN, DISK and PRINTER files) then they would
have to define the file as SPECIAL.
• When defining a SPECIAL file it is necessary to also
specify an “exit-point” program to be called to handle input and output.
• Whenever I/O is actioned against the file (Open, Close,
Read, Write, Update and Delete), control is transferred to
the exit-point program to execute the request.
• Jon realized that, if the exit-point program was an RPG
CGI program, then the report would render into the
browser when executed .
Our Sample Report Program
Program-ID My Consulting Group System Date: 11/18/02DEMORPT1 Product Codes by Date Page: 1
First Part Model Wholesale Retail VolumeShip Date Number Price Price Discount2001-01-05 00004 AR-99 3.96 4.00 N2001-01-26 00004 AR-12 1.76 2.00 N2003-07-01 00004 AR-13 4.35 5.00 Y2000-06-04 00005 AR-1 2.97 3.00 Y2001-02-02 00005 AR-10 4.50 5.00 Y2004-05-17 00005 AR-11 1.78 2.00 Y2002-07-23 00005 AR-12 3.52 4.00 Y2001-08-16 00013 AR-1 110.42 124.07 N2001-04-05 00013 AR-10 158.88 198.60 Y2003-07-22 00013 AR-11 156.80 198.48 N2003-10-09 00013 AR-13 153.06 198.78 Y2000-11-14 00014 AR-1 43.56 44.00 Y
3/18/2012
13
The RPG Program
FPRODUCT IP E K DISK
FQSYSPRT O F 132 PRINTER OFLIND(*INOF)*OQSYSPRT H 1P 1 02
O OR OFO 10 'Program-ID'O 40 'My Consulting Group'O 64 'System Date:'O UDATE Y 75O H 1P 1O OR OFO 10 'DEMORPT1 'O 40 'Product Codes by Date'O 64 'Page:'O PAGE Z 75O H 1P 1O OR OFO 5 'First'O 17 'Part'O 25 'Model'O 36 'Wholesale'O 48 'Retail'
Replacing PRINTER with
SPECIAL
• All one needs to do is copy the original program and replace the ‘PRINTER’ file specification with “SPECIAL” defined as the file type and the exit-point program name, like so:-
• FQSYSPRT O F 132 SPECIAL PGMNAME(MySpecialPgm)
• In addition to this change, all of the print control specifications, (skip-to, space-before and space-after) have to be removed because these only apply to PRINTER files.
3/18/2012
14
Our New Browser Report Program
FPRODUCT IP E K DISKFQSYSPRT O F 132 SPECIAL PGMNAME('SPECIAL')*
OQSYSPRT H 1P �skip/space control removed
O 10 'Program-ID'O 40 ‘My Consulting Group'O 64 'System Date:'O UDATE Y 75O H 1PO 10 'DEMORPT1 'O 40 'Product Codes by Date'O 64 'Page:'O PAGE Z 75O H 1PO 5 'First'O 17 'Part'O 25 'Model'O 36 'Wholesale'O 48 'Retail'
Our Exit Point Program
• The “exit-point” program has required parameters. These are as follows:-
• Parm. Len. Description
• --------- ------ ----------------------------------------
• Option A(1) where O=Open, C=Close, R=Read,
• W=Write, D=Delete and U=Update
• Status A(1) where 0=Normal, 1=Input EOF and 2=Error
• Error N(5,0) Error number placed in *RECORD of INFDS
• Area A(rcd-len) Field defined with the same record length specified on the "F" spec.
• All these parameters are loaded by the operating system. The parameter ‘Area’ will contain the
“print-line’ of the report.
3/18/2012
15
Our Exit Point Program (cont.)• In the case where a PRINTER file is being replaced by a SPECIAL file, there are only three I/O actions, Open, Close and Write.
• When control is received at file Open, the exit-point program needs to write out the some ‘header’ HTML to render the company logo, date and time,etc. But most importantly, it the HTML needs to end with <PRE> tag.
• Similarly, when control is received at file Close, the exit-point program needs to write out the </PRE>,</BODY> and </HTML> tags.
Our Exit Point Program
(cont.)
• When the print-line itself is received by the
exit-point program during the Write
operation, all that needs be done is to
push the received string through the API
that RPG CGI programs us to write to the
browser.
3/18/2012
16
The SPECIAL Program
***************************************************************** This program renders a report as an HTML file. *****************************************************************FSpecHtml IF E DISK RENAME(SpecHtml:SOURCE)
D WPError DSD EBytesP 1 4B 0 INZ(%Size(EData))D EBytesA 5 8B 0D EMsgId 9 15D EReserved 16 16D EData 17 56*D HTTPHeader C Const('Content-type: text/html')D CrLF C Const(X'15')*D WrtDta S 132D WrtDtaLen S 9B 0*D Option S 1
D Status S 1
D Error S 5 0
D Area S 132
*
The SPECIAL Program (cont)C *Entry Plist
C Parm OptionC Parm StatusC Parm ErrorC Parm Area*
C Select* Output Header at Open
C When Option = 'O'C Eval WrtDta = %Trim(HTTPHeader) + CrLf + CrLfC ExSr $WrtStOut*
C READ SpecHtmlC DOW (NOT %EOF)C Eval WrtDta = SRCDTAC ExSr $WrtStOutC READ SpecHtmlC EndDo* Output Footer at Close
C When Option = 'C'C Eval WrtDta = '</pre><HR></body></html>' + CrLfC ExSr $WrtStOutC Eval *INLR = *On* Output Spool FIle Record
C OtherC Eval WrtDta = AreaC ExSr $WrtStOut*
C EndSl
C Return
3/18/2012
17
The SPECIAL Program (cont.)
*****************************************************************C $WrtStOut BEGSRC Eval WrtDta = %Trim(WrtDta) + CrLfC Eval WrtDtaLen = %Len(%Trim(WrtDta))C CALLB 'QtmhWrStout'C PARM WrtDtaC PARM WrtDtaLenC PARM WPError
Running the report in the Browser
3/18/2012
18
Browser Report Commentary
• The report is rendered into the browser as
opposed to on paper or the spool-queue.
• Significant ease-of-use advantage
• Esthetically pleasing compared to printed
report or spool-queue equivalent.
• Achieved with minor changes to the
existing report program.
• But we can do more…
Some esthetic changes
• Firstly, it would be nice if the
heading stood out a little more.
• We can do this by detecting the
heading lines and making them
stand; color them blue (say).
3/18/2012
19
The code* D isDate S 3S 0 D isPage S 3S 0 *
D Line S 170
/Free // Highlight headings
isDate = %Scan('Date:':Area); isPage = %Scan('Page:':Area); If (isDate <> *Zero OR isPage <> *Zero); Line = '<font color=#0000ff>' + Area + '</font>';
Else; Line = Area;
EndIf;
More esthetic changes
• IMHO what really makes a web-report
stand out is replicating the appearance of
green-bar paper.
• I use a <span> tag with a class Id. to
convey the desired background color, or
just white.
• Additionally, I use the *LDA to record when
a colored or a white background was used
on the last execution of the Special File
processing program.
3/18/2012
20
The Green-Bar codeD LDA DS DTAARA(*LDA) D GB 132 132
// Output Spool File Record alternating between color and white backgroundIn LDA; If (GB = 'W');
Eval GB = 'C'; // Color Else;
Eval GB = 'W'; // White EndIf; Out LDA;
If (GB = 'C'); Eval WrtDta = '<span class=color>' +
Line + '</span>'; Else; Eval WrtDta = '<span class=white>' +
Line + '</span>'; EndIf;
The Result
3/18/2012
21
The Comparison – no contest!
More Commentary
• Once written, the same Special File
processing program can be used for
all of your reports, (use mine!).
• The implementation is simple,
replace the ‘Printer’ file with a
‘Special’ file, specify the processing
program name and remove all print-
control specifications.
3/18/2012
22
In Conclusion
• Rendering reports into the browser could effectively replace the use of sub-files. A lot of the complexities of writing a sub-file program vanish by doing this, in particular scrolling and printing because these are handled by the browser.
• The journeyman programmer could use the techniques I described herein to modernize to the web without first learning the open-source techniques.
Do-It-Yourself Web Reports!
Trevor Seeney
201-681-9301