《ireport子报表(subreport)》由会员分享,可在线阅读,更多相关《ireport子报表(subreport)(11页珍藏版)》请在金锄头文库上搜索。
1、iReport子报表(SubReport) CubeBI.com 立方开源商业智能 SubReport是ireport提供的高级功能,通过SubReport我们可以创建复杂的报表。通过SubReport我们可以创建一个包含若干个子报表的报表。创建一个包含子报表的报表我们需要三个对象:一个jasper文件,一个包含参数map(当然可以为空)和一个DataSource(数据源,或者是一个JDBC的Connection)。在本章中我们将解释如何通过这三个对象创建一个SubReport并实现在子报表中数据过滤显示的目的。9.1 创建一个子报表(create a SubReport)一个SubRepor
2、t是一个真正的包含它自己xml文件并且是一个已经编译好的jasper文件。创建一个SubReport就是创建一个普通的报表文件,创建过程中唯一需要注意的是设置SubReport的宽度、高度及一些不需要显示的band,一般情况下对于不显示的band我们把它们的高度都设置为0。在设置子报表的宽度时我们应该考虑到它在父报表中显示时的效果,然后针对这一特性有针对性的去设置。在父报表中我们要添加一个子报表可以通过iReport中的SubReport工具 来实现。子报表的形状和一个距形类似,我们可以调整SubReport的尺寸和位置以控制子报表的显示。将一个子报表链接到父报表中需要做三件事情:获得SubR
3、eport所对应的jasper报表对象、如何为它提供数据及如何为子报表的parameters设置具体的值。所有这些信息的定义我们可以通过SubReport properties窗口来实现。图9.1图9.29.2 传递参数(Passage of the parameters)当我们在应用程序里通过fillReport方法来生成一个报表的时候,我们会提供一个包含参数值的Map一起传递到报表中,包含参数的Map对象是由报表引擎直接管理的。在子报表属性窗口的里的“SubReport”标签里的“Parameters Map Expression”属性就是提供给我们的最简单的方法来为子报表设置parame
4、ters的值,它允许我们定义一个最终可以返回java.util.Map对象的表达式,使用这种方法我们可以把从外部应用程序传到父报表里的parameter对象,当然这个parameter的实际值是一个java.util.Map对象传递给子报表使用(比如$PTestMap),这里我们也可以使用内建的报表parameters:$PREPORT_PARAMETES_MAP把子报表中的java.util.Map对象传递到父报表中供使用。如果该属性我们空着不填那么一个不包含任何值的空的java.util.Map将会被传到子报表中。这种机制的局限性是parameters里所对应的java.util.Map值
5、是死的、不会变的。为了克服这种局限性jasperreport允许我们定义parameter键值对的时候每个对象的值通过一个表达式来创建,如在图9.2中的“SubReport Parameter”表中通过添加个参数java.util.Map来填充子报表。图9.3deptId是子报表中一个parameter的名称,如果设置值时也要与子报表中deptId的数据类型保持一致。指定数据源为子报表指定数据源就是告诉jasperreport引擎如何获到数据来填充SubReport。我们可以指定两种类型的数据源:JDBC Connection和DataSource。使用JDBC来填充报表是很简单的,在Conn
6、ection Expression里定义一个已经连接到数据库的java.sql.Connection对象。要把一个已经处于打开状态下的连接传到SubReport中我们只需使用一个预定义的包含一个基于从应用程序里调用fillReport方法时的传入的连接REPORT_CONNECTION参数如果使用一个DataSource就稍微复杂一点,事实上它是一个简单的记录的集合,记录集合的概念和JDBC Connection不同,既然如此我们可以通过一个parameter来传递一个DataSource来填充SubReport,此时采用这种机制内建的parameter REPORT_CONNECTION就不
7、再起作用了。一个DataSource是一个普通的“消费品”对象仅仅可用来填充一次报表。所以一个作parameter传递的DataSource可以满足一个SubReport的需要。因此parameter的方式不能满足当父报表的每一行记录都有一些子报表的数据与之对应(除非主报表中只有一条记录)。当我们解释DataSource时我们可以看到这个问题可以通过自定义DataSource方式解决。指定SubReport创建一个SubReport我们需要指定一个扩展名为.jasper文件,我们需要在SubReport属性窗口中设置SubReport Expression属性。表达式返回的类型必须与我们在下拉
8、框里选择的类似保持一致,类型列表如下:类型名称含义net.sf.jasperreports.engine.JasperReport在一个JasperReport对象里预加载一个jasper文件Java.io.InputStream一个jasper文件的流J.URL一个用来定义jasper文件的URLJava.io.File一个jasper文件的File对象Java.lang.StringJasper文件的文件名如果表达式是一个String类型,那么引擎将通过JRLoad来加载指定位置的jasper文件。9.3 子报表示例(SubReport sample)在这个例子中我们将采用示例数据库来创建
9、一个简单的包含子报表的报表。我们要从两张表里取数据:dept(部门表)、employee(员工表),要达到的效果是根据部门表的部门ID取出该部门下的所有员工。类似的效果的报表我们在groups一章中使用group也实现了一次,这里我们将用SubReport来实现相同的效果。新建一个空报表,新建一个名为deptId的parameter对象,如下图:图9.4在这里我们在Default Value Expression里赋予了一个空的字符串,为什么要这样做呢,因为接下来我们要使用该parameter来作为SQL的查询条件的输入值,所以我们要对这个参数赋予一个初始化的值。点击 打开SQL查询引擎窗口,
10、输入下面的查询语句:Select * from employee where dept_id=$PdeptId在这里,我们在查询员工信息的时候加了一个部门的条件,如下图:图9.5此时如果我们把相关的field拖到detail band里,然后点击 我们发现没有任何记录,原因是因为我们并没有为deptId赋值。保存报表文件,我们命名为emp.jrxml,我们把这个报表文件作为下面将要引用的子报表文件。因为它将作为子报表被引用,所以我们需要调整该报表的不用显示的band的高度及detail band的高度,如下图:图9.10在detail band里我们放置了三个字段:employee_name(
11、员工姓名)、sex(性别)、birthday(出生日期)。接下来我们需要建立一个父报表,关闭emp.jrxml文件,新建一个空的报表文件,命名为dept.jrxml。点击主工具栏里 打开SQL查询窗口,输入下面的语句:Select * from dept如下图:图9.11把dept_name这个field拖动到报表的detail band里,同时在detail band里添加一个了报表,在弹出的子报表向导中我们选择“Cancel”按钮,这里我们不采用向导来创建SubReport。如下图图9.12双击子报表图标打开子报表属性设置窗口,在弹出的窗口中我们选择“SubReport”标签,在“Conn
12、ection/DataSource Expression”属性里我们选择“Use Connection Expression”并且指定内建的parameter:REPORT_CONNECTION作为表达式用来存储JDBC连接,如下图:图9.13切换到“Subreport(other)”标签窗口,指定如何找到子报表文件“emp.jasper”以及如何创建和修改在子报表与父报表之间的参数传递。使用绝对路径在iReport里我们不用去考虑子报表文件是否可以被找到的问题,因为子报表存放的目录已经被自动的加到iReport的classpath里了。这里我们指定的值是“$PSUBREPORT_DIR +j
13、ava.io.File.separator+emp.jasper”图9.14为了在子报表里可以显示员工的信息我们需要为子报表的deptId这个parameter赋值,这里我们通过父报表传过去,在“Subreport parameters”窗口中,我们添加了一个用于为子报表的deptId赋值的parameter,该值到于父报表中的$FDEPT_ID这个field。编译子报表和父报表。点击主工具栏中的 按钮,查看生成的后父报表效果。图9.15在这里我们看到子报表里的有一些字段显示的有问题(如sex性别这块显示的是true和false,还是日期不是我们要的日期格式),需要我们进一步对显示的字段信息进
14、行格式化操作。打开emp.jrxml文件,选中detail band里的sex field,右键选择properties,在弹出的窗口作如下修改:图9.16在Text Field Expression里我们输入($FSEX.booleanValue()?男:女)的意思是把原来显示的true和false翻译成男和女。这里$FSEX是java.lang.Boolean类型,所以需要先把它转化成java.lang.Boolean所对应的简单类型,然后如果值为true则为男,否则为女。对于birthday(出生日期)我们同样需要对其做格式化操作,如下图:图9.17关闭emp.jrxml(关闭之前别忘记
15、对其进行编译)。打开父报表dept.jrxml文件,编译查看报表效果:图表9.18Return Parameters有时候我们需要从子报表里返回一些值到子报里,比如子报里有多少条记录等。Jasperreport1.0.0提供的一个新的特性就是允许用户从子报表中返回值到父报表中,如下图,在“Subreport (other)”标签下的“Subreport return values”标签里设置我们需要在父报表里显示子报表里的参数值。图19.19SubReport Wizard从前面的操作中我们可以看出,当我们插入一个SubReport时会自动弹出向导窗口,通过这个向导窗口我们可以快速创建一个SubReport对象,创建过程非常简单,我们这里就不再介绍。