воскресенье, 20 апреля 2014 г.

Создание отчетов в ADF при помощи JasperReport

Мало какие приложения  могут обойтись без отчетов. Если есть база и таблица,  то почти всегда нужно  вывести на печать какие то данные. В ADF часто для этого используютcя Jasper Report и iReport. JasperReports — это Java-библиотека для создания отчётов.  iReport  - это среда разработки отчетов.
Создадим отчет ,  который выводит всех сотрудников выбранного  департамента, а в итоговой колонке выводит их среднюю  и общую сумму зарплат.
Начнем.
Скачайте и установите среду разработки  отчетов (http://community.jaspersoft.com/project/ireport-designer)
Запустите установленную среду. Перед тем как мы начнем создавать отчет, нам надо  добавить соединение к бд Oracle. Так как оно не входит в пакет стандартных соединение, нам надо его добавить. Для этого скачайте файл  ojdbc6.jar (  http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html ) и добавьте его в classpath среды (Tools->Options)




 Теперь можно приступить к созданию отчета. Нажмите File->New и выберите Blank A4( пустая страница формата А4).

Дальше необходимо ввести имя файла, и место где оно будет находиться


В следующем окне нужно создать  соединение к БД, для этого нажмите New


Выберите JDBC connection


В появившемся окне введите параметры соединения  к БД.


Нажав Save мы вернемся к окну Query. Соединение настроено, теперь необходимо сделать выборку данных по которым мы составим отчет.Для этого нажмите Design Query, выберите схему в которой находится ваша таблица, перенесите ее на пустое пространство.



На этапе Fields выберите поля, которые будете использовать в отчете


Потом нажмите Next и Finish
Появилось чистое лист с  7ью секциями:
  • Title - название отчета
  • PageHeader -заголовок отчета
  • ColumnHeader - заголовок полей
  • Detail1 - секция для вывода полей
  • Column Footer -  "подвал" полей ( для итоговых значений полей)
  • Page Footer - подвал страницы
  • Summary -Итоговая секция отчета.


Наш отчет должен формироваться по входящему параметру(Номер департамента), значит нам нужно изменить  запрос к БД. Для этого нажмите по картинке подчеркнутой на картинке


Добавим параметр и условие как показано на двух нижних картинках



Теперь можно добавлять данные в отчет. Это делается простым переносом  из FIELD на лист. Перенесите поля для таблицы в секцию Details1.  А те поля по которым нужно подводить итоги( сумма зарплат и средняя зарплата по департаменту) перенесите в  секцию Column Footer. После переноса появится окно. В котором  для суммы выберите в списке Sum, а для средней зарплаты Average. Поля добавлены, теперь им надо дать им имена. Для это в отчет добавляется компонент Static text. Его можно перетянуть из вкладки  Palette(если она у вас не отображается, нажмите Windows->Palette



Как отчет будет готов, нажмите на кнопку Preview и введите департамент. Если вы все правильно выполнили, то сформируется необходимый нам  отчет



Отчет подготовлен, теперь его нужно прикрепить к приложению.  Сделаем это при  помощи сервлета



 Назовем класс ServletRep



В сформированном сервлете замените метода doGet   на наш:        
 
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String type = ""; // тип отчета (pdf,rtf,xls,htl,csv) String filename = ""; //имя файла BigDecimal deptNo=null; // номер департамента try { type = request.getParameter("type"); // вытаскивание параметров из запроса сервлета filename = request.getParameter("filename"); deptNo = new BigDecimal(request.getParameter("deptNo")); response.setContentType(CONTENT_TYPE); InitialContext initialContext = new InitialContext();
// подключение к DataSource, при помощи которого приложение подключается к бд DataSource ds = (DataSource)initialContext.lookup( "jdbc/local"); Connection conn = ds.getConnection();  
//добавление параметров, для передачи их в отчет Map parameters = new HashMap(); parameters.put("deptNoParam",deptNo); HttpSession session = request.getSession(); ServletContext context = session.getServletContext();
//добавление jrxml файла( файл отчета) InputStream input = context.getResourceAsStream("/WEB-INF/report/"+filename+".jrxml");
JasperDesign design = JRXmlLoader.load(input); JasperReport report = JasperCompileManager.compileReport(design); JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, conn); OutputStream ouputStream = response.getOutputStream(); JRExporter exporter = null; if( "pdf".equalsIgnoreCase(type) ) { response.setContentType("application/pdf"); exporter = new JRPdfExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); } else if( "rtf".equalsIgnoreCase(type) ) { response.setContentType("application/rtf"); response.setHeader("Content-Disposition", "inline; filename=\""+filename+".rtf\""); exporter = new JRRtfExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); } else if( "html".equalsIgnoreCase(type) ) { exporter = new JRHtmlExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); } else if( "xls".equalsIgnoreCase(type) ) { response.setContentType("application/xls"); response.setHeader("Content-Disposition", "inline; filename=\""+filename+".xls\""); exporter = new JRXlsExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); } else if( "csv".equalsIgnoreCase(type) ) { response.setContentType("application/csv"); response.setHeader("Content-Disposition", "inline; filename=\""+filename+".csv\""); exporter = new JRCsvExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); } try { exporter.exportReport(); } catch (JRException e) { throw new ServletException(e); } finally { if (ouputStream != null) { try { ouputStream.close(); } catch (IOException ex) { throw (ex); } } } }catch(Exception ex) { ex.printStackTrace(); } }

Код добавлен,  теперь что бы он работал нужно сначала скопировать наш файл отчета(ReportEmp.jrxml)  в папку WEB_INF\report проекта ViewController  и  добавить  в Libary and Classpath проекта ViewController следующие файлы Jasper Report-а ( в зависимости методов работы с jasper report их количество может быть меньше или больше)  :

  •  iText-2.1.7.jar
  • jasperreports-5.0.1.jar
  • jasperreports-fonts-5.0.1.jar

Они находятся (если вы не меняли адрес по умолчанию)  здесь:
C:\Program Files (x86)\Jaspersoft\iReport-5.1.0\ireport\modules\ext

Теперь нужно вызвать сервлет, для этого  добавьте на jspx страниц goButton и в свойстве destination пропишите следующий текст: 

destination="/servletrep?type=xls&deptNo=10&filename=ReportEmp"
где:

  •  /servletrep - вызов сервлета .
  • ? - передача параметров:
  • type - тип файла отчета(pdf,rtf,xls,htl,csv)
  • deptNo - номер департамента
  • filename - имя файла отчета

Готово.  

Примечание. Если вам нужно будет формировать  отчет в формате pdf, то воспользуйтесь этой статьей для добавления  русских шрифтов : http://habrahabr.ru/sandbox/23741/