Dynamic Web reports are created on-demand, possibly based on data supplied by the user. This type of solution typically involves using an ASP.NET page that presents a form to the user and collects the information needed to create the report, then creates a C1Report component to render the report into a temporary file, and returns a reference to that file.
The example that follows is a simple ASP.NET page that allows users to enter some information and to select the type of report they want. Based on this, the ASP code creates a custom version of the NorthWind "Employee Sales by Country" report and presents it to the user in the selected format.
The sample uses a temporary file on the server to store the report. In a real application, you would have to generate unique file names and delete them after a certain time, to avoid overwriting reports before the users get a chance to see them. Despite this, the sample illustrates the main techniques involved in delivering reports over the Web with C1Report.
To implement this type of application, follow these steps:

The page has five server controls:
Add the following code:
To write code in Visual Basic
| Visual Basic |
Copy Code
|
|---|---|
Imports C1.C1Report
' handle user clicks
Private Sub _btnHTML_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _btnHTML.Click
RenderReport(FileFormatEnum.HTMLDrillDown)
End Sub
Private Sub _btnPDF_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _btnPDF.Click
RenderReport(FileFormatEnum.PDF)
End Sub
|
|
To write code in C#
| C# |
Copy Code
|
|---|---|
using C1.C1Report;
// handle user clicks
private void _btnHTML_Click(object sender, System.EventArgs e)
{
RenderReport(FileFormatEnum.HTMLDrillDown);
}
private void _btnPDF_Click(object sender, System.EventArgs e)
{
RenderReport(FileFormatEnum.PDF);
}
|
|
This is the code that gets executed on the server, when the user clicks either button.
To write code in Visual Basic
| Visual Basic |
Copy Code
|
|---|---|
Private Sub RenderReport(ByVal fmt As FileFormatEnum)
' build file names
Dim rpt As String = "Employee Sales by Country"
Dim fileIn As String = GetDataPath() & "NWind.xml"
Dim ext As String = Iif(fmt = FileFormatEnum.PDF, ".pdf", ".htm")
Dim fileOut As String = GetOutputPath() & rpt & ext
Try
' create C1Report component
Dim c1r As New C1Report()
' load the report
c1r.Load(fileIn, rpt)
' get user parameters
Dim year As String = _lstYear.SelectedItem.Text
Dim goal As String = _txtGoal.Text
' customize the report data source
Dim sSQL As String = "SELECT DISTINCTROW " & _
"Employees.Country, Employees.LastName, " & _
"Employees.FirstName, Orders.ShippedDate, Orders.OrderID, " & _
" [Order Subtotals].Subtotal AS SaleAmount " & _
"FROM Employees INNER JOIN (Orders INNER JOIN " & _
" [Order Subtotals] ON Orders.OrderID = " & _
" [Order Subtotals].OrderID) " & _
" ON Employees.EmployeeID = Orders.EmployeeID " & _
"WHERE Year(Orders.ShippedDate) = " & year & ";"
c1r.DataSource.RecordSource = sSQL
' customize the report's event handlers
Dim sScript As String = _
"If SalespersonTotal > " & goal & " Then" & vbCrLf & _
" ExceededGoalLabel.Visible = True" & vbCrLf & _
" SalespersonLine.Visible = True" & vbCrLf & _
"Else" & vbCrLf & _
" ExceededGoalLabel.Visible = False" & vbCrLf & _
" SalespersonLine.Visible = False" & vbCrLf & _
"End If"
c1r.Sections(SectionTypeEnum.GroupHeader2).OnPrint = sScript
' render the report into a temporary file
c1r.RenderToFile(fileOut, fmt)
' redirect user to report file
Response.Redirect("Temp/" + rpt + ext)
Catch x As Exception
_lblStatus.Text = "*** " & x.Message
End Try
End Sub
|
|
To write code in C#
| C# |
Copy Code
|
|---|---|
// render the report
private void RenderReport(FileFormatEnum fmt)
{
// build file names
string rpt = "Employee Sales by Country";
string fileIn = GetDataPath() + "NWind.xml";
string ext = (fmt == FileFormatEnum.PDF)? ".pdf": ".htm";
string fileOut = GetOutputPath() + rpt + ext;
try
{
// create C1Report component
C1Report c1r = new C1Report();
// load the report
c1r.Load(fileIn, rpt);
// get user parameters
string year = _lstYear.SelectedItem.Text;
string goal = _txtGoal.Text;
// customize the report data source
string sSQL = "SELECT DISTINCTROW " +
"Employees.Country, Employees.LastName, " +
"Employees.FirstName, Orders.ShippedDate, Orders.OrderID, " +
" [Order Subtotals].Subtotal AS SaleAmount " +
"FROM Employees INNER JOIN (Orders INNER JOIN " +
" [Order Subtotals] ON Orders.OrderID = " +
" [Order Subtotals].OrderID) " +
" ON Employees.EmployeeID = Orders.EmployeeID " +
"WHERE Year(Orders.ShippedDate) = " + year + ";";
c1r.DataSource.RecordSource = sSQL;
// customize the report's event handlers
string sScript =
"If SalespersonTotal > " + goal + " Then \n" +
" ExceededGoalLabel.Visible = True\n" +
" SalespersonLine.Visible = True\n" +
"Else\n" +
" ExceededGoalLabel.Visible = False\n" +
" SalespersonLine.Visible = False\n" +
"End If";
c1r.Sections[SectionTypeEnum.GroupHeader2].OnPrint = sScript;
// render the report into a temporary file
c1r.RenderToFile(fileOut, fmt);
// redirect user to report file
Response.Redirect("Temp/" + rpt + ext);
}
catch (Exception x)
{
_lblStatus.Text = "*** " + x.Message;
}
}
|
|
The RenderReport routine is long, but pretty simple. It begins working out the names of the input and output files. All file names are built relative to the current application directory.
Next, the routine creates a C1Report component and loads the "Employee Sales by Country" report. This is the raw report, which you will customize in the next step.
The parameters entered by the user are available in the _lstYear and _txtGoal server-side controls. The code reads these values and uses them to customize the report's RecordSource property and to build a VBScript handler for the OnPrint property. These techniques were discussed in previous sections.
Once the report definition is ready, the code calls the a RenderToFile, which causes the C1Report component to write HTML or PDF files to the output directory. When the method returns, the report is ready to be displayed to the user.
The last step is the call to Response.Redirect, which displays the report you just created on the user's browser.
Note that the whole code is enclosed in a try/catch block. If anything goes wrong while the report is being generated, the user gets to see a message explaining the problem.
To write code in Visual Basic
| Visual Basic |
Copy Code
|
|---|---|
' get directories to use for loading and saving files Private Function GetDataPath() As String Return Request.PhysicalApplicationPath + "Data\" End Function Private Function GetOutputPath() As String Return Request.PhysicalApplicationPath + "Temp\" End Function |
|
To write code in C#
| C# |
Copy Code
|
|---|---|
// get directories to use for loading and saving files
private string GetDataPath()
{
return Request.PhysicalApplicationPath + @"Data\";
}
private string GetOutputPath()
{
return Request.PhysicalApplicationPath + @"Temp\";
}
|
|
The following screen shot shows what the result looks like in the browser:
