Dorado 5 : 07.EXCEL报表 (T1A)

在dorado5.1版本中添加了excel报表功能,主要用于将查询结果报表导出,并支持excel模板功能。dorado的excel导出可以与dataset关联。使用非常灵活,功能十分强大。通过设计者的丰富想象力,可以用各种报表形式展示数据库表的查询统计结果。

报表生成方式

快速生成excel报表展示主要分两种形式:数据导出模式和直接报表调用模式。
其中数据导出模式是通过Export2ExcelCommand组件实现,设计时需要在视图模型中定义该组件对象,并在运行时,需要先打开拥有该Command对象的页面才能得到最终想要的excel报表;
而直接的报表调用模式中,用户可以不用打开该页面,而是通过一个特殊的URL直接得到想要的excel报表。

数据导出模式

dorado5中提供了Export2ExcelCommand组件对象用于将查询处的数据结果导出为excel。使用简单,方便,快捷。
最终效果使用体验:

Export2ExcelCommand的使用方法如下:

  1. 生成一个新的视图模型;
  2. 在视图模型页面中添加一个AutoSqlDataset并使得其关联到Employee表上;
  3. 添加Export2ExcelCommand对象,并设置相关的属性设置;
  4. 添加按钮,并绑定到Export2ExcelCommand对象上;

下面通过一个范例演示Export2ExcelCommand的使用方法。

新建视图模型

新建ReportEmployee视图模型:

并在其中新增AutoSqlDataset,命名为datasetEmployee,使其关联到Employee表上。并新增DataTable使其绑定到datasetEmployee。

添加Export2ExcelCommand

在Controls中,通过右键快捷菜单,在Insert的Commands下找到Export2ExcelCommand并添加到视图模型中:

将Export2ExcelCommand对象重命名为commandExport,并设定其dataset属性为datasetEmployee,templateTable属性为tableEmployee对象。
新增Buttong对象buttonExport:

设定其command属性为前面定义的commandExport,并设定value属性为Export(value即为button的显示标题)。

生成JSP页面

利用视图模型的JSP生成向导生成JSP并预览:

单击其中的Export按钮,commandExport立即执行,并得到如下的窗口,提示用户对生成的excel数据报表的处理方式:

如果我们选择打开方式查看,则可以得到如下的excel界面:

通过这个例子,我们已经了解到Export2ExcelCommand的基本使用方式。一个报表就这样快速的生成了。显而易见,这样的报表只能实现一些简单的报表。如果要实现更高级的功能,你就必须通过excel报表的模板功能实现。关于报表模板部分的介绍我们放在稍后的部分介绍。

直接调用模式

直接调用方式是通过访问独立的URL获得报表。对于这种使用方时,我们必须定义报表模版,对某个报表的访问可以看作是对某个报表模版的访问。

报表模板简介

报表模板是为了使excel报表导出更为灵活而提供的一种excel报表处理机制。在报表模板定义中,我们可以将一个报表模板与一个具体的视图模型关联。并通过其中的EL表达式语言以及模板中的报表域的属性设定从而得到我们想要的报表格式。
模板的基本用法如下:

新增excel文件作为模板

新增excel文件作为模板。

定义TemplateProperties工作表

在excel文件中添加一个名称为TemplateProperties的工作表,并在该工作表中定义几个系统属性:
viewModelConfig:用于指定该模板与某一个具体的视图模型相关联;
viewModelClass:用于指定视图模型的实现类;
defaultDataset:模板的默认操作数据集合,可省略;
如下图:

定义DoradoReport工作表

在excel文件中添加一个名称为DoradoReport的工作表,并在该工作表中定义报表域对象,报表域是指Excel模版中某个具有别名矩形区域,excel报表使用一些带有特殊含义的别名来描述这些矩形区域的功能和行为。别名的基本语法为:

_域类型

_域类型.绑定的Dataset的id

_域类型.绑定的Dataset的id.其他参数

