使用 JasperReports 打印每个报告的应用程序版本
Print application version for each report using JasperReports
我们使用的是 JasperReports 6.0.0,并且有大约 30 个模板用于几乎没有共同点的不同报告。今天我们有一个需求,在每份报告的每页底部打印应用程序版本。
如果不修改每个模板文件,我找不到任何好的解决方案。 JasperReport 是否允许为所有模板指定总体布局?有什么解决方案可以在不修改现有模板的情况下为每个页面添加标签吗?
一些方法:
- 手动修改所有
.jrxml
个文件并为每个文件添加页脚。
- 使用 XSLT 修改所有
.jrxml
模板并添加页脚。
- 生成报表PDF后使用iText修改报表输出。
- 在编译和执行之前,使用 JasperReports API 以编程方式将页脚带注入 in-memory 模板。
- 使用 JasperReports API 以编程方式将页脚带插入每个
.jrxml
文件并将文件保存回磁盘。
- 创建主模板并包含参数化子报表。
最后一种方法将有如下主模板:
-----------
| Title |
-----------
| Subreport |
-----------
| Footer |
-----------
然后,当 运行 报告时,传入一个参数,指示要包含的子报告(即 30 个中的一个)。以这种方式,所有 30 个报告共享 Title Band 和 Footer Band。这是更多的工作,但最终是最灵活的解决方案。
如果标题范围在所有报告中完全不同,将其参数化以使用子报告。
这是包含作为参数给出的子报表的主报表的屏幕截图。在屏幕截图中,Title Band 不包含子报表,因为每个报表看起来都一样(human-readable 报表标题也是一个参数)。应该很容易看出,如果 Title Band 必须 更改其每个报表的布局 ,那么使用子报表代替将有助于这样的解决方案:
不过,如屏幕截图所示,页脚是您问题的一种可能答案。
您可能需要定义一个允许计算页码的变量:
<variable name="V_CURRENT_PAGE_NUMBER" class="java.lang.Integer" resetType="Page">
<variableExpression><![CDATA[1]]></variableExpression>
<initialValueExpression><![CDATA[$V{PAGE_NUMBER}+1]]></initialValueExpression>
</variable>
以及引用页码的相应文本字段:
msg("Page {0} of {1}", $V{V_CURRENT_PAGE_NUMBER}, $V{PAGE_NUMBER})
记住 JasperReports 使用绝对路径,定义一些参数以避免 hard-coding 子报表的位置。例如:
$P{P_REPORT_SUBREPORTS_PATH} + $P{P_SUBREPORT_NAME} + ".jasper"
此处,P_REPORT_SUBREPORTS_PATH
是根据 P_REPORT_BASE
变量定义的:
$P{P_REPORT_BASE} + "subreports/"
这允许报告 IDE 通过为 P_REPORT_BASE
提供不同的值来使用与 Web 服务器目录不同的目录,具体取决于上下文。
最后,请记住,看似不同的报表可能是参数化报表。 JasperReports 允许自定义样式,这使得动态更改报告外观成为可能(例如,文本对齐、字体、强调、边框等)。例如,在屏幕截图中,报告标题随多个报告中的每一个而改变——但它们都共享相同的标题带,因为报告标题是作为字符串参数传入的。
我们使用的是 JasperReports 6.0.0,并且有大约 30 个模板用于几乎没有共同点的不同报告。今天我们有一个需求,在每份报告的每页底部打印应用程序版本。
如果不修改每个模板文件,我找不到任何好的解决方案。 JasperReport 是否允许为所有模板指定总体布局?有什么解决方案可以在不修改现有模板的情况下为每个页面添加标签吗?
一些方法:
- 手动修改所有
.jrxml
个文件并为每个文件添加页脚。 - 使用 XSLT 修改所有
.jrxml
模板并添加页脚。 - 生成报表PDF后使用iText修改报表输出。
- 在编译和执行之前,使用 JasperReports API 以编程方式将页脚带注入 in-memory 模板。
- 使用 JasperReports API 以编程方式将页脚带插入每个
.jrxml
文件并将文件保存回磁盘。 - 创建主模板并包含参数化子报表。
最后一种方法将有如下主模板:
-----------
| Title |
-----------
| Subreport |
-----------
| Footer |
-----------
然后,当 运行 报告时,传入一个参数,指示要包含的子报告(即 30 个中的一个)。以这种方式,所有 30 个报告共享 Title Band 和 Footer Band。这是更多的工作,但最终是最灵活的解决方案。
如果标题范围在所有报告中完全不同,将其参数化以使用子报告。
这是包含作为参数给出的子报表的主报表的屏幕截图。在屏幕截图中,Title Band 不包含子报表,因为每个报表看起来都一样(human-readable 报表标题也是一个参数)。应该很容易看出,如果 Title Band 必须 更改其每个报表的布局 ,那么使用子报表代替将有助于这样的解决方案:
不过,如屏幕截图所示,页脚是您问题的一种可能答案。
您可能需要定义一个允许计算页码的变量:
<variable name="V_CURRENT_PAGE_NUMBER" class="java.lang.Integer" resetType="Page">
<variableExpression><![CDATA[1]]></variableExpression>
<initialValueExpression><![CDATA[$V{PAGE_NUMBER}+1]]></initialValueExpression>
</variable>
以及引用页码的相应文本字段:
msg("Page {0} of {1}", $V{V_CURRENT_PAGE_NUMBER}, $V{PAGE_NUMBER})
记住 JasperReports 使用绝对路径,定义一些参数以避免 hard-coding 子报表的位置。例如:
$P{P_REPORT_SUBREPORTS_PATH} + $P{P_SUBREPORT_NAME} + ".jasper"
此处,P_REPORT_SUBREPORTS_PATH
是根据 P_REPORT_BASE
变量定义的:
$P{P_REPORT_BASE} + "subreports/"
这允许报告 IDE 通过为 P_REPORT_BASE
提供不同的值来使用与 Web 服务器目录不同的目录,具体取决于上下文。
最后,请记住,看似不同的报表可能是参数化报表。 JasperReports 允许自定义样式,这使得动态更改报告外观成为可能(例如,文本对齐、字体、强调、边框等)。例如,在屏幕截图中,报告标题随多个报告中的每一个而改变——但它们都共享相同的标题带,因为报告标题是作为字符串参数传入的。