JasperReports Scriptlet
最后修改日期:2024 年 2 月 12 日
在本文中,我们将介绍 JasperReport scriptlet。
JasperReports 是一个开源报告库。它可以创建各种格式的报告,包括 PDF、HTML、XLS 或 CSV。JasperReports 以简单灵活的方式创建面向页面、可打印的文档。
Scriptlet 是 Java 类,它们为 JasperReports 提供额外的功能。当报表表达式无法执行更复杂的操作时,我们可以使用 scriptlet。Scriptlet 在每次报表事件发生时执行。Scriptlet 可以影响报表变量的值。
计算几何平均数
下面的应用程序计算利率的几何平均数。几何平均数定义为 n 个数的乘积的 n 次根。它用于增长率,例如人口增长或利率,其中简单的算术平均数不能给出准确的结果。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report" topMargin="20" bottomMargin="20"> <scriptlet name="MyScriptlet" class="com.zetcode.MyScriptlet"/> <parameter name="vals" class="java.util.List"/> <variable name="gmean" class="java.lang.Double"/> <summary> <band height="30"> <staticText> <reportElement x="0" y="0" width="90" height="15"/> <textElement/> <text><![CDATA[Geometric mean: ]]></text> </staticText> <textField> <reportElement x="100" y="0" width="200" height="15"/> <textElement/> <textFieldExpression class="java.lang.Double"> <![CDATA[$V{gmean}]]> </textFieldExpression> </textField> </band> </summary> </jasperReport>
这是报表模板文件。模板包含摘要段,其中有一个变量:gmean
。
<scriptlet name="MyScriptlet" class="com.zetcode.MyScriptlet"/>
Scriptlet 使用 scriptlet
标签引用。它是一个包含几何平均数计算的类。
<parameter name="rets" class="java.util.List"/> <variable name="gmean" class="java.lang.Double"/>
我们有一个参数和一个变量。参数是利率值列表。变量是计算出的几何平均数。
<textFieldExpression class="java.lang.Double"> <![CDATA[$V{gmean}]]> </textFieldExpression>
在 textFieldExpression
标签中,我们输出几何平均数。
package com.zetcode @Grab(group='net.sf.jasperreports', module='jasperreports', version='6.21.0') @Grab(group='org.apache.commons', module='commons-math3', version='3.6.1') @Grab(group='com.github.librepdf', module='openpdf', version='1.3.39') import java.util.List import net.sf.jasperreports.engine.JRDefaultScriptlet import net.sf.jasperreports.engine.JREmptyDataSource import net.sf.jasperreports.engine.JasperCompileManager import net.sf.jasperreports.engine.JasperExportManager import net.sf.jasperreports.engine.JasperFillManager import net.sf.jasperreports.renderers.JCommonDrawableRendererImpl import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics // Report generation def xmlFile = "report.xml" def jrReport = JasperCompileManager.compileReport(xmlFile) def vals = [1.2, 1.8, -1.2, 0.9, 1.1, 3.5, -2.7] def params = [:] params.put("vals", vals) def jrPrint = JasperFillManager.fillReport(jrReport, params, new JREmptyDataSource()) JasperExportManager.exportReportToPdfFile(jrPrint, "report.pdf") // Scriptlet class class MyScriptlet extends JRDefaultScriptlet { private DescriptiveStatistics stats void afterReportInit() { def vals = getParameterValue("vals") stats = new DescriptiveStatistics() vals.forEach((val) -> stats.addValue(val)) } void afterDetailEval() { setVariableValue("gmean", stats.getMean()) } }
Groovy 脚本生成报表。
def vals = [1.2, 1.8, -1.2, 0.9, 1.1, 3.5, -2.7]
这些值是我们的利率。
params.put("vals", vals)
该列表被放入参数中。该列表映射到报表中创建的 <parameter name="vals" class="java.util.List"/>
元素。
class MyScriptlet extends JRDefaultScriptlet {
Scriptlet 继承自 JRDefaultScriptlet
。它为 scriptlet 事件提供了默认的空实现。
private DescriptiveStatistics stats void afterReportInit() { def vals = getParameterValue("vals") stats = new DescriptiveStatistics() vals.forEach((val) -> stats.addValue(val)) }
在报表初始化后,我们获取包含利率值的 vals
参数,并将其插入 DescriptiveStatistics
。
void afterDetailEval() { setVariableValue("gmean", stats.getMean()) }
在 afterDetailEval
事件之后,计算几何平均数并将其设置为 gmean
变量。
图表 Scriptlet
下面的应用程序创建一个饼图。它使用了 JFreeChart 库。
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"> <jasperReport xmlns = "http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20"> <scriptlet name="MyScriptlet" class="com.zetcode.MyScriptlet"/> <parameter name="langs" class="java.util.Map"/> <variable name="Chart" class="net.sf.jasperreports.renderers.JCommonDrawableRendererImpl" calculation="System"/> <detail> <band height="430"> <image scaleImage="Clip" hAlign="Center"> <reportElement x="0" y="0" width="515" height="300"/> <imageExpression> <![CDATA[ $V{Chart} ]]> </imageExpression> </image> </band> </detail> </jasperReport>
在报表模板文件中,我们有一个详细信息段,其中有一个 <image>
元素,用于显示图表。
<scriptlet name="MyScriptlet" class="com.zetcode.MyScriptlet" />
Scriptlet 是一个创建图表对象的 Groovy 类。
<parameter name="langs" class="java.util.Map"/> <variable name="Chart" class="net.sf.jasperreports.renderers.JCommonDrawableRendererImpl" calculation="System"/>
我们有一个参数和一个变量。参数是要在图表中显示的值的映射。变量包含图表对象。
package com.zetcode @Grab(group='net.sf.jasperreports', module='jasperreports', version='6.21.0') @Grab(group='com.github.librepdf', module='openpdf', version='1.3.39') import net.sf.jasperreports.engine.JREmptyDataSource import net.sf.jasperreports.engine.JRException import net.sf.jasperreports.engine.JasperCompileManager import net.sf.jasperreports.engine.JasperExportManager import net.sf.jasperreports.engine.JasperFillManager import net.sf.jasperreports.engine.JRDefaultScriptlet import net.sf.jasperreports.renderers.JCommonDrawableRendererImpl import org.jfree.chart.ChartFactory import org.jfree.data.general.DefaultPieDataset import org.jfree.util.Rotation // Report generation def xmlFile = "report.xml" def jrReport = JasperCompileManager.compileReport(xmlFile) def langs = [ "Python": 30.2, "C#": 10.0, "Java": 17.5, "PHP": 8.5, "Clojure": 1.1] def params = ["langs": langs] def jrPrint = JasperFillManager.fillReport(jrReport, params, new JREmptyDataSource()) JasperExportManager.exportReportToPdfFile(jrPrint, "report.pdf") // Scriptlet class class MyScriptlet extends JRDefaultScriptlet { void afterReportInit() { def langs = getParameterValue("langs") def dataset = new DefaultPieDataset() langs.forEach(dataset::setValue) def chart = ChartFactory.createPieChart3D( "Computer languages", dataset, true, true, false ) def plot = chart.getPlot() plot.setStartAngle(290) plot.setDirection(Rotation.CLOCKWISE) plot.setForegroundAlpha(0.5f) plot.setNoDataMessage("No data to display") this.setVariableValue("Chart", new JCommonDrawableRendererImpl(chart)) } }
脚本编译报表模板并创建一个 PDF 文件。
def langs = [ "Python": 30.2, "C#": 10.0, "Java": 17.5, "PHP": 8.5, "Clojure": 1.1]
此映射中的值将显示在饼图中。
def params = ["langs": langs]
数据作为 langs
参数传递。
class MyScriptlet extends JRDefaultScriptlet {
此 scriptlet 从 langs
参数检索数据并生成饼图。图表被设置为报表模板变量。
def langs = getParameterValue("langs")
在报表初始化后,我们获取包含图表数据的 langs
参数。
def dataset = new DefaultPieDataset() langs.forEach(dataset::setValue)
数据被设置为 DefaultPieDataset
。
def chart = ChartFactory.createPieChart3D( "Computer languages", dataset, true, true, false ) def plot = chart.getPlot() plot.setStartAngle(290) plot.setDirection(Rotation.CLOCKWISE) plot.setForegroundAlpha(0.5f) plot.setNoDataMessage("No data to display")
生成了一个 3D 饼图。
this.setVariableValue("Chart", new JCommonDrawableRendererImpl(chart))
生成的图表被设置为 Chart
报表模板变量。
在本文中,我们学习了 scriptlet;我们计算了利率的几何平均数并生成了一个 3D 饼图。