您的位置:首页 > 编程语言 > ASP

利用 ASP.NET 创建多页自定义报表

2005-04-03 14:02 337 查看
发布日期: 4/1/2004 | 更新日期: 4/1/2004Chandra Kamalakantha
EDS Corporation
Marius Rochon
Microsoft Corporation
2002 年 9 月
适用于:
Microsoft ASP.NET
Microsoft Visual Studio .NET
 摘要:讲述一种利用现有的 ASP.NET 基础结构(设计器、数据绑定和其他运行时功能)来生成简单的和复杂的多页 HTML 报表的方法。 (7 页打印页)
下载 Reporttool.exe


本页内容


简介


我们的方法


利用数据绑定创建报表


运行时


小结


致谢


关于作者

简介

本文讲述一种利用现有的 ASP.NET 基础结构 — 设计器、数据绑定和其他运行时功能 — 来生成简单的和复杂的报表的方法。 报表由包含多页数据的 HTML 构成。 在通常情况下,Microsoft ASP.NET 用于处理单页的窗体,其中带有一组 UI 控件。 出于进行报告的目的,我们需要让 ASP.NET 产生相同 HTML 输出的重复序列,直到用尽所有报表数据为止。 为了达到这一目的,我们扩展了 System.Web.UI.Page类的功能。 具体来讲,我们重写了 Render 方法并增加了另外一些其他设计时属性。 利用这个新类,开发人员可以使用标准的 Microsoft Visual Studio .NET 窗体设计器来设定报表页面的布局,设置其属性以及所包含的各个控件的属性,并执行该项目以便生成绑定到传入数据的各个连续组成部分的、具有相同布局的一个 HTTP 响应流。
此报表所生成的一个输出示例包含于 Report.htm 文件中。
我们扩展了该新类的功能以便允许多个输入数据流,在同一报表中使用多个可选的页面布局(例如,第一页,报表总计页,明细页,等等),并能够逐页浏览整个报表(而不用反复访问服务器)。 所有相关的代码都包含在 ReportClass 项目中。 MSDNArticleTest 项目中包含了利用此框架的示例报表定义。


返回页首

我们的方法

ASP.NET 以立即可用的方式支持一次一页 (HTML Form) 的呈现方式。 因此,可以使用它根据用户对报表的每个页面的请求而作出响应,从而呈现该页面。 然而,这需要用户干预才能生成整个报表,并且需要在对服务器的不同访问之间保持游标状态,如果要整体生成该报表,则这可能是一种比较昂贵的需要。
然而,ASP.NET 还提供了设计和运行时可扩展框架,这就使得我们可以更改其默认行为。 在此方法中,我们已经使用了一个新类 (ReportPage) 来重写 System.Web.UI.Page 类(默认情况下,ASP.NET 窗体是从此类派生出来的)的默认窗体处理方式。
Report 类的基本操作体现在其 Render 方法中,该方法重写(并替换)了 System.Web.UI.Page 中的 Render 方法:
首先,跳过与 Form 标记相关的 HTML 生成过程 — 这是不必要的,并且实际上会干扰其他控件 ID 的重复使用。加载一个以足够数据填充报表页的数据集(利用 DataGrid 的页面大小)。 接下来,调用 DataBind以便将数据与页面上的所有控件进行关联。 利用各个控件的标准 Render 方法对其进行呈现;首先加载数据集,重复此操作直到没有要加载的数据为止。 最后,调用结束标记的 Render 方法。


返回页首

利用数据绑定创建报表

我们将要创建的示例报表(如下所述)将提供该报表的下列特性:
一个多页报表,用以查看所有作者(步骤 1 到 13)
当作者状态改变时,进行分页(步骤 14)
根据邮政编码跟踪总数(步骤 15)
列出所有可被重写的函数
显示如何在报表中添加页面导航(步骤 17)
利用数据绑定创建报表
1.创建一个新的解决方案,将其命名为 "CustomReporting"。
2.创建一个类库类型的新 C# 项目,将其命名为 "ReportClass"。
3.删除 Class1.cs 模块。
4.将所附带的 ReportPage.cs 模块下载到计算机。
5.单击该 ReportClass 项目,单击 Add Existing Item,然后将 ReportPage.cs 添加到该 ReportClass 项目。
6.在 ReportClass 项目中添加对 System.Data 和 System.Web 的引用。
7.生成类库以准备好利用数据绑定来创建报表。
8.向 CustomReporting 解决方案中添加一个新的 ASP.NET Web 项目,并将其命名为 "ReportWriterTest"。
9.在 ReportWriterTest 下添加一个到 ReportClass 的引用。 (单击 References,在 Projects 选项卡上,选择 ReportClass 项目。) 包含 ReportClass.dll(显示于 Selected components 部分)。
10.通过添加 Reportclass,编辑 WebForm1.aspx。
11.将
public class WebForm1 : System.Web.UI.Page
更改为
public class TestReport : ReportClass.ReportPage
这样就会强制 Web 页面从 ReportClass.ReportPage 进行继承,这样一来测试 Web 页面就能够利用 ReportPage类(ReportClass 类库的一部分)所公开的属性和方法了。
12.生成 ReportWriterTest 项目。
13.在设计器中编辑 WebForm1.aspx,并设计报表布局。 在本示例中,我们将根据 authors 表(Microsoft SQL Server? 中所驻留的 pubs 数据库的一部分)生成报表。
编辑 WebForm1.aspx 并设计报表布局
a.添加一个包括两行四列的 HTML 表格。
b.编辑 HTML 并删除该表格的 style 属性。
c.将 cellSpacingcellPaddingborder 设置为 0。
在该表格的第一行中,添加两个标签控件。 第一个标签用于 Page 标记,而第二个标签将显示页号;因此它将被命名为 "lblPage" 而文本应被设置为空格。
e.在该表格的第二行中,添加两个标签控件。 第一个标签控件将被用于标签标记状态。 第二个标签控件将被命名为 "lblState",其文本将被设置为 empty spaces
f.在第三行上,删除四列中的三列,仅剩余一列。 将该列的宽度设置为与表格宽度相同。
g.在 HTML 表格中,把一个数据绑定网格控件拖到第三行。
h.编辑该数据绑定网格列集合,并设置四列;分别用于作者的姓、名、地址和城市。 利用 Bound Column 并根据邮政编码统计页面总数。 请注意: 在运行时,请取消选中 Create columns automatically
i.在第四行上,添加另两个标签。 第一个标签的文本将被设置为 total,而第二个标签的文本被设置为 empty spaces且将被命名为 "lblTotal"。
j.将整个表格嵌入一个面板中,并给该面板指定 ID 为 Page1。 确保该面板被设置为在服务器上运行。
k.将一个非类型化数据集拖到窗体上。
l.导航至 Properties 选项卡并选择 WebForm1.aspx 页。 将 dataset属性设置为该页面上的数据集。 将 data-bound 网格设置为页面上的数据绑定网格。
m.在该 Web 页面的 Page_Load 事件中填充该数据集。
n.包含以下代码,以便填充数据集:
private void Page_Load(object sender, System.EventArgs e)
{
if ( IsPostBack) return;
string sConnectionString = "Provider=SQLOLEDB;data source=.;
initial catalog=pubs; User ID=sa; Password=****";
string sSQL = "select au_lname, au_fname, address, city, state,
zip from authors order by state";
OleDbConnection dbCon = new OleDbConnection(sConnectionString);
OleDbCommand dbCmd;
OleDbDataAdapter dbAdapt = new OleDbDataAdapter();
try
{
dbCon.Open();
dbCmd = new OleDbCommand(sSQL, dbCon);
dbAdapt.SelectCommand = dbCmd;
dbAdapt.Fill(dataSet1);
dbAdapt.Dispose();
dbCmd.Dispose();
}
catch (Exception e1)
{
Response.Write("Database error   " + e1.Message);
}
finally
{
dbCon.Close();
dbCon.Dispose();
}
}
14.根据列设置页面组/组分隔符:
base.TrackColumnBreaks("one", "state");
This will provide an override function and exposes the row that accounted for column/page break.
protected override void ProcessPageBreak()
{
lblState.Text  = CurrentDataRow["state"].ToString();
}
15.设置并跟踪总数:
base.TrackTotals("zip",ReportClass.TotalsScopeEnum.Page);
base.TrackTotals("zip",ReportClass.TotalsScopeEnum.Report);
16.其他可重写的函数包括:ProcessPageBreakPostProcessPageBreakProcessGroupBreakPostProcessGroupBreakProcessReportEndProcessCurrentRow。 建议不要重写 ProcessCurrentRow。 开发人员可根据具体情况来重写这些函数以重置或打印内容。
17.要在报表中添加导航条,请将 Pagenav.js 包含到项目中,并将其包括到每个报表页上。 将 ViewReport.aspx、Reportdetail.htm 和 Reportheader.htm 包括到该项目中。 ShowReport.aspx 中包含一个示例,用以说明如何调用 Viewreport.aspx 进行页面导航。 这种导航功能所完成的唯一动作就是在各个链接(例如,http://localhost/MSDNTest/WebForm1.aspx#Page[1-n])之间移动。


返回页首

运行时

当您执行此报表时,会发生什么情况? Report 类的实际操作都在其 Render 方法中,该方法重写了标准 Page 类中的同一方法。
开始 HTML 标记是通过调用 Controls[0].render 方法而呈现的。 在某个阶段,Control.Render将调用 Page.VerifyRenderingInServerForm。 此函数的默认实现方法将引发一个异常;因此,在 Report 类中重写此函数是为了不进行任何操作。
ReportClass 循环处理数据集 tables[0] 以便创建一个多页报表。 调用 LoadPage方法以便将足够数据加载(首先清除)到 DataSet 中,从而生成下一页报表。 LoadPage方法是可重写的,因此您可以在此处提供自己的逻辑。 此外,LoadPage 方法会调用虚拟函数 OnNextRow,您可以重写此虚拟函数以便进行一些特殊的处理,例如,检测数据分隔,计算小计(您可以将其保存在数据集的一个表中)等等。如果您确实要重写这些方法,并想要强制进行分页,则应将 Report.m_PageFull 设为 True。 要完全停止进一步的输出,请将 MoreData 设为 TrueLoadPage 会调用 DataBind 方法。
Page.Render 方法插入 Html 以便强制进行分页。 调用 AllControls.RenderControls方法以便强制呈现页面上的各个控件。 重复进行以上步骤,直到所指定的数据集中数据行耗尽为止。 结束 HTML 标记 (Controls[2].RenderControl) 被调用,数据库连接被关闭,Render 完成。


返回页首

小结

本示例说明了如何能够利用相对很少的几行代码将 ASP.NET 的基本范例从呈现 HTML 窗体更改为生成多页报表。 现有 ASP.NET 基础结构的绝大部分都原封未动 — 所有的工具箱控件都是可用的,可通过属性窗口设置这些控件的呈现属性,且真正的呈现过程仍然由现有代码执行。 然而,所生成的输出却可用作一个明显不同的用途。


返回页首

致谢

在此,我们想感谢以下人士:
Microsoft 咨询服务部门的 David Powell 和 Scott Beaudreau 帮助我们开始使用 .NET 并指导小组完成了本项目的初始阶段
Mark Wadsworth、Frank Degise 和 Linda Sutton 不断提供支持和鼓励,才使我们得以出版这篇文章。
Tushar Patwardhan 和 Neeraj Pathania 帮助测试和修复了所有问题,我们还要感谢 Chandra 在 EDS Corporation 的小组同事。


返回页首

关于作者

Chandra Kamalakantha 就职于EDS Corporation,该公司是领先的全球信息技术 (IT) 服务公司。 如果有问题和意见发送给 Chandra,请发送电子邮件至 Chandra.kamalakantha@eds.com
Marius Rochon 是 Microsoft 公司的一名 Technical Evangelist。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息