报表性能优化方案之多数据集实现层式报表

by admin on 2020年1月28日

我们接着从报表设计这一部分开始阐述:
3、报表设计

多数据源报表即一张报表中可以定义多个数据集,分别取出需要的数据库表,所取的数据库表甚至可以来自于不同的数据库。本文通过几个例子说明多个数据集数据如何相互关联来实现多源报表。

1. 问题描述
若报表使用的数据量是上百万条的话,觉得报表展现的速度慢,可以使用层式报表来提高报表展现速度。但由层式报表章节可以得知,层式报表必须是单数据集,若是多数据集的模板且数据量又很大,想要提高报表的查询速度要如何实现呢?

建立了数据库连接之后,我们就可以开始设计报表了。首先看一下我们要设计的报表格式:

1. 描述

2. 实现思路
在定义数据集时通过使用数据库本身的行序号或者使用数据库函数生成行序号(即行号)并且在where条件中通过页码参数使得行号在一定范围内显示,点击自定义的上一页下一页按钮时重新传入页码参数取出相应的数据。

图片 1

多数据源,就是在同一张报表当中,显示的数据来自于多个不同的表或不同的库。

注:SQL
Server2000无法生成行号,因此需要定义存储过程实现分页查询,以下具体介绍Access实现分页的步骤,SQL
Server2005以及Oracle数据库实现分页的步骤有一点区别,以下会详细介绍。


是一个典型的多层交叉表。交叉表,是相对于传统的分组报表来说的。分组报表只有纵向的分组,也就是分组列在最左侧。交叉表就是指报表的横向和纵向都有分
组。例如我们上面这张报表,纵向和横向分别有两层分组。即,左侧的地区,姓名分组,上方的类型和产品分组。该报表设计的过程,可以分为如下几个步骤:

如下图一张简单的多数据源报表,左侧蓝色部分来自于销量表,右侧黄色部分来自销售总额表,即数据来自于两张不同的数据库表:

3. Access分页示例
3.1 新建模板
新建模板mutipage.cpt,为了加快展示速度,我们可以使用分页查询,获取每个产品的详细信息并计算产品对应的订单中的应付金额,因此添加数据集时查询SQL语句为select
产品.产品ID,产品名称, 供应商ID , 类别ID, 单位数量, 产品.单价,
产品.库存量, 产品.订购量,sum(应付金额) as 应付款项 from
产品,订单,订单明细 where 产品.产品ID=订单明细.产品ID and
订单明细.订单ID=订单.订单ID and 产品.产品ID between 10*(${page}-1)+1
and 10*${page} group by 产品.产品ID,产品名称, 供应商ID , 类别ID,
单位数量, 产品.单价, 产品.库存量, 产品.订购量 order by
产品.产品ID,设置参数page的默认值为1,首次看到的是第一页,只查询出第1~20条记录;若page参数为2时,查询出第21~40条记录,即第二页内容。

新建报表

                图片 2       

注:这边定义报表每页显示10条数据,即ds1的查询SQL一次只取10条数据,从而加快报表展示速度。

定义数据源

2. 示例

3.2 自定义上一页、下一页按钮
使用分页查询后,报表需要根据page参数查询出行号在一定范围内的数据,当点击下一页时,page需要加1并传入报表查询出后10条记录;点击上一页时,page需要减1并传入报表查询出前10条记录。而报表内置的上一页下一页按钮无法做这些操作,因此需要自定义上一页下一页按钮。

绑定数据列

2.1 打开单个数据源报表

  • 在单元格中求出上一页、下一页页码的值

汇总

打开报表%FR_HOME%WebReportWEB-INFreportletsdocPrimaryCrossReportCross.cpt

在工具栏中无法直接获取page参数的值,因此先在单元格中求出上一页下一页的页码值,然后再在工具栏按钮中获取单元格的值。

格式化报表

2.2 新增数据源

图片 3

步骤一:新建报表

再新增一个数据集ds2,其SQL语句为SELECT * FROM
[销售总额]
。ds2数据集与ds1数据集都有一个销售员字段。

  • 自定义上一页下一页按钮

这一步,就是要选择新建报表的类型,该类型选择共分为三种,分组报表,自由报表。我们的报表设计主要是自由报表类型。因此在下面的报表设计器当中,我们无论选择哪种新建方式,选择的报表类型都可以是自由报表。

2.3 绑定数据列

点击模板>模板web属性>分页预览设置分,选择为该模板单独设置,在工具栏中增加两个自定义按钮分别命名为上一页,下一页,是工具栏上只剩下如下图所示几个按钮。

新建报表的第一种选择,是点击文件|新建报表,通过二级菜单来选择要新建的报表类型。如下图所示:

如下图,将ds2中销售总额数据列拖拽到单元格中,并设置父格为销售员所在单元格,使销售总额跟随销售员而扩展:

图片 4

图片 5

 图片 6

