JasperReports 处理空值
最后修改日期:2024 年 2 月 12 日
在本文中,我们将展示如何在 JasperReports 中处理空值。
JasperReports 是一个开源报告库。它可以创建各种格式的报告,包括 PDF、HTML、XLS 或 CSV。JasperReports 创建面向页面、可直接打印的文档。
数据源经常包含空值。这些在我们的报告中看起来不美观;因此,我们将展示如何将它们替换为空字符串或更具描述性的消息,例如“N/A”。
<textField isBlankWhenNull="true">
为了处理空值,我们可以将 textField
的 isBlankWhenNull
属性设置为 true
。
$F{salary} != null ? $F{salary} : 'N/A'
另一个选择是在 textFieldExpression
中使用三元运算符。
class CleanData { static String removeNull(def oldval, def newval = '') { if (oldval == null) { newval } else { oldval } } }
另一个选项是定义一个外部方法。
示例
在下一个示例中,我们将使用 isBlankWhenNull
属性和三元运算符。
report.gvy
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') @Grab(group='com.h2database', module='h2', version='1.4.200') @GrabConfig(systemClassLoader=true) import net.sf.jasperreports.engine.JasperCompileManager import net.sf.jasperreports.engine.JasperFillManager import net.sf.jasperreports.engine.JasperExportManager import groovy.sql.Sql def xmlFile = 'report.xml' def jrReport = JasperCompileManager.compileReport(xmlFile) def createTable = ''' CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), occupation VARCHAR(255), salary INT); INSERT INTO users(name, occupation, salary) VALUES('John Doe', 'gardener', NULL); INSERT INTO users(name, occupation, salary) VALUES('Roger Roe', 'driver', 940); INSERT INTO users(name, occupation, salary) VALUES('Roman Novy', 'programmer', 1980); INSERT INTO users(name, occupation, salary) VALUES('Lucia Biela', NULL, NULL); INSERT INTO users(name, occupation, salary) VALUES('Tomas Gerber', 'soldier', 1250); INSERT INTO users(name, occupation, salary) VALUES('Maria Smith', 'teacher', NULL); INSERT INTO users(name, occupation, salary) VALUES('Oleg Vasil', NULL, 2550); INSERT INTO users(name, occupation, salary) VALUES('Martin Krajci', 'optician', 2050); ''' def url = "jdbc:h2:mem:" Sql.withInstance(url) { sql -> sql.execute(createTable) def params = [:] def jPrint = JasperFillManager.fillReport(jrReport, params, sql.connection) JasperExportManager.exportReportToPdfFile(jPrint, "report.pdf") }
我们在内存中的 H2 数据库中定义了一个 users
表。
def createTable = ''' CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), occupation VARCHAR(255), salary INT); INSERT INTO users(name, occupation, salary) VALUES('John Doe', 'gardener', NULL); INSERT INTO users(name, occupation, salary) VALUES('Roger Roe', 'driver', 940); INSERT INTO users(name, occupation, salary) VALUES('Roman Novy', 'programmer', 1980); INSERT INTO users(name, occupation, salary) VALUES('Lucia Biela', NULL, NULL); INSERT INTO users(name, occupation, salary) VALUES('Tomas Gerber', 'soldier', 1250); INSERT INTO users(name, occupation, salary) VALUES('Maria Smith', 'teacher', NULL); INSERT INTO users(name, occupation, salary) VALUES('Oleg Vasil', NULL, 2550); INSERT INTO users(name, occupation, salary) VALUES('Martin Krajci', 'optician', 2050); '''
该表在 occupation
和 salary
列中包含空值。
report.xml
<?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" language="groovy" name="report" topMargin="20" bottomMargin="20"> <queryString language="SQL"> <![CDATA[ SELECT id, name, occupation, salary from users ]]> </queryString> <field name="id" class="java.lang.Integer"/> <field name="name"/> <field name="occupation"/> <field name="salary" class="java.lang.Integer" /> <title> <band height="60"> <staticText> <reportElement x="0" y="0" width="595" height="35"/> <textElement textAlignment="Center"/> <text><![CDATA[Users]]></text> </staticText> </band> </title> <detail> <band height="30"> <textField> <reportElement x="0" y="0" width="25" height="25"/> <textFieldExpression class="java.lang.Integer"> <![CDATA[$F{id}]]> </textFieldExpression> </textField> <textField> <reportElement x="30" y="0" width="100" height="25"/> <textFieldExpression> <![CDATA[$F{name}]]> </textFieldExpression> </textField> <textField isBlankWhenNull="true"> <reportElement x="140" y="0" width="70" height="25"/> <textFieldExpression> <![CDATA[ $F{occupation} ]]> </textFieldExpression> </textField> <textField> <reportElement x="220" y="0" width="70" height="25"/> <textElement textAlignment="Right"/> <textFieldExpression class="java.lang.Integer"> <![CDATA[ $F{salary} != null ? $F{salary} : 'N/A' ]]> </textFieldExpression> </textField> </band> </detail> </jasperReport>
这是报告模板。
<textField isBlankWhenNull="true"> <reportElement x="140" y="0" width="70" height="25"/> <textFieldExpression> <![CDATA[ $F{occupation} ]]> </textFieldExpression> </textField>
我们将 occupation
字段的 isBlankWhenNull
设置为 true
。具有空值的单元格将为空。
<textField> <reportElement x="220" y="0" width="70" height="25"/> <textElement textAlignment="Right"/> <textFieldExpression class="java.lang.Integer"> <![CDATA[ $F{salary} != null ? $F{salary} : 'N/A' ]]> </textFieldExpression> </textField>
对于 salary
字段,我们使用三元运算符。空值将被替换为 N/A
字符串。
在下一个示例中,我们定义了一个处理空值的外部方法。
report.gvy
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') @Grab(group='net.sf.jasperreports', module='jasperreports-fonts', version='6.21.0') @Grab(group='com.h2database', module='h2', version='1.4.200') @GrabConfig(systemClassLoader=true) import net.sf.jasperreports.engine.JasperCompileManager import net.sf.jasperreports.engine.JasperFillManager import net.sf.jasperreports.engine.JasperExportManager import groovy.sql.Sql def xmlFile = 'report.xml' def jrReport = JasperCompileManager.compileReport(xmlFile) def createTable = ''' CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), occupation VARCHAR(255), salary INT); INSERT INTO users(name, occupation, salary) VALUES('John Doe', 'gardener', NULL); INSERT INTO users(name, occupation, salary) VALUES('Roger Roe', 'driver', 940); INSERT INTO users(name, occupation, salary) VALUES('Roman Novy', 'programmer', 1980); INSERT INTO users(name, occupation, salary) VALUES('Lucia Biela', NULL, NULL); INSERT INTO users(name, occupation, salary) VALUES('Tomas Gerber', 'soldier', 1250); INSERT INTO users(name, occupation, salary) VALUES('Maria Smith', 'teacher', NULL); INSERT INTO users(name, occupation, salary) VALUES('Oleg Vasil', NULL, 2550); INSERT INTO users(name, occupation, salary) VALUES('Martin Krajci', 'optician', 2050); ''' def url = "jdbc:h2:mem:" Sql.withInstance(url) { sql -> sql.execute(createTable) def params = [:] def jPrint = JasperFillManager.fillReport(jrReport, params, sql.connection) JasperExportManager.exportReportToPdfFile(jPrint, "report.pdf") } class CleanData { static String removeNull(def oldval, def newval = '') { if (oldval == null) { newval } else { oldval } } }
在 Groovy 代码中,我们定义了 CleanData
及其 removeNull
方法。它允许我们选择一个特定的消息来代替空值。
report.xml
<?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" language="groovy" name="report" topMargin="20" bottomMargin="20"> <import value="com.zetcode.CleanData"/> <queryString language="SQL"> <![CDATA[ SELECT id, name, occupation, salary from users ]]> </queryString> <field name="id" class="java.lang.Integer"/> <field name="name"/> <field name="occupation"/> <field name="salary" class="java.lang.Integer" /> <variable name="sumsal" class="java.lang.Integer" calculation="Sum"> <variableExpression><![CDATA[$F{salary}]]></variableExpression> </variable> <title> <band height="60"> <staticText> <reportElement x="0" y="0" width="595" height="35"/> <textElement textAlignment="Center"/> <text><![CDATA[Users]]></text> </staticText> </band> </title> <detail> <band height="30"> <textField> <reportElement x="0" y="0" width="25" height="25"/> <textFieldExpression class="java.lang.Integer"> <![CDATA[$F{id}]]> </textFieldExpression> </textField> <textField> <reportElement x="30" y="0" width="100" height="25"/> <textFieldExpression> <![CDATA[$F{name}]]> </textFieldExpression> </textField> <textField> <reportElement x="140" y="0" width="70" height="25"/> <textFieldExpression> <![CDATA[ CleanData.removeNull($F{occupation}, 'N/A') ]]> </textFieldExpression> </textField> <textField> <reportElement x="220" y="0" width="70" height="25"/> <textElement textAlignment="Right"/> <textFieldExpression> <![CDATA[ CleanData.removeNull($F{salary}, 'N/A') ]]> </textFieldExpression> </textField> </band> </detail> <summary> <band height="25"> <textField> <reportElement x="220" y="0" width="70" height="25"/> <textElement textAlignment="Right"> <font isBold = "true"/> </textElement> <textFieldExpression><![CDATA[$V{sumsal}]]></textFieldExpression> </textField> </band> </summary> </jasperReport>
在此报告中,我们使用外部 CleanData.removeNull
方法。
<import value="com.zetcode.CleanData"/>
我们将类导入到报告中。
<textField> <reportElement x="140" y="0" width="70" height="25"/> <textFieldExpression> <![CDATA[ CleanData.removeNull($F{occupation}, 'N/A') ]]> </textFieldExpression> </textField>
我们将 CleanData.removeNull
传递 $F{occupation}
值和用于替换潜在空值的可选字符串。
在本文中,我们演示了如何将空值替换为空字符串或更具描述性的消息。