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 饼图。