3.3 第一页与最后一页的处理
首次访问报表时,默认显示第一页page=1,此时上一页按钮应该是无效的,否则点击上一页按钮时(页码为0),此时查询行号在-9到0之间的记录将会出错;同样,显示到最后一页时需下一页按钮无效。即当上一页页码page-1=0时,上一页无效;当下一页页码page>总页数时,下一页无效。

第二种途径是在工具栏当中,点击新建报表按钮右侧的下拉箭头,出现报表类型选择的列表,如下图所示:

2.4 设置过滤

  • 求出总页数

图片 7

此时设计器预览,效果如下:

根据总记录数及每页显示条数,求出总页数。新增数据集ds2,SQL语句为:SELECT
count(*) as 总数 FROM 产品,查询出产品表总条数,拖入单元格,如下

另外,还可以直接点击工具栏当中的新建按钮,系统将弹出如下报表类型选择的对话框:

 图片 8

图片 9

图片 10

可以看到,扩展出来的每一个销售员下,都重复显示销售总额字段的所有数据。

双击总数所在单元格弹出数据列设置对话框,选择高级>自定义显示,在自定义中填入公式:roundup($$$/10,0)求出总页数。

我们设计的主要报表类型是自由报表,因此,选择自由报表类型。打开报表设计界面。

虽然销售总额的父格为销售员数据列,由于他们来自于不同的数据集,因此销售总额不会将父格销售员作为条件进行筛选,即不存在附属关系。

将第一行的行高设置为0,或者是隐藏:

步骤二:定义数据源

我们需要销售总额与销售员一一对应,就需要设置过滤条件,将这两个数据集的数据通过销售员关联起来。

图片 11

在选定了报表类型之后,我们需要将报表当中用到的数据进行定义,也就是从数据库当中找到我们在该张报表当中需要用到的数据表。关于公有数据源和私有数据源的详细区别,请参见配置数据源章节。

选中销售总额所在单元格,设置过滤,添加过滤条件:销售员 等于
‘C4’
,取出与C4单元格中销售员匹配的数据,如下图:

上一页按钮设置:选中上一页自定义按钮,点击自定义JavaScript,在js中填入:

在上一个步骤当中,点击确定选定报表类型,系统会自动弹出一个私有数据源对话框。如下图所示:

 图片 12

  1. var page= $(“tr[tridx=0]”,”div.content-container”).children().eq(0).html();    
  2. if(page==0)//如果报表显示第一页,则上一页不可用  
  3. this.setEnable(false);  
  4. else  
  5. window.location.href=”${servletURL}?reportlet=doc/Advanced/multipage.cpt&page=”+page;   

图片 13

2.5 保存并预览

注:第一句是获取上一页页码(A1单元格)的值,其中最后的html()可以用Text()代替;第二句是重新加载报表并给page参数赋值。

点击左上角的添加按钮,新增一个数据源,会弹出一个定义名字的对话框,我们命名为ds1(这里ds是datasource的缩写),点击确定打开私有数据源的编辑页面。

保存模板,预览报表,即可看到如上的效果。

上一页按钮设置:下一页按钮设置与上一页的js差不多,只需要获取B1的值就可以了,所以在js中填入:

图片 14

3. 多数据源报表优势

  1. var page= $(“tr[tridx=0]”,”div.content-container”).children().eq(1).html();    
  2. var total=$(“tr[tridx=0]”,”div.content-container”).children().eq(2).html();    
  3. if(parseInt(page) > parseInt(total))//如果报表显示最后一页,则下一页不可用  
  4. {  
  5. this.setEnable(false);  
  6. }  
  7. else  
  8. window.location.href=”${servletURL}?reportlet=doc/Advanced/multipage.cpt&page=”+page;   

在SQL文本框中,写入SQL语句“select
* from
sale”。点击文本框下方的预览按钮,即可以看到数据库数据的预览。点击确定打开报表设计界面。

多数据源报表传统的做法,是通过拼SQL将多源整合为单源。如上例中将销量表与销售总额表整合起来:SELECT
* FROM
销量,销售总额 WHERE 销量.销售员 =
销售总额.销售员 
。若数据库表比较复杂,且使用的表个数不止2张而是更多时,可以想象,最终的SQL查询语句将会非常复杂。

注:首次打开报表的时候,由于page参数是在数据集中定义的,数据集参数的默认值在第一个次打开报表时没办法传到单元格中,所以需要定义一个完全一样的模板参数page,默认值设为1。这样,首次打开模板时,上一页按钮同样不可用。

图片 15

FineReport天然支持多数据源的报表,一张报表中可以添加任意多个数据集,每个数据集使用最简单的SQL语句查询出需要的表数据,在报表中只需要使用过滤就可以将来自不同表的数据相互关联起来。使得多数据源报表制作更加简单。

分页预览,即可查看效果。mutipage.cpt

