Article Index
Nathan M. Andelin   November 2016

IBM i Modernization - The User Interface

(Part 13)

I believe that part of modernizing the user interface includes using web technologies to generate nicely formatted and stylized printer output, which is often an improvement over spool files (whether text, or text with overlays, or Advanced Function Printing (AFP) on IBM i).

Streaming printer output to IFS directories may also facilitate the exchange and archival of reports; That may be an improvement over retaining spool files in IBM i output queues.

Text based spool files are simple to create, though visually unappealing. Over a period of years it has surprised me to hear many situations where IBM i programmers struggle with getting IBM's advanced-function printing (AFP) to work for them. I believe that HTML and CSS offer a better alternative.

Producing reports is a little different than generating web pages; reports have specific page sizes (i.e. 8.5" x 11.0", and others), orientation (portrait and landscape; they may have page sides (i.e. front and back), headers and footers that may need to be printed at the top and bottom of each page (may include page number).

W3C specifications that support printed output tend to be less known than ones that support screen output. But they do exist, thankfully. This makes it nice in that your knowledge and skills with HTML and CSS can be used to produce printed output that may include graphics, charts, backgrounds, and other styling that visually enriches the output.

My Approach to Report Generation

My approach that I'll explain with sample code in the next article often entails:

  1. Creating one or more SQL views that contain the data desired in the report (table joins, summaries, etc.).
  2. Creating an HTML template that defines report bands (page headings, page detail, page-break summaries, page footers, final totals, etc.).
  3. Using a standard CSS style sheet that includes declarations of how pages should be printed.
  4. Writing an RPG program that includes invoking procedures that generate an IFS stream file that holds an HTML version of the report.
  5. Invoking a procedure that transforms the HTML output into a PDF format.
  6. Optionally outputting the report to a browser.

Note that this approach is intended for application developers as opposed to say wizard-style reporting utilities that may be designed for end users. Sometimes the distinctions between application developers and end users blur.

This approach is better for reports that may be placed on end-user menus (i.e. with parameter prompting), or generated in batch, or generated in connection with another process such as a payroll posting.

One advantage to this approach is its runtime efficiency. The database interfaces and APIs that we use for report generation (HTML and PDF) are entirely IBM i-based, and are many times more efficient than other tooling options.

Layout Concept

As with recent articles, I intend on sharing a working example, including code, and explaining how it works. However, as I began working on a sample report for this article, I decided to break the topic into two pieces - a prelude (if you will) that introduces a layout concept for the report's detail band in this piece - then cover page headers and footers, summary counts, database access, streaming to the IFS, and PDF generation in the next.

It seems that the detail band of most reports entails the use of tables with column headings. However in this case, I was inclined to generate output where the layout may automatically adapt to page size and orientation. This is quite comparable to the articles that I wrote previously about "responsive design", where the layout automatically adapts to the width of the viewing area.

Please click on the following screen shot to see how the layout might adapt to your browser window.



How Does it Work?

The first point that I'd like to make is that I'm planning on using the same HTML template and CSS properties to produce printer output that I might otherwise use in a browser user interface.

Let's take a look at the <body> of that web page:


<body>
<div ht-container="entities" ht-href="ibmiui13a.html" ht-jref="entities.json" ht-cache ht-repeat></div>
</body>

Like with previous articles, I'm using a JavaScript utility that automatically produces attractive layout via the merger of an HTML template with a JSON data object (array). This happened to be a convenient way to play with the layout prior to, or without the need of writing any server-side logic.

By way of review, the body encapsulates a <div> container that has attributes that declare a merge of an HTML template ibmiui13a.html with a JSON array entities.json.

Let's take a look at the ibmiui13a.html template that is used for generating "entity" details:


<div class="il fl h2 mw" style="margin:10">
<div class="il fl w4 hi-row pd-5">{{NAME}}</div><br>
<div class="il fl w4 pd-5 bs-1 h1">{{ADDR}}</div>
</div>

The HTML template consists of a set of <div> elements that have a series of CSS class name references that control the flow (float) from left to right, background colors, border shadows, margins, etc.

It has become my preference to combine a number of styling options via abbreviated CSS class names. I tried a number of CSS options before settling on a final appearance. It was helpful to have a utility merge the HTML template and JSON array to get a closer picture of the final output.

The template API that I use in RPG, as well as the JavaScript merge utility - they both use double curly brace "markers" (i.e. {{NAME}}, {{ADDR}}) to delimit the location where "data" is inserted at runtime.

The Cursor API

I introduced a set of procedures in Part 12 that externalize SQL, that we've used in hundreds of interactive applications and reports. I plan on using it again to output live data in the coming sample report.

I raise the point now to show the ILE RPG program that I used to generate the entities.json file that I've been testing with.

Program JEXP003
      //-----------------------------------------------------------------
      // procedure prototypes
      //-----------------------------------------------------------------

      /copy *libl/qrpglesrc,rdcsrapi#1

      //-----------------------------------------------------------------
      // miscellaneous variables
      //-----------------------------------------------------------------

     d cols            s            128a   varying
     d stmf            s            128a   varying
     d c1              s               *
     d squote          c                   ''''

      /free

        csrInit();

        cols = 'NAME, GADDRSTR AS ADDR';

        c1  = csrNew('TLOC100P':cols);

        stmf = '/rdweb/info3/iui13/entities.json';

        csrSetOrder('NAME');
        csrRefresh();
        csrToStmf(stmf:'4');

        return;

      /end-free

The csrToStmf() - procedure is quite powerful in that it transforms any SQL result set into a JSON array, and outputs it to a stream file, or optionally outputs the JSON to the IBM i HTTP server.

Summary

I've taken an opportunity to introduce the idea of using standard HTML and CSS to generate nicely formatted and stylized reports. Most of the "how to" is reserved to the next article.

I thought it might help to first review how my merge utility and JSON generation utility might be used as a preliminary step to try different formatting options prior to using RPG to generate the report.