1 简介
Excel报表功能是目前很多系统中的基本特性之一,在Dorado中对Excel报表提供了很好支持。主要实现为基于Excel 模板的报表功能(Dorado Excel Report),将需要生成报表的数据按Excel模板的定义中的格式输出到Excel文档,形成最终Excel数据报表。
Dorado Excel Report可以将用户页面数据以模板中定义的格式输出到Excel文档中,特别适用于那些需要将页面或数据库数据导出到Excel文档或生成Excel报表。如在页面端填写的合同信息等按照配置好的合同模板格式生成到Excel文档备案、传递或打印。
在dorado中,相关的数据都是通过dataset实现的,数据查询与数据分批下载都需要通过dataset向数据层请求和获得,于是Dorado Excel Report的数据导出是基于dataset实现的,到目前为止,Dorado Excel Report使用方式主要分为: “数据导出模式”和“Excel报表模式”两种。
1.1 数据导出模式
数据导出模式是指导出某个正在运行的dorado界面中Dataset的数据。使用方法是利用Export2ExcelCommand控件。因此,在使用此种模式时,用户一定需要首先开启包含要导出数据的页面,然后才能得到最终需要的Excel报表。对于数据导出模式,dorado内部为所有的数据导出功能提供的默认的模版,位于classpath:com/bstek/dorado/report/excel/default-export-template.xls,可以通过dorado的setting.xml中的report.defaultExportTemplate来配置默认的导出模版,也可通过指定templateTable属性来指定导出模板。输出样式中可以利用DataTable的用户格式定制功能,例如动态改变列的顺序,动态改变列的标题,动态设定列是否可见等。
具体实现可以参看“dorado 5 组件详解”中“Export2ExcelCommand控件”的介绍一节。
1.2 Excel报表模式
“Excel报表模式”是具有独立的URL的报表,用户可以通过直接访问某个报表的URL在浏览器中得到该报表的展现。对于报表模式而言,报表模版是必须提供的,对某个报表的访问可以看作是对某个报表模版的访问。根据自定义Excel报表模板的方式导出数据,能设计比较灵活的报表样式,形成多种样式报表,如支持数据的分组、汇总等运算,还可以包含支持二维和三维的柱形图、饼图、面积图、折线图等常用的图表样式的报表。
2 配置
2.1 依赖环境
Dorado Excel Report需要依赖Jxl(JAVA EXCEL API),Jxl为是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容、创建新的Excel文件、更新已经存在的Excel文件。使用该 API非Windows操作系统也可以通过纯Java应用来处理Excel数据表。Dorado Excel Report需要依赖jxl-2.6.4及以上版本。
jxl、poi这一类的excel工具包在运行都会占用大量的内存,因此如果使用Excel报表功能生成大数据量的报表时容易导致JVM内存溢出。目前此问题没有有效的解决方案,因此不建议生成大数据量的报表(此处大数据量一般指3000条记录以上,此指标随报表数据和报表模版的复杂度的不同而不同)。
最新Jxl下载地址:
http://sourceforge.net/project/showfiles.php?group_id=79926
2.2 配置web.xml
对于使用数据导出模式是不需要配置web.xml。
使用Dorado Excel Report的报表模式是以Servlet方式实现,所以需要在web.xml中加入Dorado Excel Report的相关配置。
在web.xml中需要配置Dorado Excel Report使用的Servlet及参数,其中Servlet-Classes为“com.bstek.dorado.report.excel.ExcelReportServlet”,并且配置其中参数“templateBase”,用于指定报表模版的存放位置,即报表模版路径的前缀。例如:设定templateBase为classpath:sample。当用户访问http://localhost/myApp/report/template1.report时(contextPath为/myApp),报表引擎会使用classpath:sample/report/template1.xls来查找报表模版。对于报表模板的路径配置规则可以参考“附录 1”。
下面为一个完整的包含Dorado Excel Report的相关配置的web.xml。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<filter>
<filter-name>doradofilter</filter-name>
<filter-class>com.bstek.dorado.core.DoradoFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>doradofilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>doradoservlet</servlet-name>
<servlet-class>
com.bstek.dorado.core.DoradoServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Dorado Excel Report 配置开始 -->
<servlet>
<servlet-name>dorado-excel-report</servlet-name>
<servlet-class>
com.bstek.dorado.report.excel.ExcelReportServlet
</servlet-class>
<init-param>
<!-- templateBase参数用于指定报表模版的存放位置
即报表模版路径的前缀。
例如:设定templateBase为classpath:sample。
-->
<param-name>templateBase</param-name>
<!--
报表模板路径为Classpath
-->
<param-value>classpath:</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dorado-excel-report</servlet-name>
<url-pattern>*.report</url-pattern>
</servlet-mapping>
<!-- Dorado Excel Report 配置结束 -->
<servlet-mapping>
<servlet-name>doradoservlet</servlet-name>
<url-pattern>*.d</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>
http://www.bstek.com/dorado</taglib-uri>
<taglib-location>/WEB-INF/dorado.tld</taglib-location>
</taglib>
</web-app>
3 定义报表模板
新建Excel文档要存放在web.xml里关于Dorado Excel Report配置中的模板存放路径中。如设定templateBase为classpath:sample/report,则Excel模板存放在classpath:sample/report/中,报表引擎就会到classpath:sample/report/来查找报表模版。
在Dorado Excel Report的报表模式中,报表模板中有两个非常重要的配置,分别为:“模板属性参数”、 “报表域”、“报表EL表达式”。
模板属性参数主要为报表创建过程中定义一些基本信息,如数据来源的View以及Dataset等。
报表域主要为控制报表生成样式,报表数据汇总等提供控制。
报表EL表达式为向报表模板输出数据使用。报表EL表达式支持原ViewModel中的全部语法,同时又增加了用于支持报表模版的新语法。
3.1 模板属性参数
3.1.1 参数说明
使用报表模式时,需要在模板中配置一些模版的基本属性,以便在报表生成时使用。
目前支持的属性主要有:
? viewModelConfig
用于指定此报表文件由那个View使用。其中属性值为调用报表的ViewModel配置文件的名字。如:com.myCompany.myApp.Report1。
? viewModelClass
如果要引用的ViewModel没有配置文件,而是直接通过ViewModel实现类来构造的,那么也可以直接在此属性中定义ViewModel实现类的类名。
? defaultDataset
指定某个ViewModel中的Dataset为报表模版数据来源的默认的Dataset。此属性可以省略,主要用于简化后期模版定义的工作量。
? processorListener
其属性值为ExcelProcessorListener的实现类。如示例中心只读报表的ProcessorListener属性的定义:
ExcelProcessorListener的实现类会在在报表的创建过程中加入一些自定义控制。类似于Dataset的DatasetListener。其中包括两个方法,分别为:“afterProcesse”和“beforeProcesse”。分别会在报表创建前后调用。
具体介绍参看“ExcelProcessorListener”说明。
3.1.2 参数配置
在新建的Excel模板文件中新建工作区“TemplateProperties”。此工作区中第一列中定义属性名,在第二列中定义属性值。报表引擎会自动识别在TemplateProperties中定义个各个属性,同时TemplateProperties也不会出现在最终生成excel报表中。
以示例中心“只读报表”为例,其定义了“viewModelConfig”、“defaultDataset”、“processorListener”三个属性,如果“viewModelConfig”没有定义,则必须定义“viewModelClass”属性。
3.2 模板报表域
3.2.1 报表域创建
在报表模板中新建一个报表显示工作区,根据报表需求命名,如命名为“图表报表”,在显示工作区中选择多个或单个单元格,就可以创建为报表域。
? 选择单元格
选择一个或若干个单元格。
? 命名报表域
调用右键菜单的“命名单元格区域”,命名域。报表域可以在报表样式定义完成后在定义。
3.2.2 报表域说明
报表域是指Excel模版中一个或多个选中的单元格,并具有别名矩形区域,可以是一个单元格,也可是一组单元格。Excel报表使用一些带有特殊含义的别名来描述这些矩形区域的功能和行为。
Dorado Excel Report中域的别名的基本定名规则为:
_域类型
或
_域类型.绑定的Dataset的id
或
_域类型.绑定的Dataset的id.其他参数
目前支持的域类型包括:
1) _DataBand 数据域
数据域是一种为了该区域定义中El表达式定义默认的Dataset的区域。他是一个可以引用报表数据的区域,数据域往往并没有特定的实际作用,在数据域之外同样可以引用报表数据。
数据域的命名必须以“_DataBand”开始,其后可指定该域使用的Dataset,中间使用“.”分割。如,“_DataBand.datasetEmployee”。数据域的定义还有其他的形式如:
? _DataBand.dataset1
表示在该区域中使用dataset1作为默认Dataset。
? _DataBand.$
表示使用父报表域绑定的Dataset或TemplateProperties属性中定义的defaultDataset作为该区域的默认Dataset,不过这样定义没有任何实际意义。
数据域最常见的用途是为该区域定义默认的Dataset,这样在这个数据域中使用Dataset时无需指定名字,直接使用隐式变量”$”即可,如“${$.Sex}”,其中“$”表示当前数据域的默认Dataset。这样可以在一定程度上减轻模版定义的工作量。
如可以在报表中定义一个区域,类型为数据域,如定义数据域“_DataBand.datasetEmployee”。如图:
在上列报表数据模板中“${$.Sex}”中的红色“$”就是一种隐式变量,他所代表的为数据域定义的默认Dataset:“datasetEmployee”。这样在生成报表后将显示当前记录数据。
最终形成报表效果:
2) _DataRepeator 数据迭代域
迭代域是Dorado Excel Repor中最常用的域。它是使数据能够迭代显示的区域。数据迭代域会自动根据Dataset中的记录并根据报表模板中数据迭代域的格式向下复制自己格式,同时Dataset记录向下滚动,并把数据填充到报表迭代数据区。
迭代域的命名必须以“_DataRepeator”开始,其后可指定该域使用的Dataset,中间使用“.”分割。如,“_DataRepeator.datasetEmployee”。迭代域的定义还有其他的形式如:
? _ DataRepeator.dataset1
表示在该区域中使用dataset1作为默认Dataset。
? _ DataRepeator.$或 _ DataRepeator
表示使用父报表域绑定的Dataset或TemplateProperties属性中定义的defaultDataset作为该区域的默认Dataset,不过这样定义没有任何实际意义。
如在报表中定义一个区域,类型为迭代域,如定义迭代域“_DataRepeator.datasetEmployee”。如图:
在上列报表数据模板中“${$.Sex}”中的红色“$”就是一种隐式变量,他所代表的为迭代域中定义的Dataset:“datasetEmployee”。这样在生成报表后将显示Dataset中所以记录数据,并且会迭代显示。
最终形成报表效果:
3) _DataGroup 数据分组域
数据分组域用于对数据进行分组显示,在数据分组域中多数包含其他域,形成类似于一对多关系的数据显示。数据分组域实现原理是根据某个指定的分组字段,按照相邻数据相等的原则对数据进行分组。并且在进行分组时不会对记录进行重新排序,因此不相邻的两段相同数据将被认为是两个组。所以在使用分组域如果需要一定要对分组记录按分组信息进行排序。
分组域的命名必须以“_DataGroup”开始,其后可指定该域使用的Dataset以及用于分组的字段,如:
? _DataGroup.dataset1.deptId
表示定义了一个分组域“_DataGroup.dataset1.deptId”,并根据dataset1中的deptId字段对分组域中要显示的记录进行分组。
? _DataGroup.$.deptId
含义与上面_DataGroup.dataset1.deptId基本相同,只是其中“$”表示根据父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset中所指定的dataset为当前数据来源Dataset。
数据分组域之间是可以相互嵌套的,但最后(内)的一个数据分组域中必须包含一个数据迭代域。即每一个数据分组域中都应该包含一个数据分组域或一个数据迭代域。
如在报表中定义一个区域,类型为分组域,如定义分组域“_DataGroup.datasetDept.dept_id”,通过Dept_id分组,当Dataset中相连的记录相同的就会认为是两个分组。如图
运行结果:
4) _DataBlock 数据块
数据块会自动根据Dataset中的记录在数据块容器(_DataBlockContainer)所指定的空间内按照流式布局复制自己,且一旦数据块容器所指定的空间被排满,则停滞迭代。数据块的定义方法与_DataRepeator类似。例如:_DataBlock.dataset1。
5) _DataBlockContainer 数据块容器
数据容器块是与数据块配合使用的域,数据块容器在定义时不支持绑定。
数据块容器中必须且只能包含数据块(_DataBlock),用于为数据块的迭代复制划定空间。及包含的单元格数量。
如,在报表中定义一个区域,类型为数据块容器域,如定义数据块容器域“_DataBlockContainer.1”,其中包含数据块“_DataBlock.datasetEmployee”,用于显示用户信息。如图
在报表生成过程中,数据块就会在数据容器 “_DataBlockContainer.1”中按照流式布局复制自己,直到填满容器块中的单元格。形成下列报表。
注意1:
默写情况下,我们可能对需要在页面定义两个别名完全相同的报表域,例如定义两个_DataBlockContainer或两个_DataRepeator.dataset1。但是,事实上报表域的别名是不允许重复的。因此,替代的做法是在域别名的后面再追加一个序号。
例如:
DataBlockContainer和DataBlockContainer.1
或
DataBlockContainer.1和DataBlockContainer.2
或
_DataRepeator.dataset1.1或_DataRepeator.dataset1.2
注意2:
报表域之间可以相互嵌套,但绝不可以交叉或完全重合。
3.3 EL表达式
报表模版中的EL表达式用于定义报表模板中报表显示数据样式以及为报表引擎提供数据输出到报表中。与原ViewModel中的使用的EL表达式在语法上全部相同,同时又增加了用于支持报表模版的新语法。
除与原ViewModel中的使用的EL表达式在语法上全部相同外,还增加了大量报表支持报表的全新EL表达式。主要有:
? 引用Dataset的表达式
通过Dataset表达式输出记录数据,使用Dataset表达式不仅可以获得数据,也可以通过表达式获得Dataset的记录或字段、参数等。使用方式是为使用某个dataset的id作为隐式变量可以访问该dataset。如:${datasetEmplpoyee.dept_id}。或通过$隐式变量可以直接引用默认Dataset。其中默认的Dataset是当前表达式所处的域的指定的Dataset,如没有指定则是指父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset。
如在分块报表的模板中“${$.dept_name}”中就是使用当前表达式所处的域的指定的Dataset,当前域为“_DataBlock.datasetDept”,则$表示使用“datasetDept”这个Dataset。
有多种方式使用Dataset的表达式,例如:
? ${$.getString(“field1”)} 表示引用默认Dataset中field1字段的数据。
? ${$.pageCount} 表示引用默认Dataset的总页数。
? ${dataset1.getField(“field1”).getFormat()} 表示引用dataset1中field1字段的format属性。
? ${dataset1.parameters().getString(“param1”)} 表示引用dataset1中param1参数的值。
? 引用数据的表达式简式
? ${$.field1}表示引用默认Dataset中field1字段的数据。默认Dataset是指父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset。
? ${dataset1.field1}表示引用dataset1中field1字段的数据。
? 引用字段标题的表达式简式
在报表中有时需要通过字段的Label作为报表表头,就可以通过字段标题的表达式简式实现。如分组报表1中的表头:
使用方式主要有:
? ${$.field1.label}表示引用dataset1中field1字段的标题。默认Dataset是指父报表域绑定的Dataset或TemplateProperties中定义的defaultDataset。
? ${dataset1.field1.label}表示引用dataset1中field1字段的标题。
? 统计数据表达式
对报表数据进行统计是报表的基本功能,在Dorado Excel Report中通过使用统计类表达式实现。主要有两类统计表达式:记录数统计和数据值统计。
? 记录数统计表达式
记录数统计表达式可以有两种使用方式:无参数调用“${dataset.getCount()}”、带有参数调用${dataset.getCount(参数1,参数2)}或${dataset.getCount(参数1)}。
${dataset.getCount()} 表示用于返回dataset中已处理过的记录数。如果将此表达式放置在数据迭代域(_DataRepeator)或数据块(_DataBlock)之后,其数值将是dataset的总记录数;如果将此表达式放置在数据迭代域(_DataRepeator)或数据块(_DataBlock)中,其产生的效果类似与从1开始的顺序号。
带有参数调用记录数统计表达式主要是用在数据分组域(_DataGroup)中对分组记录的记录数统计上,用于显示每一个分组中的记录数,并不是统计所有记录。此时必须在每次使用${dataset.getCount()}之后将其中的数据清零才能得到正确的结果。因此,此表达式可改为${dataset1.getCount(“xxx”, true)},其中的xxx可以是任意的字符串,其作用是根据此参数对记录进行统计来区分不同的累加器,此参数可以省略。参数true表示是否要在本次使用后重置内部累加器的值。
例如有一张人员列表,我们需要同时统计出每一个部门中的员工数、每一个分公司中的员工数以及整个集团的员工数。此时,我们事实上需要三个累加器。可以分别定义${dataset1.getCount(“dept”, true)}、${dataset1.getCount(“branch”, true)}、${dataset1.getCount()}分别处理每一个部门中的员工数、每一个分公司中的员工数和整个集团的员工数。由此可见”dept”、 “branch”这样的参数可以帮助我们区分不同的累加器,这些字符串本省并没有任何意义,只要保证他们不相同就可以了。
报表设计如下:
? 统计字段值的表达式
统计类表达式是利用El表达式对数据进行求和、求平均值等。求和表达式可以使用getSum()平均值为getAverage()。
${dataset1.salary.getSum()} 用于统计salary字段的合计值。如果需要进行重置,同样可以使用${dataset1.salary.getSum(“xxx”, true)}这样的语法。
${dataset1.salary.getAverage()}用于统计salary字段的平均值。
统计类表达式报表设计:
3.4 数据列别名
在Dorado Excel Report中如果希望使用Excel固有的功能来处理报表中某个列的数值或形成图表类报表,就需要为使用数据列别名。
如将包含${$.salary}的单元格命名为salary,然后就可以利用Excel的公式=SUM(salary)来获得salary的合计值了,我们甚至可以通过此种方法将报表数据与Excel中的图标关联起来。
如图表类报表的设计中使用的别名来生成图表报表:
在插入的图表定义中也使用别名进行数据传递:
3.5 ExcelProcessorListener
ExcelProcessorListener用于控制报表的创建。可以在报表创建过程中加入一些控制。应用在报表属性设定中,要使用ExcelProcessorListen则需要实现ExcelProcessorListener接口中的两个方法“afterProcess”和“beforeProcess”;
1) beforeProcess方法
在报表文件生成前调用。
4个参数:Template 、WritableWorkbook、WritableSheet 、Context。
Template 报表模板对象,可以通过此获得报表模板的一些属性。
WritableWorkbook Excel工作薄对象。
WritableSheet 当前操作的Sheet表对象。
Context 上下文对象,可以获得上下文属性参数等。
2) afterProcess方法
在报表文件生成前调用。
4个参数:Template 、WritableWorkbook、WritableSheet 、Context。
Template 报表模板对象,可以通过此获得报表模板的一些属性。
WritableWorkbook Excel工作薄对象。
WritableSheet 当前操作的Sheet表对象。
Context 上下文对象,可以获得上下文属性参数等。
要使用ExcelProcessorListen需要在报表模板并属性定义中加入“processorListener”属性。此属性值为实现了ExcelProcessorListener类接口的类。
如示例中心的只读报表中模板readonly-report.xls的processorListener属性定义:
其中ReadOnlyExcelProcessorListener的实现代码:
public class ReadOnlyExcelProcessorListener implements ExcelProcessorListener {
public void afterProcess(Template template, WritableWorkbook workbook,
WritableSheet sheet, Context context) throws Exception {
DoradoContext doradoContext = DoradoContext.getContext();
String user = doradoContext.getParameter("user");
if ("user1".equals(user)) {
//设定报表为只读,并设定编辑密码为”123”
SheetSettings settings = sheet.getSettings();
settings.setPassword("123");
settings.setProtected(true);
}
}
public void beforeProcess(Template template, WritableWorkbook workbook, WritableSheet sheet, Context context) throws Exception {
// todo
}
}
4 数据导出模式
数据导出模式是指导出某个正在运行的dorado界面中Dataset的数据。使用方法是利用Export2ExcelCommand控件。
基本的使用方法可以参看“dorado 5 组件详解”中“Export2ExcelCommand控件”的介绍一节。
4.1 自定义导出模板
在Dorado中以为导出模式提供了默认的导出模板,但有时无法满足用户需求,这是就需要使用自定义导出模板,自定义导出类报表模板不需要定义模板属性参数。可以使用报表的EL表达式及数据域。为了简化导出模版的定义,在数据导出模式的报表模版中特别支持${autoHeader}、${autoData}、${autoFooter}表达式。
如默认的导出报表模板:
另外也可以设计类似报表模式的导出模板,但是只能由于特定的Dataset,如实例中心的自定义导出摸板3的设计,定义分组域后在其中包含数据迭代域。
另外,Export2ExcelCommand的parameters在报表模版中可以通过${Request.param}引用。
4.2 使用自定义导出模板
在Export2ExcelCommand中通过动态设定属性“TemplateFile”来设定报表模板。
5 报表模式
报表模式Dorado中使用最为频繁的一种。可以通过报表模式的自定义报表模板实现样式繁多的报表,根据自定义Excel报表模板的方式导出数据,能设计比较灵活的报表样式,形成多种样式报表,如支持数据的分组、汇总等运算,还可以包含支持二维和三维的柱形图、饼图、面积图、折线图等常用的图表样式的报表。
“Excel报表模式”是具有独立的URL的报表,用户可以通过直接访问某个报表的URL在浏览器中得到该报表的展现。对于报表模式而言,报表模版是必须提供的,对某个报表的访问可以看作是对某个报表模版的访问。
访问时直接访问报表名称即可。其中报表的文件名应与web.xml中配置相同,如在web.xml中配置为:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
…….
<!-- Dorado Excel Report 配置开始 -->
<servlet>
<servlet-name>dorado-excel-report</servlet-name>
<servlet-class>
com.bstek.dorado.report.excel.ExcelReportServlet
</servlet-class>
<init-param>
<!-- templateBase参数用于指定报表模版的存放位置
即报表模版路径的前缀。
例如:设定templateBase为classpath:sample。
-->
<param-name>templateBase</param-name>
<!--
报表模板路径为Classpath
-->
<param-value>classpath:</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dorado-excel-report</servlet-name>
<url-pattern>*.report</url-pattern>
</servlet-mapping>
<!-- Dorado Excel Report 配置结束 -->
……..
</web-app>
如果需要访问report/template 报表(模板文件名为:template.xls)则访问路径为:http://localhost/myApp/report/template1.report时(contextPath为/myApp),报表引擎会使用classpath:report/template1.xls来查找报表模版。
对于报表模式开发,可以参看Dorado中随带的Sample的事例,下面将以Sample的事例中统计类、分组类报表、包含图表类报表为例说明。
5.1 分组类报表
分组报表用于实现对Dataset中的记录根据分组信息进行分组显示,主要通过基本的数据分组域“_DataGroup”和数据迭代域“_DataRepeator”及EL表达式实现。
实现效果为:
示例中心报表路径:
src\sample\report\excel\data-group1.xls
5.1.1 创建报表模板并属性定义
创建报表模板文件。新建工作表并命名为“TemplateProperties”。定义属性viewModelConfig、viewModelClass、defaultDataset。
只需定义viewModelConfig属性,其他属性默认。
5.1.2 定义数据域及数据显示样式
新建工作表并命名为“分组报表”,作为报表数据显示空间。在“sample.report.excel.Employee”视图中报表数据来源于“datasetEmployee”。
5.1.2.1 定义数据域
在报表空间中,根据报表设计要求,定义矩形区域为分组域用于数据分组,在分组域中对于将要显示的数据以通过迭代域实现,所以在分组域中包含数据迭代域。
数据分组域用于对迭代的记录进行分组,并且根据每一个分组自动的向下复制自己。数据分组域根据某个指定的字段,按照相邻数据相等的原则对数据进行分组。
数据域并不是一定要在开始设计报表时首先设定,在熟练后可以在排列好报表样式后在定义。
分组域以“datasetEmployee .dept_id”作为分组条件。所以定义的分组域命名为“_DataGroup.datasetEmployee.dept_id”。其中“_DataGroup”为定义的域类型,“.datasetEmployee.dept_id”表示以数据分组域根据“.dept_id”字段对记录进行分组。
数据迭代域的数据来源域“datasetEmployee”,所以根据约定迭代域命名为“_DataRepeator.datasetEmployee”,其中“_DataRepeator”为定义的域类型,“datasetEmployee”表示当前域数据的来源Dataset。
5.1.2.2 设定数据显示样式
分组域为每组数据显示的最小单元。根据报表要求,要显示当前组的分组信息以及当前组中所包含的所以数据记录,对于所有数据记录的显示还要实现类似表格的。则在分组域中输出分组信息。
? 分组格式设定
本例要求为“dept_name”,在报表分组域中通过EL表达式实现。“${$.dept_name}”中“$”表示使用“_DataGroup.datasetEmployee.dept_id 域”指定的Dataset作为数据输出来源。
? 表头标题设定
实现数据表头标题功能需要使用“引用字段标题的表达式简式”,如“${$.sex.label}”等。其中的“$”表示父域(_DataGroup.datasetEmployee.dept_id)中指定的Dataset。
? 数据记录显示设定
数据的显示为每个分组中最终通过分组要显示的数据,数据的条数为不固定,所以需要将其放入数据迭代域中。在数据迭代域中通过EL表达式排列出需要显示的格式。其中数据迭代域中的“$”代表当前域所指定的Dataset。
5.1.3 完整报表模板
对文档进行细微调整后形成最终模板。包含迭代域以及统计类EL表达式的报表。
5.2 统计类报表
在传统的报表中多有“小计”、“合计”等一类的统计信息,或包含对记录数以及数据运算的信息。Dorado Excel Report中的统计类报表能够很好的实现此类功能,主要通过使用数据迭代域“_DataRepeator”以及“统计记录数的表达式”如,getCount()、getSum()等实现。
报表实现效果:
示例中心报表路径:
src\sample\report\excel\ organization2.xls
5.2.1 创建报表模板并属性定义
创建报表模板文件。新建工作表并命名为“TemplateProperties”。定义属性viewModelConfig、viewModelClass、defaultDataset。
只需定义viewModelConfig属性,其他属性默认。
5.2.2 定义数据域及数据显示样式
新建工作表并命名为“小计合计类报表”,作为报表数据显示空间。在“sample.report.excel.Organization”视图中报表数据来源于三个Dataset,分别为“datasetBranch”、“datasetDept”、“datasetEmployee”,在当前报表中将根据公司信息获得部门以及部门下人员信息,所以并通过“branch_id”,“dept_id”字段对三个Dataset进行关联。
5.2.2.1 定义数据域
此报表我们需要同时统计出每一个部门中的员工数、每一个分公司中的员工数以及整个集团的员工数。在报表空间中,根据报表设计要求,我们需要使用三个数据域来显示数据,分别显示“公公”信息、“部门”信息、“人员”信息。由于三者直接存在着关联关系,公司对应多个部门,而部门有对应多个员工,所以三者存在着嵌套关联关系,。
分别为以“datasetBranch”为条件的数据迭代域,用来输出公司信息。以“datasetDept”为条件的数据迭代域,用来输出当前公司下部门的信息,以及以“datasetEmployee”为条件的数据迭代域,用来输出当前部门下的员工信息数据。由于三个Dataset存在着关联关系,并且在报表显示中也需要显示关联信息,所以三个数据迭代域必然存在着嵌套关系。不难看出嵌套关系为:“datasetBranch迭代域”中包含“datasetDept迭代域”,并且在“datasetDept迭代域”中包含“datasetEmployee迭代域”。
定义数据域的方法与分组类报表相同,都是定义矩形区域为分组域用于数据迭代,根据报表要求,可以从“datasetEmployee迭代域”开始定义,因为其为最小数据域。
划分后数据域后,报表空间的样式为下图,蓝色选择区域为:“datasetEmployee迭代域”,黄色区域为“datasetDept迭代域”,最外面的黑色区域为:“datasetBranch迭代域”,三个迭代域一一嵌套,这样就可以在数据显示时根据公司、部门迭代人员信息。其中两个红色区域是为了实现跨行合并而增加的行,在下面说明。
在数据域定义中由于存在着嵌套,例如在“datasetDept迭代域”中包含了“datasetEmployee迭代域”,在最终数据显示是,希望在“datasetDept迭代域”中的数据能够实现类似的表格跨行合并功能,如图:
这里需要使用一个小技巧,来实现表格行的合并,不然最终形成的效果于想象的相差甚远,如图:
部门名称并没按想象的进行合并行。这是由于在Excl中定义的“datasetDept迭代域”中的每条记录并不了解其相对“datasetEmployee迭代域”的记录数,所以出现了这样的效果。为了避免这样的问题出现,可以通过在定义“datasetDept迭代域”中对应记录的单元格为合并单元格。在“datasetEmployee迭代域”下插入一空行,并指定“${$.dept_name}”单元格域下行单元格合并,同时把新增的行高设置为“0”。 同样,“datasetBranch迭代域”与“datasetDept迭代域”之间也要使用同样设置。
可以参考示例中心的“小计、合计报表模板”
5.2.2.2 设定数据显示样式
El表达式的使用与分组报表模板相同。
在模板使用了大量求和表达式,如:getSum()、getCount()等。通过参数来区分区分不同的累加器。每个迭代域中的累加器使用后都需要值初值,以便不会影响其下的记录统计。
5.2.3 完整报表模板
对文档进行细微调整后形成最终模板。包含迭代域以及显示信息的EL表达式。在最终报表中将看不到为了实现跨行合并时加入的行,因为在最终报表中后加入的行的行高已经设置为“0”;
注意1:
在出现迭代域嵌套的情况时,如果需要实现实现跨行合并时,一定要加入一个空行,并设定高度为“0”。
5.3 含图表类报表
图表类报表是基于Excel固有的图表功能实现的报表。所以可以实现多种图表报表。如饼状图、柱状图、曲线图等。为了实现图表报表,主要通过使用单元格的别名方式像图表传递数据。
实现效果为:
示例中心报表路径:
src\sample\report\excel\ chart.xls
5.3.1 创建报表模板并属性定义
创建报表模板文件。新建工作表并命名为“TemplateProperties”。定义属性viewModelConfig、viewModelClass、defaultDataset。
定义viewModelConfig属性和DefaultDataset属性,其他属性默认。其中Defaultdataset定义的目的只是为在报表中方便数据的使用。
5.3.2 定义数据域及数据显示样式
新建工作表并命名为“图表报表”,作为报表数据显示空间。在“sample.report.excel.Employee”视图中报表数据来源于“datasetEmployee”。
5.3.2.1 定义数据域
根据报表设计要求,定义矩形区域为数据迭代域,用于显示基本数据人员的信息。由于没有使用分组域所以无需定义分组域信息,使用“_DataRepeator”定义迭代域,名称为“_DataRepeator”,由于已经定义了“defaultDataset”属性,所以等于的迭代域名称可以不包含“dataset”,迭代域中数据将默认使用“defaultDataset”属性定义中的Dataset 。
5.3.2.2 设定数据显示样式
根据报表要求,需要设定标题信息,及数据样式。
? 表头标题设定
实现数据表头标题功能需要使用“引用字段标题的表达式简式”,如“${$.sex.label}”等。其中的“$”表示使用“defaultDataset”属性中指定的Dataset。
? 数据记录显示设定
在数据迭代域中通过EL表达式排列出需要显示的格式及数据。其中数据迭代域中的“$” 表示使用“defaultDataset”属性中指定的Dataset。
? 别名设定
在数据格式定义完成后,分别给单元格“${$.employee_name}”和“${$.salary }”定义别名。目的是为了使用Excel固有的功能,比如实现使用Excel公式或使用图表显示等。
为单元格“${$.employee_name}”设定别名为:”employee_name”。
为单元格“${$.salary}”设定别名为:”salary”。
? 使用Excel公式
为了能够取得人员工资在总和,在这里使用Excel的公式功能,主要用到“sum”求和公式,当然此处也可使用Dorado Excel Report 提供的求和EL表达式。
设定合计单元格插入Excel特有功能,插入公式“SUM()”,公式内容为“=SUM(salary)”,其中“salary”即为“${$.salary}”单元格的别名。
5.3.3 设定图表显示
在报表模板中加入需要的图表,如使用柱状图,则在文档中通过Excel的插入功能加入柱状图。
插入图表后,需要将数据信息传入图表,在图表上点击右键,点击“选择数据”。
出现“选择数据源”项。
此处有一点需要注意在配置“系列值”项及“轴标签”等图表生成列中一定要使用刚才定义列别名。不然无法将数据传递进入图表。
5.3.4 完整报表模板
对文档进行细微调整后形成最终模板。
注意1:
在报表中如果希望使用Excel的固有功能,如“公式”、“图表”等,一定要为传递数据的单元格定义别名,并通过别名使用。
6 附录1 - 报表模版路径的描述规则
目前,报表模版路径的装载方式主要有两种:
? 以资源方式装载
此时,报表模版一般会放置到classes中或打包在jar包中,报表引擎以java的资源方式装载模版。例如,将报表模版文件template1.xls放在classes/com/myCompany/myApp/report/中,那么该报表模版的路径将是classpath: com/myCompany/myApp/report/template1.xls。
? 以文件方式装载`
此时,报表模版可以放置在任何位置,报表引擎以文件方式装载模版。例如,将报表模版文件template1.xls放在d:/temp/report中,那么该报表模版的路径将是file:d:/report/template1.xls或file://d:/report/template1.xls。