1.1. Структура данных отчета
Рассмотрим вкладку Report structure редактора отчета.

В верхней части находятся поля ввода общих свойств отчета:
-
Name - имя отчета. Имя может быть локализовано на вкладке Localization.
-
Group - группа отчетов, применяется для группировки в общем списке браузера отчетов.
-
Default template - шаблон, по которому будет выводиться отчет.
-
System code - необязательный код отчета, по которому его можно при необходимости идентифицировать в программном коде системы.
Основным элементом структуры данных отчета является иерархия полос - Report bands.
Полоса отчета характеризуется следующими параметрами:
-
Band name - уникальное в рамках отчета имя полосы. Должно содержать только латинские буквы, цифры или символ подчеркивания.
-
Orientation - ориентация полосы: Horizontal или Vertical. Горизонтальные полосы в выводимом отчете копируются вниз, вертикальные - вправо. Горизонтальные полосы могут содержать вложенные полосы.
-
Parent band - родительская полоса.
Каждая полоса включает в себя один или несколько наборов данных - Datasets. Наборы данных при выполнении отчета представлют собой списки строк, а каждая строка - набор пар имя-значение. Полоса выводится в отчет столько раз, сколько строк в ее самом длинном наборе данных. Имена полей указываются в шаблоне отчета, и при выводе полосы имена заменяются на соответствующие значения. При описании наборов данных можно использовать внешние параметры отчета, а также поля других полос - это позволяет делать полосы связанными.
В каждом отчете присутствует корневая полоса Root. В ней можно создавать наборы данных и ссылаться на их поля из других полос, однако использовать полосу Root в шаблоне нельзя.
Имя набора данных в колонке Dataset name не имеет значения и служит только для удобства пользователя.
Рассмотрим возможные типы наборов данных.
-
SQL - набор данных формируется выполнением SQL-запроса к базе данных. Поля результирующего набора запроса желательно снабдить алиасами с помощью оператора
as
. Для исключения возможного преобразования базой данных регистра символов алиасы желательно заключить в двойные кавычки:select u.name as "userName", u.login as "userLogin" from sec_user u
В запросе можно использовать входные параметры отчета и поля родительских полос. К параметрам нужно обращаться по имени, заключенному в конструкцию
${}
, например${dateFrom}
. К полям родительской полосы нужно обращаться аналогично, добавляя имя полосы перед именем поля:${band1.field1}
.Пример SQL-запроса с параметром
groupId
, полученным из родительской полосыgroup
, и внешним параметромactive
:select u.name as "userName", u.login as "userLogin" from sec_user u where u.group_id = ${group.groupId} and u.active = ${active} and u.delete_ts is null
WarningВ запросы на SQL необходимо вручную включать условия фильтрации мягко удаленных записей.
По умолчанию SQL-запросы выполняются в основной базе данных. Если необходимо выполнить запрос в дополнительном хранилище данных (см. Руководство по разработке приложений), в поле Data store необходимо указать его имя.
-
JPQL - набор данных формируется выполнением JPQL-запроса к базе данных. Поля результирующего набора запроса необходимо снабдить алиасами с помощью оператора
as
. В JPQL-запросе можно использовать входные параметры отчета и поля родительских полос аналогично описанному для SQL-запроса.Пример JPQL-запроса с параметром
groupId
, полученным из родительской полосыgroup
, и внешним параметромactive
:select u.name as userName, u.login as userLogin from sec$User u where u.group.id = ${group.groupId} and u.active = ${active}
Запросы на JPQL автоматически поддерживают мягкое удаление и возвращают только неудаленные записи.
По умолчанию JPQL-запросы выполняются по сущностям основной базы данных. Если необходимо выполнить запрос к сущностям дополнительного хранилища (см. Руководство по разработке приложений), в поле Data store необходимо указать его имя.
-
Groovy - набор данных формируется выполнением Groovy-скрипта. Скрипт должен возвращать объект типа
List<Map<String, Object>>
. Элемент этого списка, то есть объект типаMap<String, Object>
соответствует одной записи набора данных.В скрипт передаются следующие объекты:
-
params
- мэп внешних параметров отчета. Пример получения значения параметра:def active = params['active']
-
parentBand
- родительская полоса в виде объекта типаcom.haulmont.yarg.structure.BandData
. Через этот объект методомgetParameterValue()
можно получить значение поля родительской полосы, например:def groupId = parentBand.getParameterValue('groupId')
-
persistence
- объект типаcom.haulmont.cuba.core.Persistence
, позволяющий управлять транзакциями и получать ссылку наEntityManager
. Например:def tx = persistence.createTransaction() try { def em = persistence.getEntityManager() def query = em.createQuery('select g from sec$Group g') ... tx.commit() } finally { tx.end() }
Для работы с дополнительным хранилищем данных, его имя нужно указать в параметре методов
createTransaction()
иgetEntityManager()
. По умолчанию используется основная база данных.def tx = persistence.createTransaction('myStore') try { def em = persistence.getEntityManager('myStore') ... tx.commit() } finally { tx.end() }
-
metadata
- объект типаcom.haulmont.cuba.core.global.Metadata
, позволяющий обращаться к метаданным приложения. Например:def metaClass = metadata.getClassNN('sec$User')
-
transactional
- метод, принимающий на вход замыкание, которое нужно выполнить в новой транзакции. Параметром замыкания становится текущийEntityManager
. Пример использования:transactional { em -> def query = em.createQuery('select g from sec$Group g') ... }
TipДля обращения к любым бинам Spring среднего слоя можно использовать статические методы класса
AppBeans
, например:def dataWorker = com.haulmont.cuba.core.global.AppBeans.get('cuba_DataWorker')
Пример Groovy-скрипта извлечения пользователей по группе, выводимой в родительской полосе и по внешнему параметру
active
:def result = [] transactional { em -> def query = em.createQuery('select u from sec$User u where u.group.id = ?1 and u.active = ?2') query.setParameter(1, parentBand.getParameterValue('groupId')) query.setParameter(2, params['active']) query.resultList.each { user -> result.add(['userLogin': user.login, 'userName': user.name]) } } return result
-
-
Entity - набор данных состоит из одной строки и формируется по атрибутам одного экземпляра сущности и связанных с ним сущностей.
Источником данных является внешний параметр типа Entity, который должен быть описан на вкладке Parameters and Formats. Значение в поле Entity parameter name должно соответствовать параметра.
Шаблон отчета должен содержать поля с именами атрибутов сущности. Атрибуты, используемые в шаблоне, необходимо указать в специальном окне, вызываемом кнопкой Entity attributes.
-
List of entities - набор данных формируется по списку экземпляров сущности.
Источником данных является внешний параметр типа List of entities, который должен быть описан на вкладке Parameters and Formats. Значение в поле Entity parameter name должно соответствовать имени параметра.
Шаблон отчета должен содержать поля с именами атрибутов сущности. Атрибуты, используемые в шаблоне, необходимо указать в специальном окне, вызываемом кнопкой Select entity attributes.