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:
-
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.
-
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.
-
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.
-
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.
-
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.
-
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=YtNacVr7P … 9_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