使用 C1Report 控件 > 为Web应用场景开发报表 > 动态Web报表 |
动态Web报表是按需创建的,还可能依赖于用户提供的数据。此种方案常常会通过ASP.NET页面中的表单来向用户收集创建报表所需要的信息,然后创建一个C1Report组件来呈现报表到临时文件中,然后返回文件的引用地址。
下面的例子是一个简单的ASP.NET页面,允许用户填写一些信息并且选择需要的报表类型。基于此,ASP代码创建了一个定制版本的NorthWind “Employee Sales by Country”报表,然后以用户选择的格式展现给用户。
此示例在服务器端使用临时文件来保存报表。在实际生产环境中,必须生成唯一的文件名并且在一段时间后将其删除,以避免报表在用户查看之前被覆盖。尽管如此,此示例演示了在Web上使用C1Report发布报表的主要技术。
按如下步骤来实现此类型的程序:
页面包含五个服务器端控件:
注意:如果使用demo或beta版的C1Report来运行程序,将引发控件尝试在服务器端显示其About对话框的错误。如果发生了这样的情况,只需重新加载页面就能消除这个问题。 |
添加如下代码:
Visual Basic
Visual Basic |
拷贝代码
|
---|---|
Imports C1.C1Report '处理用户点击操作 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 |
C#
C# |
拷贝代码
|
---|---|
using C1.C1Report; //处理用户点击操作 private void _btnHTML_Click(object sender, System.EventArgs e) { RenderReport(FileFormatEnum.HTMLDrillDown); } private void _btnPDF_Click(object sender, System.EventArgs e) { RenderReport(FileFormatEnum.PDF); } |
当用户点击任何一个按钮时,这些代码在服务器端运行。
Visual Basic
Visual Basic |
拷贝代码
|
---|---|
Private Sub RenderReport(ByVal fmt As FileFormatEnum) ' 构建文件名 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 ' 创建C1Report 组件 Dim c1r As New C1Report() ' 加载报表 c1r.Load(fileIn, rpt) ' 获取用户参数 Dim year As String = _lstYear.SelectedItem.Text Dim goal As String = _txtGoal.Text ' 自定义报表数据源 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 ' 自定义报表时间处理 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 ' 把报表呈现到临时文件 c1r.RenderToFile(fileOut, fmt) ' 重新寄送报表文件 Response.Redirect("Temp/" + rpt + ext) Catch x As Exception _lblStatus.Text = "*** " & x.Message End Try End Sub |
C#
C# |
拷贝代码
|
---|---|
// 呈现报表 private void RenderReport(FileFormatEnum fmt) { // 构建文件名 string rpt = "Employee Sales by Country"; string fileIn = GetDataPath() + "NWind.xml"; string ext = (fmt == FileFormatEnum.PDF)? ".pdf": ".htm"; string fileOut = GetOutputPath() + rpt + ext; try { // 创建C1Report 组件 C1Report c1r = new C1Report(); // 加载报表 c1r.Load(fileIn, rpt); // 获取用户参数 string year = _lstYear.SelectedItem.Text; string goal = _txtGoal.Text; // 自定义报表数据源 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; // 自定义报表时间处理 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; // 把报表呈现到临时文件 c1r.RenderToFile(fileOut, fmt); // 重新寄送报表文件 Response.Redirect("Temp/" + rpt + ext); } catch (Exception x) { _lblStatus.Text = "*** " + x.Message; } } |
RenderReport程序比较长,但是也很简单。开头解决输入和输出文件的名字。所有文件的名字都相对于当前程序的目录。
接着,程序创建了一个C1Report组件然后载入“Employee Sales by Country”报表。这是一个初始的报表,在下一步将对它进行定制。
用户输入的参数可以从_lstYear和_txtGoal服务器端控件中得到。代码读取这些值然后使用它们来定制报表的RecordSource属性并且为OnPrint属性构建了一个VBScript处理程序。上一个章节中提及到这些技术。
一旦报表定义准备好了,代码就调用RenderToFile方法让C1Report组件写HTML或PDF文件到输出目录。在方法返回后,报表就可以被显示给用户了。
最后一步就是调用Response.Redirect,以在用户的浏览器上显示刚刚创建的报表。
注意所有的代码被包括在一个try/catch块中。如果在生成报表的时候发生任何错误,用户可以看见描述问题的错误信息。
Visual Basic
Visual Basic |
拷贝代码
|
---|---|
'获取加载和保存文件的路径 Private Function GetDataPath() As String Return Request.PhysicalApplicationPath + "Data\" End Function Private Function GetOutputPath() As String Return Request.PhysicalApplicationPath + "Temp\" End Function |
C#
C# |
拷贝代码
|
---|---|
//获取加载和保存文件的路径 private string GetDataPath() { return Request.PhysicalApplicationPath + @"Data\"; } private string GetOutputPath() { return Request.PhysicalApplicationPath + @"Temp\"; } |
下面的屏幕截图展示了程序在浏览器中显示的样子: