使用ActiveReport for net 进行报表开发.docx
《使用ActiveReport for net 进行报表开发.docx》由会员分享,可在线阅读,更多相关《使用ActiveReport for net 进行报表开发.docx(22页珍藏版)》请在冰点文库上搜索。
使用ActiveReportfornet进行报表开发
使用ActiveReportfor.net进行报表开发
(一)--开始
ActiveReport是.net下的一个出色的报表开发程序,虽然和水晶报表相比,名气不那么大,甚至有很多人不知道它的存在,但是并不妨碍它在.net报表开发中的出色表现,本文将一步一步地介绍如何使用它和VS2005开发.net报表。
1. 安装:
你可以从DataDynamics的网站上下载最新的ActiveReportfor.net2,你可以免费使用,但是在生成的报表最下边有水印,不过不影响报表的整体美观。
下载后直接安装就可以了。
安装完后会看到开始-程序菜单里的DataDynamics的目录,里面包括了,帮助,例子程序等。
2. 第一个Winform报表程序。
在安装完成后,启动VS2005,会看到启动界面上有ActiveReport的图标,进入后新建一个工程,并且给工程添加新文件,在文件类型中就可以看到ActiveReport文件的图标。
给报表文件命名为ActiveReport1,确定后会看到项目中有一个ActiveReport1.rpx文件,这个就是报表文件了。
打开文件,就是报表的设计界面,在这里可以看到三部分,PageHeader(表头),Detail(明细),PageFooter(表尾)。
打开工具箱,给Detail部分随便添加一个Label。
下面就要显示这个报表了,在Form上添加一个Viewer控件,如果工具箱里没有,可以通过配置工具箱来找到它。
Viewer添加完后,在Form中写代码:
ActiveReports1rpt=newActiveReports1();
rpt.Run();
this.viewer1.Document=rpt.Document;
然后F5运行,就可以看到在Viewer控件中显示报表了。
要注意的是,项目名称不要命名为ActiveReport,否则会提示找不到ActiveReport.rpx文件。
3. 第一个web报表程序。
Web方式的报表开发方式和winform的差不多,不同的是,web方式下需要作一些配置,配置过程不再累述,可以在帮助里搜索“ManuallyConfiguringWebSamples”,按照里面的步骤对IIS作配置。
要注意的是,如果使用的是VS2005,那么可以不作配置,只要在创建Web项目的时候文件位置选项设置为“文件系统”就可以直接运行了。
还要注意的是,在web方式下,需要在web.config文件中添加下面这段:
如果是VS2005,系统会自动添加。
接下来的就和winform下的差不多了,不同的是,要在解决方案中新增一个“类库”项目,在这个项目中新建报表文件,然后在Web项目中添加对类库项目的引用,然后在页面上添加WebViewer控件,然后编写代码:
this.WebViewer1.Report=newYourNamespace.ActiveReports1();
然后运行界面,就可以看到在WebViewer中加载的报表了。
你可以通过WebViewer的ViewType属性来设置在页面上如何显示,例如,如果选择了AcrobatReader,就会给报表生成一个PDF文档在页面上嵌入显示。
下次我们将演示如何在报表上加载和显示数据
使用ActiveReportfor.net进行报表开发
(二)--绑定数据源
在上篇随笔中写了一个使用ActiveReportfor.net的最简单的例子,本文将演示在ActiveReport中如何绑定数据源
1. 先建一个表chartingTable,有两个字段,OnlineUserCount,Project,通过向导生成DataSet,并拖放生成TableAdapter。
2. 接下来在报表设计器中设计显示格式,在PageHeader中放置两个label,分别为“项目”和“在线人数”。
再在Detail区方式两个对应的Label,分别设置DataFiled为Project和OnlineUserCount,在运行的时候将会看到这两个Label显示的是对应字段中的内容。
3. 可以给报表指定DataSet或DataView作为数据源,下面演示给报表设置数据源:
使用DataSet:
this.chartingTableTableAdapter.Fill(this.dataSet1.ChartingTable);
rpt.DataSource=this.dataSet1;
rpt.DataMember=this.dataSet1.ChartingTable.TableName;
rpt.Run();
this.viewer1.Document=rpt.Document;
使用DataView:
this.chartingTableTableAdapter.Fill(this.dataSet1.ChartingTable);
DataViewdv=this.dataSet1.ChartingTable.DefaultView;;
rpt.DataSource=dv;
dv.RowFilter="project='1'";
rpt.Run();
this.viewer1.Document=rpt.Document;
4. 我们还可以通过报表设计器来给报表指定数据源。
在报表设计器的Detail部分的头部,有一个数据库一样的小图标,点击它后会出现向导,按照向导一步步连接数据库,并定义查询就可以了。
上面演示的是使用数据集作为数据源进行绑定,但是实际项目中经常会用到使用对象集合作为数据源显示,下一次我们将演示如何在报表上显示一个对象集合中的数据。
使用ActiveReportfor.net进行报表开发(三)--显示对象集合中的数据
上篇随笔演示了在ActiveReportfor.net中如何绑定数据源,例如DataSet,DataView。
本文将通过一些示例代码继续演示如何绑定对象集合以及如何从对象集合或列表中提取数据。
1. 直接绑定:
我们可以自己定义一个Collection,从IList继承,并使其中的每个对象都是一个实体,例如:
Customer和CustomerCollection。
然后给ActiveReport报表的DataSource直接赋值为CustomerCollection的实例就可以了。
这种绑定方法在ActiveReportfor.net自带的例子里有完整的演示。
2. 手工加载显示对象的数据:
在这里要用到两个事件:
DataInitialize和FetchData。
DataInitialize用来定义字段列表,获取数据等工作,FetchData用来指定每个字段的值。
我们简单定义一个Customer类
publicclassCustomer
{
publicintID;
publicstringName;
publicstringAddress;
}
再给报表定义一个Customer数组,用来保存要显示的数据,比如:
publicCustomer[]customers;
还需要一个值来保存当前记录的索引:
privateintindex=0;
接下来在DataInitialize中定义报表有那些字段:
this.Fields.Add("Name");
this.Fields.Add("Address");
然后在FetchData事件中添加以下代码:
if(this.index>=this.customers.Length)
{
eArgs.EOF=true;
return;
}
else
{
eArgs.EOF=false;
}
this.Fields["Name"].Value=customers[this.index].Name;
this.Fields["Address"].Value=customers[this.index].Address;
this.index+=1;
这段代码的含义就是将Customer数组中的每个Customer实例的Name和Address属性值赋给报表的Name和Address字段。
代码中的第一个if分支是判断是否已经加载到了最后一条数据,如果是,设置eArgs.EOF为ture,并返回,否则继续加载下一条数据。
然后我们可以将要显示的数据放在Customers数组中,并启动显示报表:
Customer[]customers=newCustomer[2];
Customerc=newCustomer();
c.Name="James";
c.Address="Noljadfallsjf";
Customerc2=newCustomer();
c2.Name="Joe";
c2.Address="adfaafadf";
customers[0]=c;
customers[1]=c2;
rpt.customers=customers;
rpt.Run();
this.viewer1.Document=rpt.Document;
通过上面的示例可以看到,第二种方式虽然比较烦琐,需要程序员自己处理很多东西,但是这样程序员拥有完全的操控能力,特别是需要对取出的数据作很多复杂的处理时,这样的操控能力是非常重要的。
在下一篇随笔中,将展示如何使用子报表来作显示主从表。
使用ActiveReportfor.net进行报表开发(四)—显示主从表
上篇随笔演示了在ActiveReportfor.net中如何从对象集合中提取数据。
本文简单介绍如何使用子报表来显示主从表中的数据。
1. 在需要显示主从表中的数据时,使用子报表能够提供很大的灵活性,一般就是把主表的信息显示在detail中,如果要每页的上方都要显示主表,就可以放在PageHeader中。
再把子表的信息放在Detail中,然后把子报表中的控件直接绑定到数据源上或者使用上篇随笔中的提到的方式从对象集合中提取数据。
2. 使用子报表:
新建报表,然后在工具箱上可以看到SubReport控件,拖放一个控件到Detail部分,用此控件来加载子报表。
再新建一个报表,命名为SubReport1,接下来在主报表中写代码,在页面设计器上选中Detail部分,在属性窗口切换到事件栏,双击Format,将会产生Detail_Format事件,下面就要在这个事件里指定子报表控件所要加载的报表。
3. 由于Detail部分会进行重复显示的,所以,只能指定一次报表源,在这里,我们按照下面的例子:
ActiveReportsub=null;
privatevoidDetail_Format(objectsender,System.EventArgseArgs)
{
if(sub==null)
{
sub=newActiveReports2();
this.SubReport.Report=sub;
}
}
先定义一个全局的子报表,然后在Detail_Format事件中对其进行初始化。
4. 还有要注意的一点是,在使用完子报表后要将其释放,销毁掉,具体的代码放在主报表的ReportEnd事件中,例如:
privatevoidActiveReports1_ReportEnd(objectsender,System.EventArgseArgs)
{
sub.Document.Dispose();
sub.Dispose();
sub=null;
}
5. 下面剩下的工作就是摆放控件并设置显示的字段了,加载数据等等了,前面的随笔都有介绍。
下篇随笔中将介绍如何使用ActiveReportfor.net开发交叉报表。
使用ActiveReportsfor.net进行报表开发(五)—交叉报表
交叉报表是一种常见的报表类型,而且开发起来也是比较烦琐的一种报表,在ActiveReport中,对交叉报表提供了足够的灵活性,使你能够应对各种复杂的业务逻辑。
在上篇随笔演示了显示主从表后,本篇随笔简单介绍如何制作交叉报表。
交叉报表的一个常见应用就是用作显示销售额的报表上,例如,显示多个连锁店一年内每个月的销售额,常把月份作为列来显示,每个店用一行来表示:
店名 1月 2月 3月 4月 ……………
AC 500 200 10000 50000 ……………
BC 511 85245 4545 124578 ……………
但是在数据库中的存储常常采用下面的方式
Sales Month Shop
12312 1 AB
243423 2 AB
323232 3 AB
1231312 1 BC
1232 2 BC
这样就需要在显示前对数据进行处理,把销售额和月份转换到列上,我们可以在取数据时使用sql来进行这些操作,在这里,为了演示在activeReport中的使用,把转换放到报表里来作,为了简化例子,我们只显示第一个季度每月的销售额。
1. 取数据:
使用SelectSales,Month,ShopfromCrossReportOrderbyShop这样的sql直接取数据,不作任何合计或转换处理。
2. 转换:
我们来定义一个简单的对象来表示最终要显示的记录:
publicclassSale
{
publicdecimal money1;//一月
publicdecimalmoney2;//二月
publicdecimalmoney3;//三月
publicstringshopname;
}
同时在定义一个Sale的集合sales,来保存转换后的数据。
由于在表中每个店会对应多条记录,为了把多条记录合并为一条,要进行下面的转换动作:
//用来保存已经计算过的店铺,保证每个店铺只有一条记录
ArrayListshopname=newArrayList();
while(dr.Read())
{
if(!
shopname.Contains(dr.GetString
(2)))//该店铺的第一条记录
{
Sales=newSale();
s.shopname=dr.GetString
(2);//取店名 shopname.Add(s.shopname);
if(dr.GetInt32
(1)==1)//一月
{
s.money1=dr.GetDecimal(0);
}
elseif(dr.GetInt32
(1)==2)//二月
{
s.money2=dr.GetDecimal(0);
}
elseif(dr.GetInt32
(1)==3)//三月
{
s.money3=dr.GetDecimal(0);
}
sales.Add(s);
}
else//不是该店铺的第一条记录
{
Sales=(Sale)sale[sales.Count-1];
if(dr.GetInt32
(1)==1)
{
s.money1=dr.GetDecimal(0);
}
elseif(dr.GetInt32
(1)==2)
{
s.money2=dr.GetDecimal(0);
}
elseif(dr.GetInt32
(1)==3)
{
s.money3=dr.GetDecimal(0);
}
}
}
3. 表示:
上面是对从数据库中取出的记录作转换,将其变成在报表上要显示的格式。
接下来就要在报表上显示Sales集合中的数据了。
我们可以按照前几篇随笔中介绍的方法来作:
在界面上摆放控件,并设置其FiledName字段
在报表的DataInitialize事件中设置Filed集合,取出数据:
this.Fields.Add("money1");
this.Fields.Add("money2");
this.Fields.Add("money3");
this.Fields.Add("shopname");
this.GetReportData(); //取数据并作转换
设置一个标记来表示是否显示到了最后一条记录:
intindex=0;
在FetchData事件中显示Sales集合中的数据:
if(index==sales.Count)//如果到了最后一条记录,就跳出
{
eArgs.EOF=true;
return;
}
else
{
eArgs.EOF=false;
}
Sales=(Sale)sales[index];
this.Fields["shopname"].Value=s.shopname;
this.Fields["money1"].Value=s.money1;
this.Fields["money2"].Value=s.money2;
this.Fields["money3"].Value=s.money3;
index+=1;
按照上面的步骤,主要的代码都完成了,当然要在窗体上显示,还要加一个Viewer,然后指定加载的报表:
ActiveReports1rpt=newActiveReports1();
rpt.Run();
this.viewer1.Document=rpt.Document;
如果你不满意显示的效果,可以给报表加上线框,让其显示成表格。
总结:
例子中的代码有重复,但是为了说明转换的过程,没有作优化,另外,也可以看到,代码中使用了ArrayList,出现了装箱,拆箱的动作,所以性能还有优化的空间。
从表数据到显示用数据的转换可以在Sql中作,但是业务逻辑较复杂的时候,Sql就显得力不从心,例如,显示每月的数据,而且还有收入,支出,如果再加上税收,折扣,损耗,租金,和上年同期的比较等等无法预测的业务逻辑,如果把SQL写在代码中,调试成问题,如果写成存储过程,有破坏了封装。
所以相比之下,在代码中进行的转换工作虽然较复杂,但是还是具有灵活的优势的。
使用ActiveReportsfor.net进行报表开发(六)--导出报表
ActiveReport提供了多种文件格式的导出,包括:
Html,Pdf,Text,Rtf,Xls,Tiff,这几种格式中,Pdf是效果最好