时间:2021-9-15 作者:qvyue
地址:http://www.lxiaoyu.com/p/277079
报表中的参数(Parameters )是应用程序与报表引擎之间沟通的桥梁,它可以用于以下用途:
传递 SQL 查询中的参数值,比如 SQL 语句中的 where 条件。
提供数据源所无法提供的值,比如自定义表头、生成该报表的账号、应用所指定的图片路径等等。
参数由一个名称和一个 Java 实现类(Class)组成。比如 java.sql.Connection 类型的参数,一般用于子报表(subreport);而 java.lang.Boolean 类型的参数,用于是否展示报表的某一部分。
参数可以设定一个默认值,这样如果应用没有传递该参数值,JasperReports 也能正确解析。
Parameters 下的那些灰色参数,表示是系统级的参数,不能编辑或者删除它。
右键点击 Parameters ,就可以创建参数:
右键点击某个具体参数,就可以选择删除它。
点击某个具体参数,就可以在 Properties 面板中,对其进行查看或设置:
说说 Jaspersoft Studio 中的参数以及与应用之间的交互
有以下这些可设置项:
设置项 | 参数名 |
---|---|
Name | 参数名。 |
Class | 参数实现类。 |
Default Value Expression | 参数默认值,它可以是一个表达式。 |
Description | 参数说明。JasperReports 没有直接使用该值,但为了便于未来维护,建议还是要填写下。 |
Is for Prompting | 如果勾选该项,当在 Jaspersoft Studio 中点击 Preview 预览报表时,就会弹出参数输入框,供预览者依据实际情况填写报表所需的参数值。 |
在 Properties 面板的 Advanced 选项卡中,可以按照键值对的方式,对其进行设置:
Jaspersoft Studio 定义了一些内置参数,具体说明如下:
内置参数 | 说明 |
---|---|
REPORT_PARAMETERS_MAP | 使用者调用 API 中的 fillReport() 方法所传入的 Map 型键值对参数。 |
REPORT_CONNECTION | 报表中的 JDBC connection,用于执行 SQL 语句。 |
REPORT_MAX_COUNT | 报表所能填充的最大记录数。如果未指定,则没有限制。 |
REPORT_DATA_SOURCE | 如果没有使用 JDBC connection(比如非数据库的数据源 CSV 等),将会使用这个参数。 |
REPORT_SCRIPTLET | 报表创建时的脚本实例,默认使用 net.sf.jasperreports.engine.JRDefaultScriptlet。 |
REPORT_LOCALE | locale 区域设置,一般用于国际化场景。默认为系统值。 |
REPORT_TIME_ZONE | 所在时区,默认为系统值。 |
REPORT_FORMAT_FACTORY | 默认实现是 net.sf.jasperreports.engine.util.FormatFactory。可以参考该工厂类,实现自定义工厂。 |
REPORT_CLASS_LOADER | 可用于设置报表填充时的 class loader。 |
REPORT_URL_HANDLER_FACTORY | 可用于指定创建 URL handlers 实现工厂。 |
REPORT_FILE_RESOLVER | 默认实现是 net.sf.jasperreports.engine.util.FileResolver,用于解析报表中的资源路径,也可以自定义。 |
REPORT_VIRTUALIZER | 定义报表填充器的实现类,默认为 JRVirtualizer 接口的实现类。 |
IS_IGNORE_PAGINATION | Boolean 类型,分页开关。默认情况下,除了导出 excel 与 HTML 之外,其它情况不分页。 |
一般情况下,JasperReports 会把传入的参数放入 sql statement 中,然后再执行查询,这样可以避免 SQL 注入问题。当然这也会使得参数不够灵活,无法把 SQL 片段作为参数传入语句。
参数可以定义在 where 条件中,用于过滤数据,语法为 $P{参数名}
,比如:
... and T3.STAFF_NO = $P{staff_no}
这条语句将会以 prepared statement 形式加以执行:
... and T3.STAFF_NO = ?
在 Jaspersoft Studio 的 Input Parameters 中,输入 staff_no 参数(记得先定义好这个参数)值.
参数也可以传入 SQL 片段,用于拼接 SQL 语句,语法为 $P!{参数名}
,比如:
and $P!{conditions}
在 Jaspersoft Studio 的 Input Parameters 中,输入 conditions 参数值:T3.STAFF_NO = 1
,输出结果与上例相同。
利用该语法,甚至可以把整个 SQL 语句作为参数传入报表引擎。形如 $P!{自定义SQL语句}
一个 query 可以包含任意个入参,当遇到语法 $P!{xxx}
时,就会被替换为所传入的实际值。
注意: 必须为参数设置默认值,让报表更健壮。
$P{parametername}
格式的参数,无法正确处理 Null 值,我们可以使用 $X{EQUAL,fieldname,parametername}
来处理 Null 值。
比较这两种写法的区别:
$P{param}
模式的语句为 select * from client where address = $P{address_param}
$X{EQUAL, column_name, param_name}
模式的语句为 select * from client where $X{EQUAL, address , address_param}
如果 address_param 参数值不为 Null,那么这两种写法,都会被解析为 select * from client where address = '北京'
。
如果 address_param 参数值为 Null,那么 $P{}
模式会被解析为 select * from client where address = null
,而 $X{}
模式会被解析为 select * from client where address is null
。
很明显,$X{}
的解析模式才是正确的 SQL 处理 null 的模式。
JasperReports 使用特殊语法来应对 where 中的 IN 与 NOT IN 形式。
IN 一般用于一系列的值,比如:
select * from client where address in ('北京','上海','广州')
address 的参数值一般是一个列表(最好是 java.util.Collection)或者一个数组,之前的 SQL 可以用以下语法来表示:
select * from client where $X{IN, address,address_values}
address_values 是包含一系列地址数据的参数,$X{} 支持三个入参:
如果传入的参数是 null 或者是一个空列表,$X{} 会解析为 0 = 0。
可以使用类型为 DateRange 的参数,来作为时间条件,过滤数据。
表达式格式为 +/-,具体说明如下:
比如 DAY – 1 表示前一天。
这种表达方式存在一定的局限性,只能表示某个时间点的左右偏移量。如果要表示时间范围,可以用 BETWEEN 语法:
$X{BETWEEN, column, startParam, endParam}
比如说要设置当前周到某一天的,可以这样表示:
$X{BETWEEN, column, WEEK, DAY}
参数类型 | 说明 |
---|---|
net.sf.jasperreports.types.date.DateRange | 以 YYYY-MM-DD 格式表示的日期字符串。 |
net.sf.jasperreports.types.date.TimestampRange | 以 YYYY-MM-DD HH:mm:ss 格式表示的日期时间字符串。 |
必须使用 $X{}
表达式来处理时间范围。
可以使用 DateRangeBuilder() 类把时间范围参数的默认表达式转换为相应的时间范围参数类型。
示例 | 说明 |
---|---|
new net.sf.jasperreports.types.date.DateRangeBuilder(“DAY-1”).toDateRange() | 表示前一天,并转换为 DateRange 类型。 |
new net.sf.jasperreports.types.date.DateRangeBuilder(“WEEK”).set(Timestamp.class).toDateRange() | 表示一整周,并转换为 TimestampRange 类型。 |
new net.sf.jasperreports.types.date.DateRangeBuilder(“2020-02-01”).toDateRange() | 把日期字符串,转换为 DateRange 类型。 |
new net.sf.jasperreports.types.date.DateRangeBuilder(“2020-02-01 12:33:55”).toDateRange() | 把时间字符串,转换为 TimestampRange 类型。 |
比如说,需要展示前一天的数据,可以这样定义参数与 SQL 表达式(JRXML 形式):
展示上个月最后一天之前的数据:
指定时间范围或者相对入参的时间偏移量,可以照以下步骤进行:
还可以使用 getStart() 与 getEnd() 方法来精确指定时间范围的起止点