报表设计界面里面,在左侧的数据面板,私有数据源处,可以看到我们刚刚定义的私有数据源ds1。

图片 16

图片 17

具体模板可参考:%FR_HOME%WebReportWEB-INFreportletsdocAdvancedmutipage.cpt。

步骤三:绑定数据

4. SQL Server2005示例
SQL Server2005使用ROW_NUMBER() OVER (ORDER BY 主键字段) AS
rowno生成行号。

首先,我们先来设置左侧的分组。将ds1中的字段Region字段拖拽到A3单元格中,保留其默认的设置,即数据纵向扩展,并且进行分组,合并相同内容的值。

因此只需要修改数据集ds1查询SQL语句为select * from (SELECT
*,ROW_NUMBER() OVER (ORDER BY year_school_id) AS rowno FROM
year_school) as b where b.rowno between 20*(${page}-1)+1 and
20*${page}即可。

将Manager字段拖拽到B3单元格中,同样保留其默认的设置,即数据纵向扩展,并且数据分组,即合并相同内容的值。

5. Oracle示例
Oracle数据库中本身有行序号ROWNUM,因此只需要将上例ds1数据集修改成如下:SELECT
* FROM (select A.*,ROWNUM rn from (select * from year_school) A
where ROWNUM <=${start}+20) where RN >=${start}即可。

然后,我们来设置上方的分组。首先在数据源面板的最下方扩展方向中默认的设置从上到下更改为从左到右。
图片 18
  
   
将ProType拖拽到C1单元格中,其设置为扩展方向是横向的,从左到右,数据是分组,即合并内容相同的值。

注:ROWNUM只支持小于,大于是不支持的,因此要做如上定义。

将Product字段拖拽到C2单元格中,由于我们在上一步操作已经设置了扩展方向为横向,所以B2单元格我们也保留默认的设置:横向扩展,数据合并内容相同的值。

最后,来添加交叉区域当中的汇总字段。首先在数据源面板当中,将扩展方向由从左到右更改为不扩展。然后下方的汇总当中,选择求和。

  
图片 19

·                    
将Amount字段拖拽到C3单元格中,也就是对所有的销售量记录进行求和。

  
图片 20

如上所示,这张报表,C3当中的汇总数据,既跟随左侧分组扩展,又跟随上方分组扩展。所以形成一个交叉的区域。

步骤四:汇总

完成了数据列绑定,我们来给报表添加汇总数据。

将A3和A4单元格进行合并,合并后的单元格根据FineReport的单元格命名规则,为A3。

在B4当中,写入文字“小计:”。

在C4当中,写入公式“=sum(C3)。由于我们已经合并了A3和A4单元格,所以这里C4就会跟随A4的分组进行合计。

注:这里合并单元格的作用,是使得C4当中的汇总单元格跟随A4的分组进行组内汇总。如果我们不合并单元格,则C4当中的汇总,就会显示在报表所有数据的下面,成为对所有数据的汇总。

步骤五:格式化报表

上一步当中,我们已经完成了报表主体的数据的设置。现在我们要给单元格添加边框,表头的斜线,以及文字居中等简单的格式化操作。

·                    
边框:首先我们先来选中从A1至C3这一片区域,点击工具栏中的按钮,在系统弹出的边框对话框中,添加内部和外部边框。

·                    
斜线:选中A1至B2共四个空白的单元格,点击工具栏中的按钮,合并单元格。右键该单元格,选择单元格元素,在二级菜单中,选择斜线。系统会弹出一个斜线编辑的对话框,在文本编辑框中写入我们在斜线当中要加入的内容:Products|Names,可以通过添加空格来调整文字的位置。如下图所示:

  
图片 21

·                    
文字居中:用鼠标选中A1至B3整个报表所在的区域,在工具栏当中,点击,也就是文字居中按钮,将报表当中的数据全部居中显示。报表的最终设计图如下所示:

  
图片 22

最后,预览,即可以得到我们在开始展示的报表效果。该报表在示例当中存储的路径为“../WebReport/WEB-INF/reportlets/com/doc/cross.cpt。

4、发布和浏览报表


报表设计完成之后,我们将其保存在安装目录下的“../WebReport/WEB-INF/reportlets/com/..”目录下,例如我们刚刚
设计的报表,其保存的路径和名称为“../WebReport/WEB-INF/reportlets/com/doc/cross.cpt”。这样就完
成了报表在服务器上的部署。


操作系统的“开始菜单”找到FineReport6.0的快速启动程序,启动“报表Web演示”。系统会启动自带的应用服务器,并且在IE浏览器中打开自
带的报表演示页面。您可以在浏览器中输入如下地址:
reportlet=/com/doc/cross.cpt,即可以在浏览器中打开报表。如下图所示:

图片 23

论坛专区与专家交流

完善的报表使用文档和二次开发文档

更多了解,敬请关注:www.finereport.com

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图