[Анализ и проектирование систем, IT-компании] Работа с отчетностью в системе управления данными
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Всем привет! В этой статье мы хотим рассказать о том, каким образом мы в платформе Unidata формируем отчетность. Любая работа с данными неизбежно ведет к построению специализированных отчетов, в которых пользователи могут эффективно эти данные обрабатывать и принимать на их основе бизнес-решения.Как выбирали систему построения отчетностиСоздавать модуль построения отчетов в платформе – задача нетривиальная и дорогостоящая, поэтому возникла необходимость поиска подходящего инструментария для построения отчетов. Главными нашими критериями были:
- Бесплатное использование ПО в коммерческих проектах с открытым исходным кодом
- Инструмент для построения данных должен работать с основными форматами источников данных, а так же напрямую БД.
- Использование языка Java для построения отчетов
- ПО должно быть поддерживаемым и обновляемым c поддержкой обратной совместимости
- Редактор построения отчетов должен быть удобным и понятным
- Инструмент должен позволять создавать шаблоны отчетов всех основных форматов: excel, csv, pdf, html, и т.д
- Богатые возможности визуализации и построения дашбордов.
Мы провели исследование части наиболее известных open-source систем построения отчетов, и результаты нашего исследование мы собрали в таблицу, которой хотим поделиться.НаименованиеПроизводительЛицензияВозможности и достоинстваНедостаткиBIRTThe Business Intelligence and Reporting Tools (BIRT)Eclipse FoundationEclipse Public LicenseПоследняя версия 4.5.0 (Июнь 24, 2015) т.е. проект живой;Есть визуальный редактор отчетов в среде разработки Eclipse IDE;Сконструированные отчеты BIRT сохраняются в XML и имеют доступ к целому ряду различных источников данных, включая хранилище данных JDO, JFire, Plain Old Java Object, SQL, database, Web Service и XML;Содержит технологию построения графиков, которая полностью интегрирована в дизайнер отчетов и может использоваться автономно для интеграции графиков в приложение;Много документации;Сырой и неудобный редактор;Ставится отдельным web-приложением;Для использования необходим Eclipse;Отчеты, созданные в разных версиях несовместимы;JasperReportsJaspersoftGNU Lesser General Public LicenseПоследняя версия 6.2.2 (6 мая 2016 года)отчёты могут выводиться на экран, принтер, либо в форматы PDF, RTF,HTML, XLS, CSV и XML;Использование динамических языков JavaScript и Groovy при реализации логики отчета;Реализация диаграмм (charts) на основе библиотеки JFreeChart;Реализация подотчётов (subreports) с неограниченной глубиной вложенности;Реализация кросстаблиц (crosstabs);Pentaho Reporting JFreeReport Project CorporationPentaho Community Edition (CE): Apache version 2.x; Pentaho Enterprise Edition (EE): Commercial LicenseГибкое позиционирование элементов дашборда на макете;Развитые инструменты визуализации отчетов;Возможность вывода отчетов в форматах HTML, Excel, csv, xml, PDF, текстовых форматах;Мало информации о применении;Все основные фичи реализованы в коммерческой версии от Hitachi Group Company;YARGCUBAApache 2.0 LicenseГенерировать отчет в формате шаблона или конвертировать результат в PDF;Создавать шаблоны отчетов в привычных и распространенных форматах: DOC, ODT, XLS, DOCX,XLSX, HTML;Создавать сложные XLS и XLSX шаблоны: с вложенными областями данных, графиками, формулами и т.д.;Использовать в отчетах изображения и HTML-разметку;Хранить структуру отчетов в формате XML;Запускать standalone приложение для генерации отчетов, что делает возможным использование библиотеки вне Java-экосистемы (например для генерации отчетов в PHP);Интегрироваться с IoC-фреймворками (Spring, Guice).Нет внятного редактора;Есть UI, который предоставляет платформа CUBA;Как видно из нашего небольшого исследования, наиболее подходящим инструментом для нас стал JasperReports. В пользу этого open-source инструмента говорит наличие весьма удобного визуального редактора проектирования отчетов, богатого набора визуализаций, включая кросстаблицы, а самое главное - наличие REST API. Проектирование макетов отчетов в JasperReports не требует особых глубоких знаний, а результаты проекта сохраняются в xml-формат. Так же мы ориентируемся на опыт коллег, например, наши партнеры КРОК в своей статье https://habr.com/ru/company/croc/blog/244085/ рекомендуют использовать Jasper. «JasperSoft наибольшим образом подходит для построения фиксированной отчетности. Интересны любой компании, которой необходимы инструменты анализа данных». Конечно, у jasper есть определенные проблемы, когда требуется сделать гибкий шаблон, например, когда необходимо сделать гибкий вывод полей в таблице, но в нашей практике мы сталкиваемся как правило с фиксированными отчетами, которые обозначает заказчик.Взаимодействие клиент-сервер с Jasper reportsМы полагаем, что может быть интересным то, как именно мы встраиваем jasper отчеты непосредственно в платформу без лишних запросов к Jasper Server. JasperReports Server – это основной компонент системы. Его задача - хранить отчеты, которые будут встраиваться в платформу, а так же предоставлять возможность просмотра отчетов напрямую через специальный интерфейс. Вот пример как это выглядит в платформе
При построении отчетов наша задача состоит в том, чтобы получить от пользователя параметры отчета, собрать на основе переданных параметров данные из источников, построить визуализацию данных, и готовую визуализацию данных интегрировать в виде iframe на интерфейс или выгрузить в файл. Описание данного механизма представлена ниже на схеме.
Для того, чтобы получить отчет необходима авторизация в Jasper Server. Авторизация происходит путем передачи пары логин/пароль, а в ответ Jasper создает сессию и сохраняет session_id в куках. В обычном случае для того, чтобы напрямую взаимодействовать с JasperServer из JavaScript, нам необходимо авторизоваться, получить session_id из куки и запросить сам отчет. Однако на практике мы столкнулись с проблемой, что в случае использования кластера серверов с дублированием Jasper на всех инстансах, jasper отчеты то доступны, то недоступны для пользователя. Проблема заключается в том, что балансировщик, получив запрос от клиента, запрашивает ответ с разных JasperServer, но использует session_id только одного инстанса . То есть мы авторизовались в JasperServer на первом инстансе, получили от него session_id, затем c этим же session_id мы идем на другой инстанс и получаем ошибку доступа «с сообщением «Авторизуйтесь на JasperServer». Для решения этой задачи мы используем специальный проксировщик, который по сути является расширением бэкэнда платформы и устанавливается на все ноды кластера. Так как проксировщик установлен на том же сервере, что и Jasper server, ему нет необходимости обращаться по IP к ноде, а достаточно обратиться по localhost. Таким образом, балансировщик, передавая запрос от клиента на ту или иную ноду, запрашивает у проксировщика авторизацию уже на месте и гарантировано Jasper Server вернет ответ. Ниже представлен код проксировщика.
public Response getJasperReport(@QueryParam("url") String url) throws UnsupportedEncodingException {
url = url.replaceAll(";;", "&").replaceAll(" ","%20").replaceAll(""","%22");
Client client = ClientBuilder.newClient();
Response authResponse = client
.target(jasperUrlLogin)
.queryParam("j_username", jasperLogin)
.queryParam("j_password", jasperPassword)
.request()
.header("Content-Type", "application/x-www-form-urlencoded")
.header("charset", "utf-8")
.post(Entity.json(""));
NewCookie sessionIdCookie = null;
if (authResponse.getStatus() == 200) {
Map<String, NewCookie> cookies = authResponse.getCookies();
sessionIdCookie = cookies.get("JSESSIONID");
} else {
LOGGER.warn("Cant auth JasperServer");
return null;
}
String requestUrl = jasperReportUrl + url;
Response response = client
.target(requestUrl)
.request()
.cookie(sessionIdCookie)
.header("Content-Type", "text/html")
.get();
return response;
}
Проксировщик получает на вход некий URL отчета, который собирается из параметров на клиенте. По этому URL происходит авторизация в jasperServer, далее проксировщик достает из куки session_id и уже по нему запрашивает ответ непосредственно самого отчета. Ответ от jasper приходит виде html-страницы. Именно эту html-страницу мы передаем в iframe для отрисовки на клиенте, а не url, как это обычно бывает. Таким образом мы один раз запрашиваем отчет, далее вся работа с ним идет уже непосредственно на клиенте платформы.Создаем Iframe
{
xtype: 'component',
margin: '20 0 0 0',
reference: 'report',
maxWidth: 1200,
height:485,
autoEl: {
tag: 'iframe',
src: '',
frameBorder: 0,
marginWidth: 0,
},
listeners: {
load: {
element: 'el',
fn: function () {
var panel = this.getParent().component;
panel.setLoading(false, panel.body);
}
}
}
}
Подкладываем html страницу от Jasper Server
generateReport: function () {
var report_url = this.generateReportUrl('html');
if (report_url) {
var panel = this.view;
panel.setLoading(true, panel.body);
this.getHtmlAndUpdateReport(report_url);
}
}
generateReportUrl - метод, который генерирует URL с нужными параметрами для отчета и session_id.Cоздание отчета в JasperReportsДалее поговорим про непосредственно создание отчетов и дашбордов в Jasper. Создание jasper отчета состоит из набора визуализаций, скомпонованных на едином макете: Для создания макета отчета мы используем визуальный редактор JasperSoft Studio, который может быть отдельным приложением или плагином для eclipse. Подробнее об этом инструменте можно легко найти информацию в документации и открытых источниках, Нам же важно выделить то, что в данном редакторе достаточно легко можно построить дашборд, а сам редактор достаточно удобен и понятен. Достаточно выбрать нужные визуализации, перетащить их на макет, заполнить параметры и функциональные элементы. Построение дашбордов не требует навыков программирования и каждый может разобраться с ними в достаточно короткое время. Ниже пример простого отчета в JasperStudio.
После того, как создали макет отчета, переходим к построению логики самого отчета. Jasper отчет представляет xml-файл в специальном формате jrxml. Структура jrxml файла условно можно поделить на три части: в первой части определяются параметры отчета, во второй части пишется запрос к данным, в третьей части описываются функциональные блоки макета, в которых происходит обработка результатов запроса и отображение данных в макете.Начало структуры файла: пример параметров отчета
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.9.0.final using JasperReports Library version 6.9.0-cb8f9004be492ccc537180b49c026951f4220bf3 -->
<jasperReport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://jasperreports.sourceforge.net/jasperreports" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="pubsub_diagram" pageWidth="1150" pageHeight="550" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e8ef4a20-ab26-44c0-8b4d-316411f7d350">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="postgres_local.xml"/>
<property name="net.sf.jasperreports.export.xls.ignore.graphics" value="false"/>
<parameter name="date_from_param" class="java.lang.String"/>
<parameter name="date_to_param" class="java.lang.String"/>
<parameter name="systems_param" class="java.util.Collection"/>
<parameter name="status_param" class="java.util.Collection"/>
<parameter name="entities_param" class="java.util.Collection"/>
<parameter name="count_details_param" class="java.lang.Integer"/>
<parameter name="group_param" class="java.lang.String"/>
Далее предположим, что источником данных является во второй части после параметров пишем SQL-запрос
<queryString>
<![CDATA[SELECT * FROM (
Cnjbn with main_table AS
(SELECT T3.status as status, count(T3.id) as count_status, (count(T3.id) / (to_date($P{date_to_param}, 'DD_MM_YYYY') - to_date($P{date_from_param}, 'DD_MM_YYYY') + 1)) as avg_count_status FROM
(SELECT T1.id,T2.status
FROM public.history
AS T1
LEFT JOIN
(SELECT DISTINCT ON (history_id) history_id, status FROM public.track
WHERE createdate >= to_date($P{date_from_param}, 'DD_MM_YYYY')
AND DATE(createdate) <= to_date($P{date_to_param}, 'DD_MM_YYYY')
ORDER BY history_id, createdate DESC NULLS LAST
) AS T2
ON T1.id = T2.history_id
WHERE T2.status IS NOT NULL
AND $X{IN,T1.unidatasourcesystem, systems_param} AND $X{IN,T1.entity, entities_param}
AND T1.createdate >= to_date($P{date_from_param}, 'DD_MM_YYYY')
AND DATE(T1.createdate) <= to_date($P{date_to_param}, 'DD_MM_YYYY')
AND $X{IN,T2.status, status_param}
) AS T3
GROUP BY T3.status)
SELECT main_table.*, round((count_status * 100) / (SELECT SUM(count_status) FROM main_table), 2) AS percent_status FROM main_table
) AS t_result order by status]]>
</queryString>
Стоит обратить внимание, что в запросе мы используем параметры $P{date_to_param}, которые динамически приходят от клиента, что так же является фишкой Jasper.Далее описывается тело всего отчета по функциональным разделам. Подробнее о описании всех разделов можно найти в документации. Ниже пример как это может выглядеть
<columnHeader>
<band height="35">
<staticText>
<reportElement x="0" y="0" width="150" height="30" uuid="1972f653-13ec-41b8-987a-a1f25940e053"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12" isBold="true"/>
</textElement>
<text><![CDATA[Статус]]></text>
</staticText>
<staticText>
<reportElement x="150" y="0" width="150" height="30" uuid="bde4e86c-d3d8-4538-a278-44eae4cda528"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12" isBold="true"/>
</textElement>
<text><![CDATA[Количество сообщений]]></text>
</staticText>
<staticText>
<reportElement x="300" y="0" width="160" height="30" uuid="ab26081d-2c0b-45b3-8c43-5707e2b555e7"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12" isBold="true"/>
</textElement>
<text><![CDATA[Среднее в день]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="35" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="150" height="30" uuid="ea66974c-f627-4096-86c3-fc0f921a88d2"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$F{status}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="150" y="0" width="150" height="30" uuid="a820021d-95d6-4ee5-a5a4-887aca484efb"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$F{count_status}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="300" y="0" width="160" height="30" uuid="e7927fa9-5b8f-43ff-bea7-1d74d8a3ce27"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$F{avg_count_status}]]></textFieldExpression>
</textField>
</band>
</detail>
<summary>
<band height="370">
<staticText>
<reportElement x="0" y="0" width="150" height="30" uuid="d93b83c8-b168-4766-91d8-b9545e3239a7"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12" isBold="true"/>
</textElement>
<text><![CDATA[ИТОГО]]></text>
</staticText>
<textField>
<reportElement x="150" y="0" width="150" height="30" uuid="6e306a81-3522-437d-a973-0dcf8646aa5f"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$V{sum_status}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="300" y="0" width="160" height="30" uuid="67d24b52-4d3e-47ae-a35d-dc98a9b230f5"/>
<textElement textAlignment="Center" verticalAlignment="Middle">
<font fontName="Arial" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$V{sum_avg_count_status}]]></textFieldExpression>
</textField>
<pieChart>
<chart evaluationTime="Report">
<reportElement x="0" y="40" width="400" height="320" uuid="bf9f29b3-51c1-472d-822b-e7e4b20fa160"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend/>
</chart>
<pieDataset>
<keyExpression><![CDATA[$F{status}]]></keyExpression>
<valueExpression><![CDATA[$F{count_status}]]></valueExpression>
<labelExpression><![CDATA["" + $F{percent_status} + "% " + $F{status}]]></labelExpression>
</pieDataset>
<piePlot>
<plot>
<seriesColor seriesOrder="0" color="#33F54A"/>
<seriesColor seriesOrder="1" color="#EB73C1"/>
<seriesColor seriesOrder="2" color="#433DF2"/>
<seriesColor seriesOrder="3" color="#FAEC52"/>
<seriesColor seriesOrder="4" color="#FFC342"/>
<seriesColor seriesOrder="5" color="#D9D2D8"/>
<seriesColor seriesOrder="6" color="#DE522F"/>
</plot>
<itemLabel/>
</piePlot>
</pieChart>
</band>
</summary>
Отдельно стоит отметить еще одну полезную функцию Jasper отчетов - это наличие подотчетов. В случае, когда мы хотим переиспользовать какой-либо отчет в другом отчете с тем же параметрами, нам не нужно писать с нуля, а достаточно обраться к готовому отчету по его идентификатору, передав новые значения параметров
<subreport>
<reportElement x="460" y="40" width="650" height="320" uuid="e0d58e35-b1da-4bcc-9978-fbda3028ff5a"/>
<subreportParameter name="date_from_param">
<subreportParameterExpression><![CDATA[$P{date_from_param}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="date_to_param">
<subreportParameterExpression><![CDATA[$P{date_to_param}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="systems_param">
<subreportParameterExpression><![CDATA[$P{systems_param}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="status_param">
<subreportParameterExpression><![CDATA[$P{status_param}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="entities_param">
<subreportParameterExpression><![CDATA[$P{entities_param}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="group_param">
<subreportParameterExpression><![CDATA[$P{group_param}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["repo:pubsub_grapf.jrxml"]]></subreportExpression>
</subreport>
Ключевым вопросом в построении отчета является передача параметров (фильтров) отчета от клиента на сервер. Для того, чтобы не отправлять пользователя на JasperServer и все параметры отчета заполнять в платформе удобным способом, Jasper предлагает использовать собственный REST API. Наличие такого мощного API было решающим аргументом в сторону выбора JasperSoft для автоматизации отчетности. Вместо того, чтобы создавать ресурсы и заполнять параметры в среде Jasper Server мы просто воспользуемся методами, которое предоставляет нам API и передадим параметры GET-запросом от клиента. API jasper позволяет не только параметризировать данные, используемые в отчетах, но и сами отчеты, что позволяет очень гибко отображать нужные дашбордыИтогоРезюмируя все выше описанное мы рекомендуем к использованию JasperSoft когда есть потребность в создании гибких отчетов согласно шаблонам заказчика. Для этого Jasper предоставляет весь необходимый инструментарий, а работать в ним достаточно просто и удобно.
===========
Источник:
habr.com
===========
Похожие новости:
- [Финансы в IT, IT-компании] За год карантина выручка OnlyFans выросла на 553%
- [JavaScript, ReactJS, TypeScript] Как готовить микрофронтенды в Webpack 5
- [Космонавтика, IT-компании] Blue Origin Джеффа Безоса намерена оспорить контракт НАСА со SpaceX на $2,9 млрд
- [Java] Что такое ExecutorService?
- [JavaScript, Интерфейсы, Natural Language Processing, Голосовые интерфейсы] От дизайна до разработки: как делать качественные смартапы для виртуальных ассистентов Салют
- [IT-инфраструктура, Карьера в IT-индустрии, IT-компании] Project Manager: кто такой, зачем он нужен работодателям и как им стать?
- [Управление e-commerce, Бизнес-модели, IT-компании] «Сбер» переименовал маркетплейс goods.ru в «СберМегаМаркет»
- [JavaScript, ReactJS] Как мы решили проблемы с z-index
- [Программирование, Java, Компиляторы] Передача и вызов лямбд на сервере и отказаться от docker/deploy/…
- [Облачные сервисы, Софт, IT-компании] «Яндекс» запустил сервис «Документы»
Теги для поиска: #_analiz_i_proektirovanie_sistem (Анализ и проектирование систем), #_itkompanii (IT-компании), #_java, #_javascript, #_jasperreports, #_otchetnost (отчетность), #_dannye (данные), #_blog_kompanii_junidata (
Блог компании Юнидата
), #_analiz_i_proektirovanie_sistem (
Анализ и проектирование систем
), #_itkompanii (
IT-компании
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 03:11
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Всем привет! В этой статье мы хотим рассказать о том, каким образом мы в платформе Unidata формируем отчетность. Любая работа с данными неизбежно ведет к построению специализированных отчетов, в которых пользователи могут эффективно эти данные обрабатывать и принимать на их основе бизнес-решения.Как выбирали систему построения отчетностиСоздавать модуль построения отчетов в платформе – задача нетривиальная и дорогостоящая, поэтому возникла необходимость поиска подходящего инструментария для построения отчетов. Главными нашими критериями были:
При построении отчетов наша задача состоит в том, чтобы получить от пользователя параметры отчета, собрать на основе переданных параметров данные из источников, построить визуализацию данных, и готовую визуализацию данных интегрировать в виде iframe на интерфейс или выгрузить в файл. Описание данного механизма представлена ниже на схеме. Для того, чтобы получить отчет необходима авторизация в Jasper Server. Авторизация происходит путем передачи пары логин/пароль, а в ответ Jasper создает сессию и сохраняет session_id в куках. В обычном случае для того, чтобы напрямую взаимодействовать с JasperServer из JavaScript, нам необходимо авторизоваться, получить session_id из куки и запросить сам отчет. Однако на практике мы столкнулись с проблемой, что в случае использования кластера серверов с дублированием Jasper на всех инстансах, jasper отчеты то доступны, то недоступны для пользователя. Проблема заключается в том, что балансировщик, получив запрос от клиента, запрашивает ответ с разных JasperServer, но использует session_id только одного инстанса . То есть мы авторизовались в JasperServer на первом инстансе, получили от него session_id, затем c этим же session_id мы идем на другой инстанс и получаем ошибку доступа «с сообщением «Авторизуйтесь на JasperServer». Для решения этой задачи мы используем специальный проксировщик, который по сути является расширением бэкэнда платформы и устанавливается на все ноды кластера. Так как проксировщик установлен на том же сервере, что и Jasper server, ему нет необходимости обращаться по IP к ноде, а достаточно обратиться по localhost. Таким образом, балансировщик, передавая запрос от клиента на ту или иную ноду, запрашивает у проксировщика авторизацию уже на месте и гарантировано Jasper Server вернет ответ. Ниже представлен код проксировщика. public Response getJasperReport(@QueryParam("url") String url) throws UnsupportedEncodingException {
url = url.replaceAll(";;", "&").replaceAll(" ","%20").replaceAll(""","%22"); Client client = ClientBuilder.newClient(); Response authResponse = client .target(jasperUrlLogin) .queryParam("j_username", jasperLogin) .queryParam("j_password", jasperPassword) .request() .header("Content-Type", "application/x-www-form-urlencoded") .header("charset", "utf-8") .post(Entity.json("")); NewCookie sessionIdCookie = null; if (authResponse.getStatus() == 200) { Map<String, NewCookie> cookies = authResponse.getCookies(); sessionIdCookie = cookies.get("JSESSIONID"); } else { LOGGER.warn("Cant auth JasperServer"); return null; } String requestUrl = jasperReportUrl + url; Response response = client .target(requestUrl) .request() .cookie(sessionIdCookie) .header("Content-Type", "text/html") .get(); return response; } {
xtype: 'component', margin: '20 0 0 0', reference: 'report', maxWidth: 1200, height:485, autoEl: { tag: 'iframe', src: '', frameBorder: 0, marginWidth: 0, }, listeners: { load: { element: 'el', fn: function () { var panel = this.getParent().component; panel.setLoading(false, panel.body); } } } } generateReport: function () {
var report_url = this.generateReportUrl('html'); if (report_url) { var panel = this.view; panel.setLoading(true, panel.body); this.getHtmlAndUpdateReport(report_url); } } После того, как создали макет отчета, переходим к построению логики самого отчета. Jasper отчет представляет xml-файл в специальном формате jrxml. Структура jrxml файла условно можно поделить на три части: в первой части определяются параметры отчета, во второй части пишется запрос к данным, в третьей части описываются функциональные блоки макета, в которых происходит обработка результатов запроса и отображение данных в макете.Начало структуры файла: пример параметров отчета <?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.9.0.final using JasperReports Library version 6.9.0-cb8f9004be492ccc537180b49c026951f4220bf3 --> <jasperReport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://jasperreports.sourceforge.net/jasperreports" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="pubsub_diagram" pageWidth="1150" pageHeight="550" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e8ef4a20-ab26-44c0-8b4d-316411f7d350"> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="postgres_local.xml"/> <property name="net.sf.jasperreports.export.xls.ignore.graphics" value="false"/> <parameter name="date_from_param" class="java.lang.String"/> <parameter name="date_to_param" class="java.lang.String"/> <parameter name="systems_param" class="java.util.Collection"/> <parameter name="status_param" class="java.util.Collection"/> <parameter name="entities_param" class="java.util.Collection"/> <parameter name="count_details_param" class="java.lang.Integer"/> <parameter name="group_param" class="java.lang.String"/> <queryString>
<![CDATA[SELECT * FROM ( Cnjbn with main_table AS (SELECT T3.status as status, count(T3.id) as count_status, (count(T3.id) / (to_date($P{date_to_param}, 'DD_MM_YYYY') - to_date($P{date_from_param}, 'DD_MM_YYYY') + 1)) as avg_count_status FROM (SELECT T1.id,T2.status FROM public.history AS T1 LEFT JOIN (SELECT DISTINCT ON (history_id) history_id, status FROM public.track WHERE createdate >= to_date($P{date_from_param}, 'DD_MM_YYYY') AND DATE(createdate) <= to_date($P{date_to_param}, 'DD_MM_YYYY') ORDER BY history_id, createdate DESC NULLS LAST ) AS T2 ON T1.id = T2.history_id WHERE T2.status IS NOT NULL AND $X{IN,T1.unidatasourcesystem, systems_param} AND $X{IN,T1.entity, entities_param} AND T1.createdate >= to_date($P{date_from_param}, 'DD_MM_YYYY') AND DATE(T1.createdate) <= to_date($P{date_to_param}, 'DD_MM_YYYY') AND $X{IN,T2.status, status_param} ) AS T3 GROUP BY T3.status) SELECT main_table.*, round((count_status * 100) / (SELECT SUM(count_status) FROM main_table), 2) AS percent_status FROM main_table ) AS t_result order by status]]> </queryString> <columnHeader>
<band height="35"> <staticText> <reportElement x="0" y="0" width="150" height="30" uuid="1972f653-13ec-41b8-987a-a1f25940e053"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12" isBold="true"/> </textElement> <text><![CDATA[Статус]]></text> </staticText> <staticText> <reportElement x="150" y="0" width="150" height="30" uuid="bde4e86c-d3d8-4538-a278-44eae4cda528"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12" isBold="true"/> </textElement> <text><![CDATA[Количество сообщений]]></text> </staticText> <staticText> <reportElement x="300" y="0" width="160" height="30" uuid="ab26081d-2c0b-45b3-8c43-5707e2b555e7"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12" isBold="true"/> </textElement> <text><![CDATA[Среднее в день]]></text> </staticText> </band> </columnHeader> <detail> <band height="35" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="150" height="30" uuid="ea66974c-f627-4096-86c3-fc0f921a88d2"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12"/> </textElement> <textFieldExpression><![CDATA[$F{status}]]></textFieldExpression> </textField> <textField> <reportElement x="150" y="0" width="150" height="30" uuid="a820021d-95d6-4ee5-a5a4-887aca484efb"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12"/> </textElement> <textFieldExpression><![CDATA[$F{count_status}]]></textFieldExpression> </textField> <textField> <reportElement x="300" y="0" width="160" height="30" uuid="e7927fa9-5b8f-43ff-bea7-1d74d8a3ce27"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12"/> </textElement> <textFieldExpression><![CDATA[$F{avg_count_status}]]></textFieldExpression> </textField> </band> </detail> <summary> <band height="370"> <staticText> <reportElement x="0" y="0" width="150" height="30" uuid="d93b83c8-b168-4766-91d8-b9545e3239a7"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12" isBold="true"/> </textElement> <text><![CDATA[ИТОГО]]></text> </staticText> <textField> <reportElement x="150" y="0" width="150" height="30" uuid="6e306a81-3522-437d-a973-0dcf8646aa5f"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12"/> </textElement> <textFieldExpression><![CDATA[$V{sum_status}]]></textFieldExpression> </textField> <textField> <reportElement x="300" y="0" width="160" height="30" uuid="67d24b52-4d3e-47ae-a35d-dc98a9b230f5"/> <textElement textAlignment="Center" verticalAlignment="Middle"> <font fontName="Arial" size="12"/> </textElement> <textFieldExpression><![CDATA[$V{sum_avg_count_status}]]></textFieldExpression> </textField> <pieChart> <chart evaluationTime="Report"> <reportElement x="0" y="40" width="400" height="320" uuid="bf9f29b3-51c1-472d-822b-e7e4b20fa160"/> <chartTitle/> <chartSubtitle/> <chartLegend/> </chart> <pieDataset> <keyExpression><![CDATA[$F{status}]]></keyExpression> <valueExpression><![CDATA[$F{count_status}]]></valueExpression> <labelExpression><![CDATA["" + $F{percent_status} + "% " + $F{status}]]></labelExpression> </pieDataset> <piePlot> <plot> <seriesColor seriesOrder="0" color="#33F54A"/> <seriesColor seriesOrder="1" color="#EB73C1"/> <seriesColor seriesOrder="2" color="#433DF2"/> <seriesColor seriesOrder="3" color="#FAEC52"/> <seriesColor seriesOrder="4" color="#FFC342"/> <seriesColor seriesOrder="5" color="#D9D2D8"/> <seriesColor seriesOrder="6" color="#DE522F"/> </plot> <itemLabel/> </piePlot> </pieChart> </band> </summary> <subreport>
<reportElement x="460" y="40" width="650" height="320" uuid="e0d58e35-b1da-4bcc-9978-fbda3028ff5a"/> <subreportParameter name="date_from_param"> <subreportParameterExpression><![CDATA[$P{date_from_param}]]></subreportParameterExpression> </subreportParameter> <subreportParameter name="date_to_param"> <subreportParameterExpression><![CDATA[$P{date_to_param}]]></subreportParameterExpression> </subreportParameter> <subreportParameter name="systems_param"> <subreportParameterExpression><![CDATA[$P{systems_param}]]></subreportParameterExpression> </subreportParameter> <subreportParameter name="status_param"> <subreportParameterExpression><![CDATA[$P{status_param}]]></subreportParameterExpression> </subreportParameter> <subreportParameter name="entities_param"> <subreportParameterExpression><![CDATA[$P{entities_param}]]></subreportParameterExpression> </subreportParameter> <subreportParameter name="group_param"> <subreportParameterExpression><![CDATA[$P{group_param}]]></subreportParameterExpression> </subreportParameter> <connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression> <subreportExpression><![CDATA["repo:pubsub_grapf.jrxml"]]></subreportExpression> </subreport> =========== Источник: habr.com =========== Похожие новости:
Блог компании Юнидата ), #_analiz_i_proektirovanie_sistem ( Анализ и проектирование систем ), #_itkompanii ( IT-компании ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 03:11
Часовой пояс: UTC + 5