将条件表达式与样式一起使用时如何获取 JasperReports 中的当前元素?
How to get current element in JasperReports when using conditionalExpression with styles?
我想在单元格的数值小于零时将 textValue 中的文本设置为红色。目前我的配置是这样的:
<style name="RedText">
<conditionalStyle>
<conditionExpression><![CDATA[$F{col1}.compareTo(BigDecimal.ZERO) == -1]]></conditionExpression>
<style forecolor="#FF0000"/>
</conditionalStyle>
</style>
我有更多的单元格(col2、col3、col4 ...)需要应用这种红色文本样式。是否有可能使它对当前值等具有通用性。col*?
不使用Java代码的standard/classical方法
不使用Java代码是不可能的。在您的情况下,您需要为每个字段创建新样式并将此具体样式应用于 textField 元素,其中 conditionExpression 包含具体值 字段.
通常情况下textField的表达式可能很复杂,conditionExpression也是如此。样式不知道它属于哪个控件。我们不能使用抽象字段的值(parameter/variable),引擎需要具体的名称来计算表达式。
使用 Java API
是否可以使用 JasperReports Java API 解决应用样式的任务。例如:
JRDesignStyle boldStyle = new JRDesignStyle();
boldStyle.setName("Sans_Bold");
boldStyle.setFontName("DejaVu Sans");
boldStyle.setFontSize(12);
boldStyle.setBold(true);
// ...
textField.setStyle(boldStyle);
JRDesignExpression expression = new JRDesignExpression();
expression.setText("$F{col1}");
textField.setExpression(expression);
使用后门或"yes we like to hack"
看看Java中美丽的class是地图,它在[=65中是无价的=]JasperReports。可以帮助我们破解这个任务。
- 我们需要 Map 类型的参数来存储字段的值(它将是抽象字段 - "coln")
- 我们需要在解析 textField 的表达式时启用应用样式。 属性
net.sf.jasperreports.style.evaluation.time.enabled 将有助于启用此功能。
- 我们需要一些 Java 方法来将值放入 Map(作为 "coln") 其中 returns 我们刚刚输入的值。 Map.put(K key, V value) 不适用于此目的。我用 Map.put 方法的包装器编写了小型实用程序 class。
数据源
使用简单的 csv 数据源就足够了。我喜欢这种用于测试和调试的数据源。
col1,col2,col3,col4,col5
1,2,3,9,-5
-2,6,-3,4,1
2,-2,-2,7,-3
8,3,4,-5,6
下例中此数据源的数据适配器名称为numbers.csv。文件的第一行被跳过 - 它包含列的名称。
Java代码
这是一个非常简单的实用程序class
public class Storage {
public static Integer add(Map<String, Integer> map, String key, Integer value) {
map.put(key, value);
return value;
}
}
报告模板
我们的实用程序 class 的导入应该添加以便使用它。
为了正确解析条件式的表达式,我们需要在表达式中使用一些参数或变量(你可以查看[=65=的源代码]JasperReports)。我将添加一些假变量用于 conditionExpression
我们需要把"coln"的值放到Map中,然后使用这个值条件样式。在这种情况下,我们不需要知道我们在 条件样式 中检查的字段名称。该参数将用于存储Map.
我们需要分两次放置和绘制"coln"的值。我们可以使用伪造的不可见 textField 将字段的值放入 Map 和另一个 textField 来显示值应用条件样式。 textField 的位置和大小相同 - 一个在另一个之上。
我们的条件是这样的:
<style name="ColoredText">
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) < 0)]]></conditionExpression>
<style forecolor="blue"/>
</conditionalStyle>
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) > 0)]]></conditionExpression>
<style forecolor="green"/>
</conditionalStyle>
</style>
conditionExpression 中没有 field 并且有效:)
jrxml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<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="Apply style withou name" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="numbers.csv"/>
<property name="net.sf.jasperreports.style.evaluation.time.enabled" value="true"/>
<import value="some.package.Storage"/>
<style name="ColoredText">
<conditionalStyle>
<conditionExpression><![CDATA[$P{STORAGE}.get($P{KEY}) == null && !"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style forecolor="#CC0000"/>
</conditionalStyle>
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) < 0) && !"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style forecolor="#0037FF"/>
</conditionalStyle>
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) > 0) && !"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style forecolor="#00BA00"/>
</conditionalStyle>
</style>
<style name="Fake">
<conditionalStyle>
<conditionExpression><![CDATA[!"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style mode="Opaque" forecolor="#FFFFFF" backcolor="#FFFFFF"/>
</conditionalStyle>
</style>
<parameter name="STORAGE" class="java.util.Map">
<defaultValueExpression><![CDATA[new java.util.HashMap()]]></defaultValueExpression>
</parameter>
<parameter name="KEY" class="java.lang.String">
<defaultValueExpression><![CDATA["key"]]></defaultValueExpression>
</parameter>
<field name="col1" class="java.lang.Integer"/>
<field name="col2" class="java.lang.Integer"/>
<field name="col3" class="java.lang.Integer"/>
<field name="col4" class="java.lang.Integer"/>
<field name="col5" class="java.lang.Integer"/>
<variable name="FAKE" class="java.lang.String">
<variableExpression><![CDATA["FAKE"]]></variableExpression>
</variable>
<detail>
<band height="20">
<textField evaluationTime="Auto">
<reportElement style="Fake" x="0" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col1})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="0" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="100" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col2})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="100" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="200" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col3})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="200" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="300" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col4})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="300" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="400" y="0" width="140" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col5})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="400" y="0" width="140" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
绿色用于正数,蓝色用于负数。红色用于表示算法的问题。
输出结果
借助JRPdfExporter生成的pdf:
我想在单元格的数值小于零时将 textValue 中的文本设置为红色。目前我的配置是这样的:
<style name="RedText">
<conditionalStyle>
<conditionExpression><![CDATA[$F{col1}.compareTo(BigDecimal.ZERO) == -1]]></conditionExpression>
<style forecolor="#FF0000"/>
</conditionalStyle>
</style>
我有更多的单元格(col2、col3、col4 ...)需要应用这种红色文本样式。是否有可能使它对当前值等具有通用性。col*?
不使用Java代码的standard/classical方法
不使用Java代码是不可能的。在您的情况下,您需要为每个字段创建新样式并将此具体样式应用于 textField 元素,其中 conditionExpression 包含具体值 字段.
通常情况下textField的表达式可能很复杂,conditionExpression也是如此。样式不知道它属于哪个控件。我们不能使用抽象字段的值(parameter/variable),引擎需要具体的名称来计算表达式。
使用 Java API
是否可以使用 JasperReports Java API 解决应用样式的任务。例如:
JRDesignStyle boldStyle = new JRDesignStyle();
boldStyle.setName("Sans_Bold");
boldStyle.setFontName("DejaVu Sans");
boldStyle.setFontSize(12);
boldStyle.setBold(true);
// ...
textField.setStyle(boldStyle);
JRDesignExpression expression = new JRDesignExpression();
expression.setText("$F{col1}");
textField.setExpression(expression);
使用后门或"yes we like to hack"
看看Java中美丽的class是地图,它在[=65中是无价的=]JasperReports。可以帮助我们破解这个任务。
- 我们需要 Map 类型的参数来存储字段的值(它将是抽象字段 - "coln")
- 我们需要在解析 textField 的表达式时启用应用样式。 属性 net.sf.jasperreports.style.evaluation.time.enabled 将有助于启用此功能。
- 我们需要一些 Java 方法来将值放入 Map(作为 "coln") 其中 returns 我们刚刚输入的值。 Map.put(K key, V value) 不适用于此目的。我用 Map.put 方法的包装器编写了小型实用程序 class。
数据源
使用简单的 csv 数据源就足够了。我喜欢这种用于测试和调试的数据源。
col1,col2,col3,col4,col5
1,2,3,9,-5
-2,6,-3,4,1
2,-2,-2,7,-3
8,3,4,-5,6
下例中此数据源的数据适配器名称为numbers.csv。文件的第一行被跳过 - 它包含列的名称。
Java代码
这是一个非常简单的实用程序class
public class Storage {
public static Integer add(Map<String, Integer> map, String key, Integer value) {
map.put(key, value);
return value;
}
}
报告模板
我们的实用程序 class 的导入应该添加以便使用它。
为了正确解析条件式的表达式,我们需要在表达式中使用一些参数或变量(你可以查看[=65=的源代码]JasperReports)。我将添加一些假变量用于 conditionExpression
我们需要把"coln"的值放到Map中,然后使用这个值条件样式。在这种情况下,我们不需要知道我们在 条件样式 中检查的字段名称。该参数将用于存储Map.
我们需要分两次放置和绘制"coln"的值。我们可以使用伪造的不可见 textField 将字段的值放入 Map 和另一个 textField 来显示值应用条件样式。 textField 的位置和大小相同 - 一个在另一个之上。
我们的条件是这样的:
<style name="ColoredText">
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) < 0)]]></conditionExpression>
<style forecolor="blue"/>
</conditionalStyle>
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) > 0)]]></conditionExpression>
<style forecolor="green"/>
</conditionalStyle>
</style>
conditionExpression 中没有 field 并且有效:)
jrxml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<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="Apply style withou name" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="numbers.csv"/>
<property name="net.sf.jasperreports.style.evaluation.time.enabled" value="true"/>
<import value="some.package.Storage"/>
<style name="ColoredText">
<conditionalStyle>
<conditionExpression><![CDATA[$P{STORAGE}.get($P{KEY}) == null && !"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style forecolor="#CC0000"/>
</conditionalStyle>
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) < 0) && !"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style forecolor="#0037FF"/>
</conditionalStyle>
<conditionalStyle>
<conditionExpression><![CDATA[(((Integer)$P{STORAGE}.get($P{KEY})) > 0) && !"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style forecolor="#00BA00"/>
</conditionalStyle>
</style>
<style name="Fake">
<conditionalStyle>
<conditionExpression><![CDATA[!"null".equalsIgnoreCase($V{FAKE})]]></conditionExpression>
<style mode="Opaque" forecolor="#FFFFFF" backcolor="#FFFFFF"/>
</conditionalStyle>
</style>
<parameter name="STORAGE" class="java.util.Map">
<defaultValueExpression><![CDATA[new java.util.HashMap()]]></defaultValueExpression>
</parameter>
<parameter name="KEY" class="java.lang.String">
<defaultValueExpression><![CDATA["key"]]></defaultValueExpression>
</parameter>
<field name="col1" class="java.lang.Integer"/>
<field name="col2" class="java.lang.Integer"/>
<field name="col3" class="java.lang.Integer"/>
<field name="col4" class="java.lang.Integer"/>
<field name="col5" class="java.lang.Integer"/>
<variable name="FAKE" class="java.lang.String">
<variableExpression><![CDATA["FAKE"]]></variableExpression>
</variable>
<detail>
<band height="20">
<textField evaluationTime="Auto">
<reportElement style="Fake" x="0" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col1})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="0" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="100" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col2})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="100" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="200" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col3})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="200" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="300" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col4})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="300" y="0" width="100" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="Fake" x="400" y="0" width="140" height="20"/>
<textFieldExpression><![CDATA[some.package.Storage.add($P{STORAGE}, $P{KEY}, $F{col5})]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto">
<reportElement style="ColoredText" x="400" y="0" width="140" height="20"/>
<textFieldExpression><![CDATA[$P{STORAGE}.get($P{KEY})]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
绿色用于正数,蓝色用于负数。红色用于表示算法的问题。
输出结果
借助JRPdfExporter生成的pdf: