11.2. Отчёты JasperReports.

В iReport создайте шаблон и сохраните его в директорию reports как <модуль>_<id>.jrxml. Откройте его в iReport.

Для отображения отчёта необходимо получить данные (datasource). Получение данных описывается в шаблоне отчёта, для iReport - это пункт меню Data->Report Query (Запрос Отчёта).

На данный момент возможны два метода получения datasource - SQL и BGBS. В параметре Query language необходимо указать используемый.

SQL-метод используется для отчётов, данные которых можно получить одним запросом.

При этом значения фильтров, переменные конфигурации подставляются в запрос макросами:

$(name) - подставляет текстовое значение, где name - имя фильтра, либо переменная конфигурации модуля;

$mm(name) - подставляет значение месяца вида MM, январь - 01;

$yy(name) - подставляет год вида yyyy;

$date(name) - подставляет дату в формате sql;

$time(name) - подставляет время в формате sql;

$module_month_table(table, name) - подставляет имя таблицы в зависимости от текущего модуля, указанного имени таблицы и даты - параметра фильтра,

т.е $module_month_table( log_session , date ) , если фильтр date="01.01.2008", а текущий модуль 1 подставит log_session_1_200801;

$month_table - тоже самое без идентификатора модуля, т.е, например log_session_200801;

При построении запроса можно установить соединение с базой и, используя статические данные вместо макросов значений фильтров, проверить запрос и получить имена и типы полей отчёта. Промежуточные и итоговые значения (сумма, счётчик, максимум, минимум) можно указать для подсчёта в variables - параметр Calculation Type, а в Variable Expression указать макрос поля (например $F{col2}). Если одного запроса для построения отчёта не достаточно? то можно воспользоваться скриптом - в Query language укажите bgbs, а в поле запроса должна быть конструкция вида

import java.sql.*;
import java.util.*;

public void fillReport( con, filter, result )
{
   //код для получения datasource

   result.setParams( params ); //установка параметров, которые будут доступны в отчёте (Parameters) - объект интерфейса Map
   result.setDataSource( datasource ); //установка datasource, это может быть объект интерфейса Collection<Map<String, Object>>, ResultSet
}

con - объект класса java.sql.Connection - соединение с базой данных;

filter - объект класса bitel.billing.server.admin.reports.BGReportFilter, содержащий параметры фильтра, переменные конфигурации модуля отчётов. Краткий перечень доступных функций (полный - в API-документации для разработки скриптов BGBS):

String getStringParam( String name )

int getIntParam( String name )
int getIntParam( String name, int def )

long getLongParam( String name )
long getLongParam( String name, long def )

Calendar getCalendarParam( String name )
Date getDateParam( String name )

result - объект, в который необходимо передать параметры отчёта и datasource. У него имеются функции:

void setDataSource( JRDataSource dataSource )
void setDataSource( Collection<Map<String, Object>> dataSource )
void setDataSource( ResultSet dataSource )

void setParams( Map params )

JRDataSource createDataSource( ResultSet dataSource ) //создание объекта datasource из ResultSet
JRDataSource createDataSource( Collection<Map<String, Object>> dataSource ) //создание объекта datasource из коллекции Map

String sql( String sql, BGReportFilter filter ) //преобразование строки запроса с помощью шаблонов
// (преобразование аналогично sql варианту получения данных)

В параметрах (Parameters) отчёта должны быть определены параметры _filter и _months с соответствующими снимку экрана ниже типами:

Пример шаблона отчёта "Отчет наработки по услугам":

Файл kernel_report.rep.xml

<?xml version="1.0" encoding="UTF-8"?>
<report title="Мой отчёт по наработке">
  <month name="month" title="Месяц"/>
  <contractGroups name="gr" title="Группы договоров"/>
</report>

При использовании типа запроса SQL: Query language - SQL, сам запрос:

SELECT t3.title as col1, SUM(t1.summa) as col2 FROM contract_account AS t1,  contract AS t2, service AS t3 
WHERE t1.cid=t2.id AND t1.sid=t3.id 
AND t2.gr&$(gr)>0
AND t1.yy=$yy(month) AND t1.mm=$mm(month)
GROUP BY t1.sid ORDER BY t3.mid, t3.title

Здесь макросы $() будут заменены на соответствующие значения фильтра, т.е month и gr.

При использовании типа запроса BGBS: Query language - BGBS, запрос:

import java.sql.*;
import java.util.*;

public void fillReport( con, filter, result )
{
  PreparedStatement ps = con.prepareStatement( result.sql( "SELECT t3.title as col1," +
  " SUM(t1.summa) as col2 FROM contract_account AS t1,  contract AS t2, service AS t3"+
  " WHERE t1.cid=t2.id AND t1.sid=t3.id AND t2.gr&$(gr)>0 AND t1.yy=$yy(month) AND"+
  " t1.mm=$mm(month) GROUP BY t1.sid ORDER BY t3.mid, t3.title", filter ) );

  ResultSet rs = ps.executeQuery();
  result.setDataSource( rs );
}

запрос использующий Collection<Map>:

import java.sql.*;
import java.util.*;

public void fillReport( con, filter, result )
{
  PreparedStatement ps = con.prepareStatement( result.sql( "SELECT t3.title as col1," +
  " SUM(t1.summa) as col2 FROM contract_account AS t1,  contract AS t2, service AS t3"+
  " WHERE t1.cid=t2.id AND t1.sid=t3.id AND t2.gr&$(gr)>0 AND t1.yy=$yy(month) AND"+
  " t1.mm=$mm(month) GROUP BY t1.sid ORDER BY t3.mid, t3.title", filter ) );

  ResultSet rs = ps.executeQuery();

  double total = 0;
  List res = new ArrayList();
  while(rs.next())
  {
    Map  map = new HashMap();
    map.put("col1", rs.getString(1));
    double val = rs.getDouble(2);
    map.put("col2", val);
    total += val;

    res.add(map);
  }

  Map params = new HashMap();
  params.put( "total", total );

  result.setDataSource( res );
  result.setParams( params );
}

Для отображения в отчёте даты отчёта добавляем textfield с Expression Class: java.util.Date, Pattern: год: yyyy месяц: MMMMM, Expression: $P{_filter}.getDateParam( "month" ).

Подсчёт итогового значения предоставим отчёту, добавив variable sum c Class Type java.lang.Double, Calculation Type Sum, Variable Expression $F{col2}.

Добавим текстовое поле для его отображения, Expression Class java.lang.Double, Pattern # ##0.00, Text Field Expression $V{sum}.

iReport вместе с вариантом данного примера: ftp://bgbilling.ru/pub/bgbilling/reports/iReport_1.3.2.zip

Другие примеры отчётов доступны на Wiki. Наиболее простой способ разработки собственного отчёта - модификация существующего. Также некоторые отчёты, идущие в стандартной поставке (например, отчёт по должникам) могут быть изменены.

Имеется возможность в отчёте использовать гиперссылки. Это позволяет из одного отчёта быстро открывать другие связанные отчёты или разные сущности системы, например, договоры. Можно использовать отчёты как "универсальный поиск" - формируем любые фильтры и логику поиска, связываем строки результата с отрываемыми договорами и можно получить список договоров по любому критерию с возможностью открыть нужный. На данный момент поддерживаются следующие типы ссылок:

Можно указывать глобальные настройки для библиотеки jasperreports в файле jasperreports.properties, путь к которому можно указать с помощью параметра запуска сервера ( server.sh/server.bat):

-Dnet.sf.jasperreports.properties=/path/jasperreports.properties

Значения опции вы можете узнать в документации библиотеки jasperreports.