如何获得平均值忽略字段

时间:2016-10-09 10:26:48

标签: java jasper-reports

我知道如何获得数字之间的平均值,但是当我尝试使用相同的方法(通过设置变量的属性)来获得数字和字符串的混合值的平均值时,它总是返回异常(我知道原因)。

如何使用数字和字符串的混合值获取 column_1 的平均值?

column_1
  3
  4
  N/A
  3
  N/A

意思是说,在第1列中,平均值必须为3.33.应该应用(3+4+3)/3公式,必须忽略/排除计算中的两个N/A值。怎么做?

1 个答案:

答案 0 :(得分:2)

此任务可以分解为几个简单的子任务:

  1. 从混合类型中获取数值。我们应该检查字段的数值。
  2. 计算所有数值的平均值(跳过非数字值)。
  3. 为了解决第一个子任务,我们可以使用Apache commons-lang 库。 StringUtils.isNumeric(java.lang.CharSequence)方法可帮助我们检查值是否为数字。

    为了解决第二个子任务,我们可以使用两个变量 - 第一个用于存储数值,第二个用于计算平均值。

    工作示例

    数据源

    我在此示例中使用了csv数据源:

    numValue
    3
    4
    N/A
    3
    N/A
    

    以下示例中此数据源的数据适配器名称为 str_num.csv 。跳过文件的第一行 - 它包含列的名称。

    报告的模板

    我使用 Jaspersoft Studio (JSS)来设计报告模板。 Detail 频段用于显示数据,摘要频段用于显示平均值。

    包含值(数字和非数字)的字段将属于 java.lang.String 类型。

    第一个变量仅用于存储数值。如果值

    ,我们正在使用 null 初始化变量

    表达式为:

    StringUtils.isNumeric($F{numValue}) ? Integer.valueOf($F{numValue}) : null
    

    Java 库正在此表达式中使用,这就是为什么我们需要将报表的语言设置为 java 并为类 StringUtils 添加导入

    平均值计算类型的第二个变量:

    <variable name="averageValue" class="java.lang.Double" calculation="Average">
        <variableExpression><![CDATA[$V{number}]]></variableExpression>
        <initialValueExpression><![CDATA[0]]></initialValueExpression>
    </variable>
    

    完整模板:

    <?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="Average value" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="bee405b0-c35a-442a-841d-f51423c1c797">
        <property name="com.jaspersoft.studio.data.defaultdataadapter" value="str_num.csv"/>
        <import value="org.apache.commons.lang3.StringUtils"/>
        <queryString>
            <![CDATA[]]>
        </queryString>
        <field name="numValue" class="java.lang.String"/>
        <variable name="number" class="java.lang.Integer">
            <variableExpression><![CDATA[StringUtils.isNumeric($F{numValue}) ? Integer.valueOf($F{numValue}) : null]]></variableExpression>
        </variable>
        <variable name="averageValue" class="java.lang.Double" calculation="Average">
            <variableExpression><![CDATA[$V{number}]]></variableExpression>
            <initialValueExpression><![CDATA[0]]></initialValueExpression>
        </variable>
        <detail>
            <band height="30" splitType="Stretch">
                <textField>
                    <reportElement x="0" y="0" width="230" height="30" uuid="9d00d7e3-b9bc-404d-8842-728326a5d2df"/>
                    <textFieldExpression><![CDATA["Original value: " + $F{numValue}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="230" y="0" width="250" height="30" uuid="4509cae9-3b89-4860-838a-36aa4466fb37"/>
                    <textFieldExpression><![CDATA["Only numeric value: " + $V{number}]]></textFieldExpression>
                </textField>
            </band>
        </detail>
        <summary>
            <band height="53">
                <staticText>
                    <reportElement x="0" y="0" width="230" height="30" uuid="937af139-259c-49da-a0d9-191bcf801cca"/>
                    <text><![CDATA[Average value (non numeric values are skipped):]]></text>
                </staticText>
                <textField pattern="0.00">
                    <reportElement x="230" y="0" width="140" height="30" uuid="9abd786b-32ee-4ab1-91dc-851e8bfef0db"/>
                    <textFieldExpression><![CDATA[$V{averageValue}]]></textFieldExpression>
                </textField>
            </band>
        </summary>
    </jasperReport>
    

    输出结果

    JSS 中生成的resut如下所示:

    The result in JSS. Average of 3 records

    如果我们将第一个变量(用于存储数值)的表达式更改为:

    StringUtils.isNumeric($F{numValue}) ? Integer.valueOf($F{numValue}) : 0
    

    结果将是:

    The result in JSS. Average of 5 records

    - 这是5条记录的平均值,而不是上述第一种情况中的3条记录。