当使用带表达式的条件表达式时,如何在JasperReports中获取当前元素? [英] How to get current element in JasperReports when using conditionalExpression with styles?

查看:193
本文介绍了当使用带表达式的条件表达式时,如何在JasperReports中获取当前元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当单元格的数值小于零时,我想让textValue中的文本变为红色。目前我的配置是这样的:

 < style name =RedText> 
< conditionalStyle>
< conditionExpression><![CDATA [$ F {col1} .compareTo(BigDecimal.ZERO)== -1]]>< / conditionExpression>
< style forecolor =#FF0000/>
< / conditionalStyle>
< / style>

我有更多的单元格(col2,col3,col4 ......)我需要应用这个红色文字样式。是否有可能使它成为当前值的通用等col *?

解决方案

不使用Java代码的标准/经典方式



如果不使用 Java 代码,这是不可能的。在您的情况下,您需要为每个字段创建新样式,并为 textField 元素应用此具体样式,其中 conditionExpression 包含具体字段的值。



在通常情况下, textField 的表达式可能很复杂,对于 conditionExpression 也是如此。该样式不知道它属于哪个控件。我们不能使用抽象字段(参数/变量)的值来操作,引擎需要具体名称来计算表达式。



使用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);



使用后门或是的我们喜欢破解



看看 Java 中的美丽类是 Map ,它在 JasperReports 中非常宝贵。它可以帮助我们破解这项任务。


  1. 我们需要 Map 类型的参数来存储字段的值(它将是抽象字段 - col n

  2. 我们需要在解析文本字段。主题


    I want to make text in the textValue to be red when the numeric value of the cell is less than zero. Currently my configuration is like this:

    <style name="RedText">
        <conditionalStyle>
            <conditionExpression><![CDATA[$F{col1}.compareTo(BigDecimal.ZERO) == -1]]></conditionExpression>
            <style forecolor="#FF0000"/>
        </conditionalStyle>
    </style>
    

    I have more cells (col2, col3, col4 ...) that I would need to apply this red text style. Is it possible to make it universal for current value, etc. col*?

    解决方案

    The standard/classical way without using Java code

    It is impossible without using Java code. In your case you need to create the new style for each field and apply this concrete style for textField element with conditionExpression contains the value of concrete field.

    In common case the expression of textField can be complex, the same is true for the conditionExpression. The style does not know to which control it belongs. We can't operate with value of abstract field (parameter/variable), the engine need the concrete names to calculate expression.

    Using Java API

    Is it possible to solve the task applying style with JasperReports Java API. For example:

    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);
    

    Using backdoor or "yes we like to hack"

    Look at the beatiful class in Java is Map, it so invaluable in JasperReports. It can help us to crack this task.

    1. We need parameter of Map type for storing the value of field (it will be abstract field - "coln")
    2. We need to enable applying style during resolving expression of a textField. The propery net.sf.jasperreports.style.evaluation.time.enabled will help to enable this feature.
    3. We need some Java method for putting value in to the Map (as a storage of a "coln") which returns the value we just put. The Map.put(K key, V value) is not good for this purpose. I wrote the small Utility class with wrapper over Map.put method.

    The datasouce

    The using of simple csv datasource is enough for this example. I like this kind of datasource for testing and debugging.

    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
    

    The name of data adapter for this datasource in the example below is numbers.csv. The first line from the file is skipped - it is contains the column's name.

    Java code

    It is a very simple utility class

    public class Storage {
    
        public static Integer add(Map<String, Integer> map, String key, Integer value) {
            map.put(key, value);
            return value;
        }
    }
    

    Report template

    1. The import for our utitlity class should be added for using it.

    2. For correct resolving expression of conditional style we need to use in expression some parameter or some variable (you can check the source code of JasperReports). I'll add some fake variable for using in conditionExpression

    3. We need to put the value of "coln" to the Map and then use this value in conditional style. In this case we don't need to know the name of field we are checking in conditional style. The parameter will be used for storing Map.

    4. We need place and draw the value of "coln" in two runs. We can use fake invisible textField to put the field's value to the Map and another textField to show value with applying conditional style. The positions and sizes of this textFields are same - one above the other.

    Our condition will be like this:

    <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>
    

    There is no field in conditionExpression and it works :)

    The jrxml file:

    <?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>
    

    The green color is used for positive numbers and blue - for negative. The red color is using to indicate algorithm's problems.

    Output result

    The generated pdf with help of JRPdfExporter:

    这篇关于当使用带表达式的条件表达式时,如何在JasperReports中获取当前元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