Отчёты 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. Наиболее простой способ разработки собственного отчёта - модификация существующего. Также некоторые отчёты, идущие в стандартной поставке (например, отчёт по должникам) могут быть изменены.
Имеется возможность в отчёте использовать гиперссылки. Это позволяет из одного отчёта быстро открывать другие связанные отчёты или разные сущности системы, например, договоры. Можно использовать отчёты как "универсальный поиск" - формируем любые фильтры и логику поиска, связываем строки результата с отрываемыми договорами и можно получить список договоров по любому критерию с возможностью открыть нужный. На данный момент поддерживаются следующие типы ссылок:
bgbilling:reports://bitel.billing.module.services.reports.BGReportsPanel?param1=value1¶m2=value2&... для открытия любого другого отчёта. Для этого нужно знать соответствующие параметры метода Report модуля reports (код отчёта и т. д.).
bgbilling:reports://bitel.billing.module.contract.ContractEditor?<cid> для открытия вкладки с соответствующим договором.
Можно указывать глобальные настройки для библиотеки jasperreports в файле jasperreports.properties, путь к которому можно указать с помощью параметра запуска сервера ( server.sh/server.bat):
-Dnet.sf.jasperreports.properties=/path/jasperreports.properties
Значения опции вы можете узнать в документации библиотеки jasperreports.