目前支持的域类型有:

  1. _DataBand 数据域:数据域往往并没有特定的实际作用,在数据域之外同样可以引用报表数据。数据域最常见的用途是为某个区域定义默认的Dataset。这样可以在一定程度上减轻模版定义的工作量。如:_DataBand.dataset1表示在该区域中使用dataset1作为默认Dataset。_DataBand.$表示使用父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset作为该区域的默认Dataset,不过这样定义没有任何实际意义。
  2. _DataRepeator 数据迭代域: 数据迭代域会自动根据Dataset中的记录向下复制自己。_DataRepeator或_DataRepeator.$表示根据父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset进行迭代。_DataRepeator.dataset1表示根据dataset1进行迭代。
  3. _DataGroup 数据分组域:数据分组域用于对迭代的记录进行分组,并且根据每一个分组自动的向下复制自己。数据分组域根据某个指定的字段,按照相邻数据相等的原则对数据进行分组。并且在进行分组时不会对记录进行重新排序,因此不相邻的两段相同数据将被认为是两个组。数据分组域可以嵌套,但最后一个数据分组域中必须包含一个数据迭代域。的即每一个数据分组域中都应该包含一个数据分组域或一个数据迭代域。_DataGroup.dataset1.deptId表示根据dataset1中的deptId字段对记录进行分组。_DataGroup.$.deptId表示根据父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset中的deptId字段对记录进行分组。
  4. _DataBlock 数据块:数据块会自动根据Dataset中的记录在数据块容器(_DataBlockContainer)所指定的空间内按照流式布局复制自己,且一旦数据块容器所指定的空间被排满,则停滞迭代。数据块的定义方法与_DataRepeator类似。例如:_DataBlock.dataset1
  5. _DataBlockContainer 数据块容器:数据块容器中必须且只能包含数据块(_DataBlock),用于为数据块的迭代复制划定空间。数据块容器在定义时不支持绑定
利用EL表达式设定数据显示

定义好模板的报表域之后,接下来我们就可以利用EL表达式定义要显示的数据了。
例如:

${datasetEmployee.employee_name}

上述的表达式即表示要访问datasetEmployee的当前记录的employee_name字段的值。
设定一个报表域,并定义其值为:

_DataRepeator.datasetEmployee

以上代码表示表示该迭代域根据datasetEmployee进行迭代。如果我们在该域中的一个单元格中定义表达式${datasetEmployee.employee_name},则表示在该域中迭代输出datasetEmployee的用工姓名。
报表定义视图如下:

最终效果如下:

系统配置

为了使系统支持直接调用模式,使定义好的模板生效,我们必须在web.xml中添加一个servlet的声明:

 <servlet> 
 	<servlet-name>dorado-excel-report</servlet-name> 
 	<servlet-class> 
 		com.bstek.dorado.report.excel.ExcelReportServlet 
 	</servlet-class> 
 	<init-param> 
 		<param-name>templateBase</param-name> 
 		<param-value>classpath:</param-value> 
 	</init-param> 
 </servlet> 
 <servlet-mapping> 
 	<servlet-name>dorado-excel-report</servlet-name> 
 	<url-pattern>*.report</url-pattern> 
 </servlet-mapping>

修改好web.xml之后,我们还需要将xls模板文件拷贝到web应用的classes目录中,便于servlet可以找到它。
重新启动web服务之后我们就可以通过如下的URL访问模板文件,直接得到报表:

报表实做

该实例的实做是基于上一节数据导出的实例基础上完成的,因此在实现该例子之前必须先完成数据导出一节的范例开发。

  1. 在src目录中新增report目录,在该目录中新增excel文件,并命名为reportEmployee.xls;
  2. 在reportEmployee.xls中添加两个工作表,分别为DoradoReport,TemplateProperties;
  3. 在TemplateProperties工作表中定义三个属性:

    属性

    viewModelConfig

    ReportEmployee

    viewModelClass

     

    defaultDataset

     

  4. 利用EL表达式在DoradoReport工作表中定义一个报表标题:


其中的C3到H3中的值分别为:

位置

C3

${datasetEmployee.employee_name.label}

D3

${datasetEmployee.sex.label}

E3

${datasetEmployee.birthday.label}

F3

${datasetEmployee.degree.label}

G3

${datasetEmployee.salary.label}

H3

${datasetEmployee.email.label}

  1. 在DoradoReport工作表中定义一个报表域:

选择C4-H4的区域,并打开鼠标右键,选择命名单元格区域,如下图:

在属性中输入:

_DataRepeator.datasetEmployee

  1. 在DoradoReport工作表中用EL表达式定义展现数据:

在C4到H4单元格中,分别设定值为:

位置

B4

${$.getCount(false)}

C4

${$.employee_name}

D4

${$.sex}

E4

${$.birthday}

F4

${$.degree}

G4

${$.salary}

H4

${$.email}

上面的表达式中,由于报表域_DataRepeator.datasetEmployee,它名称的含义是定义这一区域将根据datasetEmployee中的记录进行重复。同时由于该区域已被声明为与datasetEmployee进行绑定,因此其中的子对象都将以datasetEmployee作为默认的Dataset,${$.employee_name}表示datasetEmployee中当前记录的employee_name字段的值。

  1. 结果查看

重新发布应用后输入网址:

可以看到如下的excel报表:

学习建议

以上的范例只是excel数据导出的一个基本功能展示,excel数据导出还可以实现Master/Detail类型的数据报表以及图形报表功能,如下图:
主从式报表:

小计与合计:

图表:

详细内容请参考<<Dorado报表模版设计指南.doc.doc>>。