Skip to content

Web Reporting with PDF Files

Reporting in Web Applications
Secure File Streaming


The WebOrder sample contains web views that show how to generate reports within a web application. The samples also show how to download files (since that is essentially what you are doing when displaying a PDF report). This section explains how this all works.

You can create reports by generating PDF files and streaming them to your browser. This would be done in an application using the following steps:

  1. An end user invokes a report dialog and makes selections for their report. They press a “Run” button, which sends the request to the server.

  2. The server processes the client information and uses this to generate a report that is output to a PDF file. You could use DataFlex Reports to generate this file.

  3. The server passes the name of this PDF file back to the client as a URL. To ensure that only the current user can access this report, the name of the file will be encrypted.

  4. The client uses this information to display the report. It does this by requesting the PDF by making a special call to the server passing the encrypted name.

  5. The server will decrypt the file name, make sure that this is a valid operation for this client, and download the data back to the client.

  6. Depending on your application, the PDF report will appear in a new browser tab, a new browser window, or embedded inside of your view.

The Web Framework provides the interface to do this in an easy and secure way. We will look at this on a step-by-step basis. As an example, we will use DataFlex Reports to generate a report to a PDF and then display this file in the browser.

With a web view, the process can be contained within a single procedure that is called via some action like the OnClick of a web-button. Your code will look like this:

Object oRunButton is a cWebButton
    Set psCaption to "Run Report"

    Procedure OnClick
        Send RunReport
    End_Procedure
End_Object

Procedure RunReport
    String sFile sUrl
    // Generate the report PDF file and return its full file path name (not a URL)
    Get GenerateReport of oReport to sFile
    If (sFile="") Begin
        Send ShowInfoBox "The Report could not be generated"
    End
    Else Begin
        // Use the resource manager to convert the file name into an encrypted URL.
        Get DownloadURL of ghoWebResourceManager sFile to sUrl

        // Display the File (here are three options)
        // Show this in a new browser tab.
        Send NavigateToPage sUrl btNewTab

        // Or show this in a new browser window.
        // Send NavigateToPage sUrl btNewWindow

        // Or show this in an embedded IFrame viewer within this view
        // WebSet psUrl of oWebIFrame1 to sUrl
    End
End_Procedure

The first thing RunReport does is to generate the report. It does this by calling a method that generates a PDF report and returns the file path. In this example, that method is GenerateReport inside of oReport. While this location of this file could be web-accessible (e.g., MyWebApp\AppHtml\Report123.pdf), it doesn't have to be and, for security reasons, you probably do not want it to be. Instead, you would want to place this file in a location that can only be accessed internally by the server. For example, you may keep all reports in Data\ReportCache (e.g., MyWebApp\Data\ReportCache\Report123.pdf).

Now let’s look at how the report is generated. Keep in mind that you can use any report generation process you want to generate the report. You just need to return the name of a file. For example, you could bypass actually generating a new report and just return the name of a static PDF file.

Let’s say you are running a DataFlex Reports report. You might generate the report as follows:

Object oReport is a cDRReport

    Procedure OnInitializeReport
        Send SetFilters
        Send SetSortFields
    End_Procedure

    Procedure SetFilters
        //….. do whatever you need to do to set the report filters
    End_Procedure

    Procedure SetSortFields
        //….. do whatever you need to do to set the sorting order
    End_Procedure

    Function GenerateReport Returns String
        String sReportId sName sDataPath sPath
        drPDFExportOptions PDFReportOptions
        Boolean bCanceled

        Get psDataPath of (phoWorkspace(ghoApplication)) to sDataPath
        Set psReportName to (sDataPath + "\CustomerList.dr")
        Get OpenReport to sReportId

        If (sReportId <> "") Begin
            Move C_drNormal to PDFReportOptions.iPageMode
            Move C_drLow to PDFReportOptions.iImageQuality
            Move "" to PDFReportOptions.sOwnerPassword
            Move "" to PDFReportOptions.sUserPassword
            Set pPDFExportOptions of oReport to PDFReportOptions

            // Assign a random unique name for the report.
            Get RandomHexUUID to sName

            // Save the report to our report cache directory
            Move (sDataPath + "\ReportCache\" + sName + ".pdf") to sPath

            // Create the report
            Send ExportReport C_drPDF sPath

            // See if report ran ok, if not return empty path
            Get pbCanceled to bCanceled
            If bCanceled Begin
                Move "" to sPath
            End

            Send CloseReport of oReport
        End

        Function_Return sPath
    End_Function
End_Object

The GenerateReport function sets the report name, opens it, creates a unique file name (using Get RandomHexUUID), and exports the file to a PDF file. If the report generation succeeds, it returns the file name. In this example, reports are generated to the Data\ReportsCache directory. This cache is not directly web accessible. The file will not be deleted from the cache, which will continue to grow. You could create a maintenance program that would delete old files from time to time.

After the file is generated, the resource manager is used to create a secure and encrypted URL that will provide the user and only this user access to the file. It does this by calling DownloadURL:

Get DownloadURL of ghoWebResourceManager sFile to sUrl

If your file name was:

C:\DataFlex\Examples\AJAXWeb\Data\CustomerReport.pdf

Your encrypted URL might look like this:

DfEngine/Resource.asp?resource=YtNacVr7P9_eeWS4vfCA==

As you can see, the URL refers to DfEngine/Resource.asp. When called, this page will call the web application’s resource manager passing the encrypted name. The resource manager will decrypt the name and verify that the session information is valid before allowing the file download.

The final step in RunReport determines where the PDF file is displayed. The PDF file can be displayed in a number of ways. If you wish to display the report in a new browser tab, you would use the code:

// Show this in a new browser tab.
Send NavigateToPage sUrl btNewTab

If you wish to display the report in a new browser window, you would use the code:

// Show this in a new browser window.
Send NavigateToPage sUrl btNewWindow

If you wish to display the report within a view in an embedded IFrame, you must create the IFrame WebObject:

Object oWebIFrame1 is a cWebIFrame
    Set pbFillHeight to True
    Set pbShowBorder to True
End_Object

And then inside of RunReport, set its psURL property:

// This is used to show PDF in an embedded viewer within this view
WebSet psUrl of oWebIFrame1 to sUrl

For the secure file download to work, we rely on ASP. Therefore, your workspace’s Global.asa must be up to date.


Previous Topic: Reporting in Web Applications
Next Topic: Secure File Streaming

See Also

Developing Web Applications