Группировка и суммирование данных

Данная статья является продолжением двух других статей, где рассматривался пример использования библиотеки JasperReport для создания отчета на основе jrxml-шаблона, формируемого приложением iReport Designer. Здесь описанный ранее пример получает дальнейшее развитие и на его основе рассматриваются четыре вопроса :

  • группировка данных;
  • суммирование данных в группе;
  • суммирование всех данных;
  • нумерация записей в группе.

В статье практически не будет Java кода; основной упор переносится на iReport Designer : формирование секций отчета (группировка, суммирование), определение переменных для секций, взгляд на добавленные в jrxml-шаблон секции изнутри. Общая структура jrxml-шаблона на примере описана в предыдущих статьях и здесь будут представлены только изменения. В конце статьи пример можно скачать. На следующем скриншоте представлена страница отчета, которая будет создаваться с использованием шаблона.

Определение переменных

Для секций группировки и суммирования потребуются переменные. Добавим для этих секций переменные sum_group и summa. Кроме этого добавим переменную num, которую будем использовать для нумерации записей в группе. Чтобы добавить переменную необходимо выделить в панели Report Inspector элемент Variables и в контекстном меню, вызываемом нажатием правой клавиши мыши, выбрать пункт меню «Add Variable», как это представлено на следующем скриншоте.

После этого определяем свойства переменной. Для этого выделяем переменную в панели Report Inspector и в панели Properties устанавливаем соответствующие параметры - наименование (Name), тип (Variable Class) и т.д.

В следующей таблице представлен список используемых в шаблоне переменных и их установленные свойства. Все переменные имеют тип java.lang.Integer.

ПеременнаяСвойствоЗначение
cost Variable Class java.lang.Integer
variableExpressionnew Integer($F{quantity}.intValue()*$F{price}.intValue())
summa Variable Classjava.lang.Integer
CalculationSum
Variable Expressionnew Integer($F{quantity}.intValue()*$F{price}.intValue())
sum_group Variable Classjava.lang.Integer
CalculationSum
Reset TypeGroup
Reset GroupState name
Variable Expressionnew Integer($F{quantity}.intValue()*$F{price}.intValue())
num Variable Classjava.lang.Integer
CalculationCount
Reset TypeGroup
Reset GroupState name
Variable Expression$F{item}

Переменная cost используется для вычисления значения одной записи, т.е. только одно значение по горизонтали. Переменные summa и sum_group используются для определения сумм нескольких записей. У переменных cost, summa и sum_group значение параметра Variable Expression идентично - произведение значений двух полей $F{quantity} и $F{price}. Значение параметра Calculation переменных summa и sum_group определено как Sum (из списка). Поскольку переменная sum_group используется только в группе записей, то для нее установлены параметры Reset Type и Reset Group.

Для переменной num, определяющей номер записи в группе, в параметре Calculation выбрано значение Count, определены значения групповых параметров (Reset Type, Reset Group). Подсчет значений (Variable Expression) выполняется для поля $F{item}. Ниже в листинге представлено описание переменных в jrxml-шаблоне.

Листинг переменных - Variables

<variable name="cost" class="java.lang.Integer">
    <variableExpression>
        <![CDATA[
            new Integer($F{quantity}.intValue()*$F{price}.intValue())
        ]]>
    </variableExpression>
</variable>

<variable name="sum_group" class="java.lang.Integer"
                           resetType="Group"
                           resetGroup="State name"
                           calculation="Sum">
    <variableExpression>
        <![CDATA[
            new Integer($F{quantity}.intValue()*$F{price}.intValue())
        ]]>
    </variableExpression>
</variable>

<variable name="summa" class="java.lang.Integer"
                       calculation="Sum">
    <variableExpression>
        <![CDATA[
            new Integer($F{quantity}.intValue()*$F{price}.intValue())
        ]]>
    </variableExpression>
</variable>

<variable name="num" class="java.lang.Integer"
                     resetType="Group"
                     resetGroup="State name"
                     calculation="Count">
    <variableExpression>
        <![CDATA[$F{item}]]>
    </variableExpression>
</variable>

Определение группы

Для создания групповой секции необходимо выделить корневую запись, вызвать контекстное меню и выбрать "Add Report Group".

В результате данного действия iReport откроет «мастера» создания групповой секции. Необходимо на первом шаге определить наименование группы и поле для группировки. Выбираем группировку записей по "штату" $F{stat}.

На следующем шаге устанавливаем обе подсекции группы, которые будем использовать для

  • наименования группы записей - group header, поле $F{stat};
  • вычисления суммы значений - group footer, переменная $V{sum_group}.

Размещаем в секции «group header» поле $F{stat}, а в секции «group footer» - статическое поле (Static Field) "Итого :" и поле «Text Field» с переменной $V{sum_group}. В предыдущей статье была рассказано как разместить в шаблоне компоненты и связать их с переменными.

В результате в панели Report Inspector у нас появились элементы группой секции : «State name Group Header 1» и «State name Group Footer 1».

