PowerBuilder Tips, Tricks, and Techniques

Berndt Hamboeck

Subscribe to Berndt Hamboeck: eMailAlertsEmail Alerts
Get Berndt Hamboeck: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


PowerBuilder: Article

PowerBuilder Web Reporting From Scratch in Minutes

Using DataWindow.NET and Visual Studio

A week ago one of my customers asked me to do a presentation on Sybase DataWindow.NET. We discussed what they would like to see (besides all the standard stuff all PowerBuilder shops want to see, such as a Master/Detail DataWindow in a client/server environment and, in a second step, these DataWindows within a browser), and they asked me to talk a little bit about distributing such a Web application in a production environment.

They said that they recently had a presentation from their Java people and the deployment was a mess. This is fairly easy with the Web setup project provided in Visual Studio, but I wanted to show them more. As they are a large PowerBuilder shop and they already have a lot of reports for their users, I decided to build a small Web application where they can bring their reports to the Web within minutes. The outcome of this small weekend project is described in this article. Let's have a look at what came to mind and how easy it was to implement using DataWindow.NET. I used DataWindow.NET 2.0 beta and Visual Studio 2005, but everything I used is also available in DataWindow.NET 1.5.1 and Visual Studio 2003.

The Idea
The idea was to give the customer a chance to develop and test DataWindows locally on the desktop machine using DataWindowBuilder (or PowerBuilder) and then, using a Web page, upload them to the Web server so that the library will be available to all users. These users can now choose one library from the uploaded libraries. All the available DataWindows (including the comment and the save date) within this library will be shown to the user; he or she can simply click on it and the data should be displayed within the browser. This should work without any configuration and storage of additional information for the person uploading the library and for the users.

