В среде Java разработки JasperReports фактически стандартный генератор отчётов. Он позволяет создавать отчёты различной сложности и экспортировать их в большое количество форматов, включая html. Но есть одна тонкость. Эта тонкость описана в стандартной документации, которую можно скачать с официального сайта. Но далеко не все её читают, к сожалению. Мне недавно пришлось править один проект, в котором уже довольно долго стояла проблема генерации отчётов с диаграммами в html, но не была решена.
Проблема в следующем. HTML документ — это обычный текстовый документ с разметкой. Он не содержит в себе картинок. Внутри этого документа будут лишь теги <img src=… Но чтобы они работали нужно немного настроить проект.
В файл web.xml нужно добавить сервлет:
1 2 3 4 5 6 7 8 9 |
<servlet> <servlet-name>image</servlet-name> <servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>image</servlet-name> <url-pattern>/reports/image</url-pattern> </servlet-mapping> |
Этот сервлет будет отдавать сгенерированные картинки и диаграммы.
Затем в коде генерации отчёта нужно указать ImageHandler как net.sf.jasperreports.web.util.WebHtmlResourceHandler, инициализированный с указанием адреса на наш /reports/image. Также нужно сохранить объект jasperPrint в параметр сессии net.sf.jasperreports.j2ee.jasper_print (указан константой ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE).
Вот как примерно это будет выглядеть в коде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Получаем HttpServletRequest request и HttpServletResponse response // InputStream is = ... инициализируем ссылкой на файл *.jrxml // DataSource dataSource = ... наш источник данных // Map<String, Object> parameters = new HashMap<String, Object>() // Заполнение parameters. // Компиляция JasperReport jasperReport = JasperCompileManager.compileReport(is); // Заполнение данными JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource.getConnection()); // Экспорт в HTML ByteArrayOutputStream baos = new ByteArrayOutputStream(); HtmlExporter exporter = new HtmlExporter(); SimpleHtmlExporterOutput htmlExporterOutput = new SimpleHtmlExporterOutput(baos, "UTF-8"); String[] uriParts = request.getRequestURI().split("/"); WebHtmlResourceHandler imageHandler = new WebHtmlResourceHandler( "/" + uriParts[1] + "/reports/image?image={0}"); htmlExporterOutput.setImageHandler(imageHandler); exporter.setExporterOutput(htmlExporterOutput); exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint); exporter.exportReport(); // Теперь baos содержит сгенерированный отчёт. Можно отдать его пользователю. response.setContentType("text/html;charset=UTF-8") response.setContentLength(body.length); OutputStream outputStream = response.getOutputStream(); outputStream.write(body); |
В дистрибутиве JasperReports есть подробный пример. Смотрите по пути:
demo/samples/webapp/WEB-INF/classes/servlets/HtmlServlet.java
Ссылки.
Документация JasperReports:
http://community.jaspersoft.com/documentation?version=15786
Дистрибутив JasperReports:
http://community.jaspersoft.com/project/jasperreports-library/releases
Если у меня существует уже изображение и доступ к нему есть через другой уже существующий сервлет. Могу ли я просто «в тупую» указать параметр src для изображений?
Я так ещё ни разу не делал, по крайней мере. Может и есть какой-нибудь способ.