Using Flex2Crystal in Web Apps¶
The same basic steps used to add Flex2Crystal to a Windows app are required to use Flex2Crystal in a web app as well. But web apps present some unique challenges related to returning the output of the report to the browser. Because DataFlex includes a newer “Web App Framework” and an older “Classic Web App” model, included are examples of how to use Flex2Crystal in each case.
Web Application Framework¶
The following example shows how to migrate the DataFlex 18.2 CustomerListSample.wo
in the WebOrder
workspace to the latest version of Crystal Reports. The original version of this wo simply returned a static PDF file. We’ll use it as a shell to show how to run a Flex2Crystal report that generates a PDF and return that PDF.
Add the Flex2Crystal Library to Your Workspace¶
Start DataFlex Studio and open the required workspace.
Select
from the DataFlex menu bar. Existing library paths (if any) are displayed in the Library Maintenance dialog box.Click Add Library.
Navigate to the
User Documents\Mertech Data Systems\Flex2Crystal\lib
folder.Select
Flex2Crystal.sws
, then click Open.A confirmation dialog box prompts to add the library using relative pathing (Yes) or absolute pathing (No). It is recommended that you select Yes. The Library Maintenance dialog box shows the addition of the Flex2Crystal library.
Click OK.
Update the .wo File¶
Edit the CustomerListSample.wo
to use the cFlex2Crystal.pkg
and to define an output filename property.
Use cWebView.pkg
Use cWebPanel.pkg
Use cWebForm.pkg
Use cWebRadio.pkg
Use cWebCheckbox.pkg
Use cWebForm.pkg
Use cWebButton.pkg
Use cWebLabel.pkg
Use cWebGroup.pkg
// Add the cFlex2Crystal.pkg
Use cFlex2Crystal.pkg
// Modify the caption and add variable psOutFileName
Object oCustomerListSample is a cWebView
Set piWidth to 700
Set psCaption to "Customer List (Crystal Report)"
Property String psOutputFileName ""
Modify the RunReport
procedure to use the newly defined output filename and to run the Crystal Object (oCrystalRpt
) RunReport
method. If the report (PDF file) is successfully generated, it is displayed in a new browser tab.
Replace the Report object (oReport) with the Crystal Object (oCrystalRpt
) shown below. oCrystalRpt
selects the report to be run, sets up the selection criteria and runs the report. It includes the OnExport
procedure that writes the report (PDF file) to the folder assigned by the DataFlex framework. A random function is used to ensure the report filename is unique.
Procedure RunReport
String sUrl
// Use the new variable psOutFileName
Set psOutputFileName to ""
Send RunReport of oCrystalRpt
If ((psOutputFileName(Self))="") Begin
Send ShowInfoBox "The Report could not be generated"
End
Else Begin
Get DownloadURL of ghoWebResourceManager (psOutputFileName(Self)) to sUrl
// this is used to show a PDF file in a new browser tab or window
// use btNewTab to open a new browser tab page
// use btNewWindow to open a new browser window
Send NavigateToPage sUrl btNewTab
// this is used to show a PDF file in an embedded viewer within this view
// WebSet psUrl of oWebIFrame1 to sUrl
End
End_Procedure
// Replaces oReport in the original wo
Object oCrystalRpt is a cFlex2Crystal
Set psReportName to "customerswithgooglemap18.rpt"
Set peOutputDestination to PRINT_TO_FILE
Procedure OnInitializeReport Handle hoReport
Integer[] iCustomerCustomerNumbers
String[] sCustomerNames
String sSelection
Handle hoParam
Integer iRadio iSortDirection
Boolean bAscending
Forward Send OnInitializeReport hoReport
// customer number filter
WebGet psValue of oFromCustomerCustomerNumber to iCustomerCustomerNumbers[0]
WebGet psValue of oToCustomerCustomerNumber to iCustomerCustomerNumbers[1]
If (iCustomerCustomerNumbers[0] <> 0) Begin
Append sSelection "{Customer.Customer_Number} >= " iCustomerCustomerNumbers[0]
End
If (iCustomerCustomerNumbers[1] <> 0) Begin
Append sSelection (If(sSelection<>"", " and ", "")) "{Customer.Customer_Number} <= " iCustomerCustomerNumbers[1]
End
// customer name filter
WebGet psValue of oFromCustomerName to sCustomerNames[0]
WebGet psValue of oToCustomerName to sCustomerNames[1]
If (sCustomerNames[0] <> "") Begin
Append sSelection (If(sSelection<>"", " and ", "")) "{Customer.Name} >= " '"' (Trim(sCustomerNames[0])) '"'
End
If (sCustomerNames[1] <> "") Begin
Append sSelection (If(sSelection<>"", " and ", "")) "{Customer.Name} <= " '"' (Trim(sCustomerNames[1])) '"'
End
// sorting
WebGet psValue of oSortNumber to iRadio
Get GetChecked of oSortAscending to bAscending
// Delete old sort order
Send DeleteSortOrder of hoReport
// Setup new sort order
Move (If(bAscending,crAscendingOrder, crDescendingOrder)) to iSortDirection
If (iRadio=0) Send AppendSortField of hoReport "Customer" "Customer_Number" iSortDirection
Else Send AppendSortField of hoReport "Customer" "Name" iSortDirection
// Send the selection criteria to the report
Set ComRecordSelectionFormula of hoReport to sSelection
Get GetParamObjectByName of hoReport "SelTxt" to hoParam
If (hoParam) Send ComAddCurrentValue of hoParam sSelection
End_Procedure
// Place the report in the folder that the framework has assigned.
// Use the Random function to ensure a unique filename
Procedure OnExportReport Handle hoReport
Handle hoExport
String sFile sUrl
Set pbExportPrompt of hoReport to False
Forward Send OnExportReport hoReport
Get ExportObject of hoReport to hoExport
If (hoExport) Begin
Get GetReportsCache of ghoWebApp True to sFile
Move (sFile + "\customerlist" + String(Random(1000000000)) + ".pdf") to sFile
Set ComDestinationType of hoExport to crEDTDiskFile
Set ComDiskFileName of hoExport to sFile
Set pbCanceled of hoExport to False
Set ComFormatType of hoExport to crEFTPortableDocFormat // PDF
Set psOutputFileName to sFile
End
End_Procedure // OnExportReport
End_Object //oCrystalRpt
End_Object // oCustomerListSample
Do the Cleanup¶
This example generates a PDF report stored in a folder assigned by the DataFlex framework. At some point old reports have to be removed from disk. You may want to write a cleanup procedure to do this.
Report Features¶
The report itself, customerswithgooglemap18.rpt
, demonstrates some noteworthy features available in Crystal Reports.
How to embed a Google map in a report
The Use of SQL Expression fields
Classic Web Application¶
Any Web app not using the Web Application Framework is referred to as a classic web application. Published functions are called from ASP or directly from the browser using SOAP or JSON. The following example shows how to update the DataFlex 15.1 Order Entry workspace to work with the latest version of Crystal Reports.
Add the Flex2Crystal Library to Your Workspace¶
You can follow the procedures shown in the previous example (Add the Flex2Crystal Library to Your Workspace) or you can copy the library file to the OrderEntry\AppSrc
directory.
Create a CrystalReport.wo¶
This sample wo contains two report objects. Each report object defines the report to be run, selection parameters and print to file option. Each report object also contain the OnExportReport
procedure that writes the report to disk in PDF format. The filename is defined in the WebBusinessProcess
object, which runs the selected report.
Note
You can define as many reports as you want in one wo and then use it to serve all your reporting needs.
Use cWebBusinessProcess.pkg
Use cFlex2Crystal.pkg
// First Report
Object oCrystalRpt is a cFlex2Crystal
Set psReportName to "customers.rpt"
Property String psExportFileName ""
Set peOutputDestination to PRINT_TO_FILE
Procedure OnInitializeReport Handle hoReport
Forward Send OnInitializeReport hoReport
Handle hoParam
Get GetParamObjectByName of hoReport "SelTxt" to hoParam
If (hoParam) Send ComAddCurrentValue of hoParam "CA"
End_Procedure
//Set the output path and output file format (PDF) and write the file to disk
Procedure OnExportReport Handle hoReport
Handle hoExport
Set pbExportPrompt of hoReport to False
Forward Send OnExportReport hoReport
Get ExportObject of hoReport to hoExport
If (hoExport) Begin
Set ComDestinationType of hoExport to crEDTDiskFile
Set ComDiskFileName of hoExport to (psExportFileName(Self))
Set ComFormatType of hoExport to crEFTPortableDocFormat // PDF
End
End_Procedure // OnExportReport
End_Object
// Second Report, similar to the first report but with additional selection criteria
Object oCrystalRptWithParams is a cFlex2Crystal
Set psReportName to "customers.rpt"
Set peOutputDestination to PRINT_TO_FILE
Property String psExportFileName ""
Property Integer piFromCustomerCustomerNumber
Property Integer piToCustomerCustomerNumber
Property Integer piIndex
Procedure OnInitializeReport Handle hoReport
String sSelection
Handle hoParam
Integer iRadio iSortDirection
Boolean bAscending
Forward Send OnInitializeReport hoReport
If (piFromCustomerCustomerNumber(Self) <> 0) Begin
Append sSelection "{Customer.Customer_Number} >= " (piFromCustomerCustomerNumber(Self))
End
If (piToCustomerCustomerNumber(Self) <> 0) Begin
Append sSelection (If(sSelection<>"", " and ", "")) "{Customer.Customer_Number} <= " (piToCustomerCustomerNumber(Self))
End
// Delete old sort order
Send DeleteSortOrder of hoReport
If (piIndex(Self)=1) Send AppendSortField of hoReport "Customer" "Customer_Number" crAscendingOrder
Else Send AppendSortField of hoReport "Customer" "Name" crAscendingOrder
Set ComRecordSelectionFormula of hoReport to sSelection
Get GetParamObjectByName of hoReport "SelTxt" to hoParam
If (hoParam) Send ComAddCurrentValue of hoParam "CA"
End_Procedure
//Set the output path and output file format (PDF) and write the file to disk
Procedure OnExportReport Handle hoReport
Handle hoExport
Set pbExportPrompt of hoReport to False
Forward Send OnExportReport hoReport
Get ExportObject of hoReport to hoExport
If (hoExport) Begin
Set ComDestinationType of hoExport to crEDTDiskFile
Set ComDiskFileName of hoExport to (psExportFileName(Self))
Set ComFormatType of hoExport to crEFTPortableDocFormat // PDF
End
End_Procedure // OnExportReport
End_Object
// WebBusinessProcess: Contains two published functions, one to run each report. Both generate a random filename so existing report files are not overwritten.
Object oCrystalReport is a cWebBusinessProcess
Set psDescription to "Crystal Report"
{ Published = True }
{ Description = "" }
Function RunReport Returns String
String sFile
Move ("\customerlist" + String(Random(1000000000)) + ".pdf") to sFile
Set psExportFileName of oCrystalRpt to ((psAppHtmlPath(phoWorkspace(oApplication))) - sFile)
Send RunReport of oCrystalRpt
Function_Return sFile
End_Function
{ Published = True }
{ Description = "" }
Function RunReportWithParams Integer iFromCustomerNo Integer iToCustomerNo Integer iIndex Returns String
String sFile
Move ("\customerlist" + String(Random(1000000000)) + ".pdf") to sFile
Set piFromCustomerCustomerNumber of oCrystalRptWithParams to iFromCustomerNo
Set piToCustomerCustomerNumber of oCrystalRptWithParams to iToCustomerNo
Set piIndex of oCrystalRptWithParams to iIndex
Set psExportFileName of oCrystalRptWithParams to ((psAppHtmlPath(phoWorkspace(oApplication))) - sFile)
Send RunReport of oCrystalRptWithParams
Function_Return sFile
End_Function
End_Object
Let the Browser Open the Report¶
This example uses ASP to call the report and get back the path to the generated PDF. The ASP code then redirects the browser to this file.
<h3>Customer Information Drill Down Report</h3>
<%
Index = request("Index") ' The last selected Index number
SelStart1 = request("SelStart1")
SelStop1 = request("SelStop1")
sFile = oCrystalReport.call("get_RunReportWithParams", SelStart1, SelStop1, Index )
Response.Redirect(sFile)
%>
Do the Cleanup¶
This example generates a PDF report stored in a folder assigned by the DataFlex framework. At some point old reports have to be removed from disk. You may want to write a cleanup procedure to do this.