The Implementation
The following pages needed to be developed:

  • Helper pages, such as "header.asp" and "footer.asp" (and a stylesheet), that are included in every page should have a common look and feel
  • The start Page - a simple welcome page, which has no logic included (see Figure 1)
  • Upload a library - Visual Studio has a component included that makes this implementation simple (see Figure 2)
  • Choose a library - read the content of the server directory and display the files to the user (see Figure 3)
  • Choose a report - read the list of objects in the library
  • The report page itself - display the DataWindow the user has chosen, including graphical DataWindows (see Figure 4) and also give the user a chance to get a PDF file from the report
  • A page that holds a StreamImageContainer (so that the images don't need to be stored on the Web server)
In addition, we need directories for storing PDF files of our reports, images, and include files. You can see the complete project hierarchy and objects in Figure 5.

We don't need to talk about the helper pages since how to create a common look and feel is completely up to you or your company, so let's take a look at the page where users are able to upload a library. The requirements for an HTML form to be able to upload files are very simple (see the full source code in Listing 1), as we have to use a form with a multipart/form-data encryption:

<form id="Form1" enctype="multipart/form-data" runat="server">

The HTML input control that is used to upload the file has a simple type of file:

<input id="uplTheFile" type="file" runat="server" style="width: 300px"/>

This is all that needs to be done to the HTML form for a client to be able to submit a file to an ASP.NET application. The more interesting part is receiving the file on the server side, which is done in the server-side script for the upload button. The line:

uplTheFile.PostedFile.SaveAs(strFullFileOnServer);

saves the file on the physical directory on the server. I decided to use a directory within my virtual Web directory, called PBL, so that all the libraries can be found in one place by the administrator. The second page needs to read all the available (uploaded) PowerBuilder libraries from the PBL directory. As you can see in Listing 2, I used a GridView component that I have bound to a DirectoryInfo object (see Listing 3) that holds all the available files. Again, nothing really spectacular here. Let's have a look at the page that reads the contents of the library. Once again I used a GridView (see Listing 4) that I have bound to an array of DataWindowObjectEntry objects. This class is provided by DataWindow.NET and is part of the utility classes. Just one line is needed to get all the existing DataWindow objects from a physical file on your Web server (for the full server-side code, look at Listing 5).

DataWindowObjectEntry[] dwEntries =
Sybase.DataWindow.Utility.GetDataWindowObjectEntries(strLib);

Now we have just two more pages to go. Let's start with the easier of these two, the page that includes just a StreamImageContainer. As a PowerBuilder developer you know that we have DataWindows displaying data in text format or in a graphical format. Within a browser these graph DataWindows can be displayed as a standalone image file or in an image stream embedded into the Web page. The disadvantage in using an image file is that the file is stored on the Web server and needs to be removed somehow (it will not be removed automatically), the StreamImageContainer does not have this drawback, but it needs more memory on the server side to serve the image to the client. Simply create a new page to put a StreamImageContainer object on and save it (see Listing 6). Our last step will be to create the heart of our application, the page where the report is displayed (and the page containing the StreamImageContainer might be used) (see Listing 7). I placed the following objects on this page:

  • A WebDataWindow control
  • A transaction object, or define an AdoTransaction on your own
  • A button to display a PDF from the report
  • A TextBox to display any errors
We have to set a few properties to be able to display graph DataWindows. We specify how we want the graph to be rendered by setting the RenderOption property in the GraphConfigurations section. We have the choice of using ImageStream or ImageFile. If we set the property to ImageStream so that the rendering of the graph object is saved into a memory stream in the session cache in a StreamImageContainer, we have to also set the property StreamImageContainerPage to point to the page we created earlier.

If you prefer to get real physical images, use ImageFile, so the rendering of the graph object is saved into a file on the Web server and an image URL is generated automatically to a reference of this image file within the page. Also the physical directory in which the temporary image file is stored and the URL path need to be specified in the GraphDynamicImageFileUrlPath property. This property must specify a URL path in the Web application virtual directory (I used the images directory). The last step is to choose how to render the graph (the file format). To select the image format, set the ImageFormat property to GIF, JPEG, or PNG. The default image format is PNG, which provides superior rendering and a smaller footprint than JPEG, whereas GIF is the way to go to reduce the footprint to a minimum (of course, at the cost of some loss of quality).

We also want our users to be able to export the WebDataWindow's content to a PDF file on the server and then stream the result to the browser. This can easily be done by using the SaveAs function on the server side (after installing the GNU AFPL Ghostscript driver on the Web server) - you'll find the complete source code in Listing 8:

dwReport.SaveAs(pdfFileName, Sybase.DataWindow.FileSaveAsType.Pdf);

ASP.NET pages are inherently stateless, which means that when we come back to the server to save the WebDataWindow's content as a PDF, we need to get the current state of the data visible to the user. This can easily be done by setting the following properties to true:

  • AutoRestoreContext: To have the data automatically restored to the DataWindow in the browser before the user can make any changes to the DataWindow.
  • AutoRestoreDataCache: To restore the data cache if it exists in session state.
  • AutoSaveDataCacheAfterRetrieve: To specify that the DataWindow will automatically save the data as a data cache after a retrieve.
  • EnableDataState: To use the WebDataWindow context management system.
Possible Enhancements
This small project was created for demo purposes and lacks some functionality, which can be built in easily, and some points that you might build in to bring it in into a production-ready state:
  • No retrieval arguments possible. Now you would get an error if the user chooses a DataWindow that uses one or more retrieval arguments
  • No dynamic switching of the database. I used the EAS Demo DB V110 DWD database, which has to be defined on the machine running the sample. You might bind a library to a project (which has to be chosen during the file upload) and, on that project, the database connection could be defined (for example, by storing the information within a file in the project directory).
  • Saving the reports in different formats (not only PDF).
  • Switching the report format between HTML, XML, and XHTML, so that users could sort the data by clicking on the header without a roundtrip to the server (again already built into the XML DataWindow by default).
Conclusion
DataWindow.NET and Visual Studio are a good combination when it comes to development on the Windows platform. For PowerBuilder developers it's easy to start development after learning the basics about the .NET Framework. EAServer developers will miss a well-defined component model, but will be happy to see that the original HTML DataWindow has made it into the .NET world and will not have any problems with the client event model. In my simple example I showed (as you have seen all of these pages can be written within a few minutes) that we now have a foot in the Microsoft world, and we, as a PowerBuilder community, are no longer limited to the Java and PowerBuilder world anymore. Sybase DataWindow.NET brings us closer to the world of Microsoft. I wish you happy coding with Sybase DataWindow.NET.

More Stories By Berndt Hamboeck

Berndt Hamboeck is a senior consultant for BHITCON (www.bhitcon.net). He's a CSI, SCAPC8, EASAC, SCJP2, and started his Sybase development using PB5. You can reach him under [email protected]

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
SYS-CON Australia News Desk 01/26/06 07:53:29 PM EST

A week ago one of my customers asked me to do a presentation on Sybase DataWindow.NET. We discussed what they would like to see (besides all the standard stuff all PowerBuilder shops want to see, such as a Master/Detail DataWindow in a client/server environment and, in a second step, these DataWindows within a browser), and they asked me to talk a little bit about distributing such a Web application in a production environment.