Tip 11: Using Crystal Reports in ASP.NET 2.0 Web Forms
ASP.NET 2.0 includes an enhanced ReportViewer and CrystalReportSource control, as well as a new CrystalReportsPartViewer control. The latter allows me to work with ASP.NET 2.0 Web Parts, which let me work with individual sections of a page. The enhanced ReportViewer allows users to preview and navigate through a report using a preview toolbar similar to that found in the Crystal Reports Windows Forms toolbar. A future Baker's Dozen article will cover ASP.NET 2.0 data-driven Web applications and Web reporting.
Tip 12: Generating Reports against Custom .NET Classes Instead of Datasets
I prefer to work with data in custom classes and custom collections, as opposed to datasets. I'd like to generate a report directly against those objects, without having to use datasets.
In both the original article and this article, I've focused on datasets as the design-time and run-time source for the push model. However, I can also push .NET custom collections into a report.
The following code shows a basic class with two simple properties for name and salary called
TestReportInfo.
using System;
using System.Collections.Generic;
using System.Text;
namespace ReportWithClassTest
{
public class TestReportInfo
{
public TestReportInfo(string cEmpName, decimal nSalary)
{
this.EmpName = cEmpName;
this.Salary = nSalary;
}
private string _EmpName;
public string EmpName
{
get { return _EmpName; }
set { _EmpName = value; }
}
private decimal _Salary;
public decimal Salary
{
get { return _Salary; }
set { _Salary = value; }
}
}
}
I can use the preceding class as the design-time data source for a test report, by doing the following:
- Launch Crystal Reports and open the Database Expert (as shown in Figure 19).
- Click Project Data, and then click .NET Objects.
- Select the class containing the objects that the report will use.
- Drag the objects from the Crystal Reports Field Explorer onto the report body as needed (as shown in Figure 20).
|
 | |
| Figure 20: Properties from .NET class available in Field Explorer. |
|
|
That covers the design-time aspectwhat about pushing a collection of objects into the report at run time? It's just as easy. Here's the code to create a List object (using the new .NET 2.0 Generics namespace) to store multiple instances of the TestReportInfo class.
List<TestReportInfo> oList = new List<TestReportInfo>();
oList.Add(new TestReportInfo("Kevin Goff",90000));
oList.Add(new TestReportInfo("John Goff",95000));
oList.Add(new TestReportInfo("Mike Smith",99000));
CrystalReport1 oRpt = new CrystalReport1();
oRpt.SetDataSource(oList);
Then I can instantiate the report object and use the report's
SetDataSource method to push the List object into the report.
So I can push a DataSet, DataTable, DataReader, or (in this instance) anything that implements System.Collections.IEnumerable into a Crystal Reports report.
Additionally, if I'm using Crystal Reports XI, I can now pass a DataView object. Prior versions of Crystal Reports did not support the DataView object. So if I'm using anything prior to Crystal Reports XI and want to push the contents of a DataView into a report, I have two choices:
If I'm using Visual Studio 2005, I can use the new ADO.NET method,
DataView.ToTable, to convert the view to a table.
If I'm using Visual Studio 2003, I can use the following code to create a DataTable from a DataView:
public DataTable ViewToTable(DataView dv)
{
// Create a new table structure from the
// table object of the view, and then loop
// through the view and import the rows into
// the new table
DataTable DtReturn = dv.Table.Clone();
foreach (DataRowView drv in dv)
DtReturn.ImportRow(drv.Row);
return DtReturn;
}
Tip 13: A Potpourri of Reporting Tips
Question: How do I convert a numeric column to a string?
Answer: Create a Crystal Reports formula that uses the Crystal Reports ToText function, which converts numeric data to string. The function also contains overloads, allowing me to specify the number of decimals in the return string. This helps in instances where I have a value of 123.00 and want to return a string that reads "123".
Question: How can I display a column of data in a different color, based on some condition?
Some developers view reports as busy work. But they are the bridge between the data that you see, and the information that clients and users expect from the system.
|
|
Answer: Create a Crystal Reports formula that compares the column to another threshold column, and then returns a Crystal Reports constant for the color. Insert the formula into the report by doing the following:
- Right-click the column and choose Format Field.
- In the Format Editor, click the Font tab.
- On the Font tab, click the formula icon to the right of the Font color option.
- In the formula editor, insert the following code:
if {MyData.Costs} > MyData.CostThreshold} then
crRed
else
crBlack
Question: How can I save the image of generated reports, in an audit trail fashion, so that anyone can go back and see what was actually generated at the time?
Answer: One technique is to automatically save the report as PDF to a shared location when the user prints the report. The library in Tip 3 makes this process very easy. You can create a database table that logs each instance (who generated the report, when, the name of the PDF, etc.)
Question: How do I programmatically set print options beyond those specified in my print library?
Answer: Access the print options class inside the report object. Here's a code sample that shows some different possibilities:
using CrystalDecisions.Shared;
RPT_Invoice oRpt = new RPT_Invoice();
oRpt.PrintOptions.PrinterName = "printer name";
oRpt.PrintOptions.PaperSize = PaperSize.Paper10x14;
oRpt.PrintOptions.PaperSource = PaperSource.Envelope;
oRpt.PrintOptions.CustomPaperSource = PaperSource.Envelope;
oRpt.PrintOptions.PaperOrientation =
PaperOrientation.Landscape;
Have you ever submitted something (an article, a paper, some code, etc.) and thought of some good ideas
after the fact? Well, I'm the king of thinking of things afterwards. Fortunately, that's the type of thing that makes blogs valuable. Check
my blog for follow-up tips and notes on Baker's Dozen articles
and maybe a few additional treats! You can find the entire source code on
my Web site.