Групповых секций может быть несколько. Ниже представлен листинг групповой секции в jrxml-шаблоне.

Обрамление компонента

Для обрамления поля используем безымяное окно, открываемое из контекстного меню ("Padding and Borders"). Можно определить толщину и стиль линии обрамления, цвет и сторону компонента.

Листинг групповой секции group - groupHeader, groupFooter

<group name="State name">
    <groupExpression>
        <![CDATA[$F{state}]]>
    </groupExpression>
    <groupHeader>
        <band height="18">
            <textField>
                <reportElement x="69" y="0" width="442" height="18" 
                       uuid="1adc41ce-7c09-46fe-960a-dff145ad7e50"/>
                <box>
                    <topPen    lineWidth="1.0"/>
                    <leftPen   lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen  lineWidth="1.0"/>
                </box>
                <textElement textAlignment="Center"
                             verticalAlignment="Middle">
                    <font size="11" isBold="true" isItalic="false"/>
                    <paragraph leftIndent="10"/>
                </textElement>
                <textFieldExpression>
                    <![CDATA[$F{state}]]>
                </textFieldExpression>
            </textField>
        </band>
    </groupHeader>
    <groupFooter>
        <band height="18">
            <staticText>
                <reportElement mode="Opaque" x="69" y="0" 
                               width="343" height="18"
                               backcolor="#F8F8F8"
                        uuid="97bb96e0-d791-4b78-a952-767f248cfb77"/>
                <box>
                    <pen       lineWidth="1.0"/>
                    <topPen    lineWidth="1.0"/>
                    <leftPen   lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen  lineWidth="1.0"/>
                </box>
                <textElement textAlignment="Right" 
                             verticalAlignment="Middle">
                    <font size="11" isBold="true" isItalic="false"/>
                    <paragraph rightIndent="10"/>
                </textElement>
                <text>
                    <![CDATA[Итого :]]>
                </text>
            </staticText>
            <textField>
                <reportElement mode="Opaque" x="412" y="0"
                               width="99" height="18" 
                               backcolor="#F8F8F8"
                        uuid="990ce7e6-1cb4-43ba-b9e3-cfc5abd0be0e"/>
                <box>
                    <pen       lineWidth="1.0"/>
                    <topPen    lineWidth="1.0"/>
                    <leftPen   lineWidth="1.0"/>
                    <bottomPen lineWidth="1.0"/>
                    <rightPen  lineWidth="1.0"/>
                </box>
                <textElement textAlignment="Right" 
                             verticalAlignment="Middle">
                    <font isBold="true"/>
                    <paragraph rightIndent="5"/>
                </textElement>
                <textFieldExpression>
                    <![CDATA[$V{sum_group}]]>
                </textFieldExpression>
            </textField>
        </band>
    </groupFooter>
</group>

Листинг секции Summary

Добавим в шаблон секцию Summary и разместим в ней статическое поле (Static Field) "Всего :" и переменную $V{sum}; «выделим» компоненты бледно-серым цветом. Как добавить секцию в jrxml-шаблон было рассказано в предыдущей статье.

Ниже в листинге представлена секция Summary.

<summary>
    <band height="18">
        <staticText>
            <reportElement mode="Opaque" x="69" y="0" 
                           width="343" height="18" 
                           backcolor="#F8F8F8"
                        uuid="44add398-f6d7-4075-bbce-1a15e6a10b5a"/>
            <box>
                <pen       lineWidth="1.0"/>
                <topPen    lineWidth="1.0"/>
                <leftPen   lineWidth="1.0"/>
                <bottomPen lineWidth="1.0"/>
                <rightPen  lineWidth="1.0"/>
            </box>
            <textElement textAlignment="Right"
                         verticalAlignment="Middle">
                <font size="11" isBold="true" isItalic="false"/>
                <paragraph rightIndent="10"/>
            </textElement>
            <text><![CDATA[Всего :]]></text>
        </staticText>
        <textField>
            <reportElement mode="Opaque" x="412" y="0"
                           width="99" height="18"
                           backcolor="#F8F8F8"
                        uuid="fb524506-8517-4436-bcfc-90c89d24710a"/>
            <box>
                <pen       lineWidth="1.0"/>
                <topPen    lineWidth="1.0"/>
                <leftPen   lineWidth="1.0"/>
                <bottomPen lineWidth="1.0"/>
                <rightPen  lineWidth="1.0"/>
            </box>
            <textElement textAlignment="Right" verticalAlignment="Middle">
                <font isBold="true"/>
                <paragraph rightIndent="5"/>
            </textElement>
            <textFieldExpression>
                <![CDATA[$V{summa}]]>
            </textFieldExpression>
        </textField>
    </band>
</summary>

В заключение представим интерфейс получившегося jrxml-шаблона.

Скачать пример

Исходные коды примера создания отчета, включающего секции группировки и суммирования данных, с использованием библиотеки JasperReports можно скачать здесь (7.97 Кб).

Пример настройки JDBC в приложении iReport и формирование JasperReport отчета можно увидеть здесь.

  Рейтинг@Mail.ru