jasperreports_JasperReports:棘手的部分

jasperreports

如果您使用Java进行编程的时间足够长,则有可能需要为业务用户生成报告。 就我而言,我已经看到几个项目使用JasperReports®Library来生成PDF和其他文件格式的报告。 最近,我荣幸地观察了Mike和他的团队使用上述报告库以及他们所面临的挑战。

简而言之JasperReports

简而言之,使用JasperReports(JR)生成报告涉及三个步骤:

  1. 加载已编译的报告(即,加载JasperReport对象)
  2. 通过用数据填充报告来运行报告(结果是JasperPrint对象)
  3. 将已填充的报告导出到文件(例如,使用JRPdfExporter导出到PDF)

在Java代码中,看起来像这样。

JasperReport compiledReport = JasperCompileManager.compileReport("sample.jrxml");
Map<String, Object> parameters = ...;
java.sql.Connection connection = dataSource.getConnection();
try {JasperPrint filledReport = JasperFillManager.fillReport(compiledReport, parameters, connection);JasperExportManager.exportReportToPdf(filledReport, "report.pdf");
} finally {connection.close();
}

多亏了facade类,这看起来很简单。 但是外表可能是骗人的!

鉴于以上代码段(以及概述的三个步骤),您认为哪些部分需要最多的时间和内存? (听起来像面试问题)。

如果您回答(#2)填写数据,那是对的! 如果您回答了#3,那也是正确的,因为#3与#2成正比。

恕我直言 ,大多数在线教程仅显示简单的部分。 在JR的情况下,似乎缺少关于较困难和棘手的部分的讨论。 在这里,与Mike的团队一起,我们遇到了两个困难:内存不足错误和长期运行的报告。 使这些困难特别令人难忘的是,它们仅在生产期间出现(而不在开发期间出现)。 我希望通过共享它们,将来可以避免它们。

内存不足错误

第一个挑战是报告内存不足。 在开发过程中,与实际操作数据相比,我们用于运行报告的测试数据将太小。 因此, 为此设计

在我们的例子中,所有报告都使用JRVirtualizer运行。 这样,当达到内存中的页面/对象最大数量时,它将刷新到磁盘/文件。

在此过程中,我们还了解到需要清理虚拟机。 否则,周围会有几个临时文件。 而且,我们只能在报告导出到文件清理这些临时文件。

Map<String, Object> parameters = ...;
JRVirtualizer virtualizer = new JRFileVirtualizer(100);
try {parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);...... filledReport = JasperFillManager.fillReport(compiledReport, parameters, ...);// cannot cleanup virtualizer at this pointJasperExportManager.exportReportToPdf(filledReport, ...);
} finally {virtualizer.cleanup();
}

有关更多信息,请参见Virtualizer Sample – JasperReports 。

请注意,当我们在运行报告时遇到内存不足的错误时,JR 并不总是罪魁祸首。 有时,即使在使用JR之前,我们也会遇到内存不足错误。 我们看到了如何滥用JPA来加载报告的整个数据集( Query.getResultList()TypedQuery.getResultList() )。 同样,由于数据集仍然很小,因此在开发期间不会显示该错误。 但是,当数据集太大而无法容纳在内存中时,我们会遇到内存不足错误。 我们选择避免​​使用JPA生成报告。 我猜我们只需要等待JPA 2.2的Query.getResultStream()可用即可。 我希望JPA的Query.getResultList()返回Iterable 。 这样,就有可能一次映射一个实体,而不是整个结果集。

现在,避免加载整个数据集。 一次加载一个记录。 在此过程中,我们返回了良好的JDBC。 不错,JR很好地使用了ResultSet

长期运行的报告

第二个挑战是长期运行报告。 同样,在开发过程中可能不会发生这种情况。 充其量,将运行10秒钟左右的报告视为冗长。 但是,有了实际的运行数据,它可以运行大约5-10分钟。 当根据HTTP请求生成报告时,这尤其麻烦。 如果报告可以在超时时间段内(通常为60秒或最多5分钟)开始写入响应输出流,那么它很有可能被请求用户(通常是通过浏览器)接收。 但是,如果填写报告需要5分钟以上,而导出到文件又需要8分钟,那么用户将只会看到超时的HTTP请求,并将其记录为错误。 听起来有点熟?

请记住,报告可以运行几分钟。 因此, 为此设计

就我们而言,我们在单独的线程上启动报告。 对于使用HTTP请求触发的报告,我们将以一个包含所生成报告链接的页面作为响应。 这样可以避免超时问题。 当用户单击此链接而报告尚未完成时,他/她将看到仍在生成报告。 但完成的报告时,他/她就可以看到生成的报告文件。

ExecutorService executorService = ...;
... = executorService.submit(() -> {Map<String, Object> parameters = ...;try {...... filledReport = JasperFillManager.fillReport(compiledReport, parameters, ...);JasperExportManager.exportReportToPdf(filledReport, ...);} finally {...}
});

我们还必须添加停止/取消运行报告的功能。 好东西,JR有检查Thread.interrupted()代码。 因此,仅中断线程将使其停止。 当然,您需要编写一些测试来进行验证(期望JRFillInterruptedExceptionExportInterruptedException )。

在讨论的同时,我们重新发现了将“监听器”添加到报告生成中的方法(例如FillListenerJRExportProgressMonitor )并为用户提供一些进度信息。

我们还创建了实用程序测试类,以通过反复重复给定的数据来生成大量数据。 这对帮助团队的其他成员开发专为处理长期运行和内存不足错误而设计的JR应用程序很有用。

进一步的设计考虑

要考虑的另一件事是填写报告时需要打开和关闭所需的资源。 这可以是JDBC连接,Hibernate会话,JPA EntityManager或文件输入流(例如CSV,XML)。 下图是我的设计注意事项的粗略草图。

1. Compiling- - - - - - - - - - - - - -\- - - -\                    \
2. Filling       > open-close         \- - - -/   resource           > swap to file/
3. Exporting                         /- - - - - - - - - - - - - -/

我们想隔离#2并定义装饰器,这些装饰器将打开资源,填充报告并在finally块中关闭打开的资源。 打开的资源可能取决于报表中的<queryString>元素(如果存在)。 在某些情况下,如果没有<queryString>元素,则可能无需打开资源。

<queryString language="hql"><![CDATA[ ... ]]>
</queryString>
...
<queryString language="csv"><![CDATA[ ... ]]>
</queryString>

此外,我们还希望将#2和#3组合为一种抽象。 这种单一的抽象使通过装饰进行装饰变得更加容易,例如将创建的页面对象刷新到文件中,并在导出过程中将其加载回。 如前所述,这是JRVirtualizer工作。 但是,我们希望使用结合#2和#3的抽象对对象透明的设计。

致谢

目前为止就这样了。 再次感谢Mike和他的团队分享了他们的经验。 是的,他是将自己应用的收入捐赠给慈善机构的那个人 。 另外,还要感谢克莱尔(Claire)通过一次又一次重复给定数据进行测试的想法。 相关代码段可以在GitHub上找到 。

翻译自: https://www.javacodegeeks.com/2018/01/jasperreports-tricky-parts.html

jasperreports

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑运行adb闪退_adb+python进阶使用

之前文章有提到过使用python加adb刷视频&#xff0c;今天带来进阶版——无线多台手机。首先要使用adb连接多台手机&#xff0c;手机和电脑肯定要在统一局域网内。1.打开手机开发者模式&#xff0c;并通过USB接口链接电脑。2.打开cmd&#xff1a;输入adb tcpip 5555, 会得到相关…

java office在线编辑_国外10个最受欢迎的 Java 开发的 CMS 系统

CMS是Content Management System的缩写&#xff0c;意为"内容管理系统"&#xff0c;它具有许多基于模板的优秀设计&#xff0c;可以加快网站开发的速度和减少开发的成本。CMS的功能并不只限于文本处理&#xff0c;它也可以处理图片、Flash动画、声像流、图像甚至电子…

apache kafka_Apache Kafka简介

apache kafka什么是Apache Kafka&#xff1f; Apache Kafka是一个分布式流系统&#xff0c;具有发布和订阅记录流的功能。 在另一方面&#xff0c;它是企业消息传递系统。 它是一个快速&#xff0c;水平可扩展和容错的系统。 Kafka有四个核心API&#xff0c; 生产者API&#x…

人脸特征值能存放在sql server中吗_SQL运行内幕:从执行原理看调优的本质

原文链接&#xff1a;https://www.cnblogs.com/arthinking/p/13205303.html相信大家看过无数的MySQL调优经验贴了&#xff0c;会告诉你各种调优手段&#xff0c;如&#xff1a;避免 select *&#xff1b;join字段走索引&#xff1b;慎用in和not in&#xff0c;用exists取代in&a…

rest资源设计_REST资源何时应获得其自己的地址?

rest资源设计在纯粹的REST方法中&#xff0c;所有端点&#xff08;起始端点除外&#xff09;都是不透明的&#xff0c;因此不需要发布其各种详细信息。 即使使用这种方法&#xff0c;本文中的要点也很重要&#xff0c;因为服务器逻辑将必须确定何时需要结束点。 介绍 在REST体…

ckeditor回显带标签_Spring Boot中带有CKEditor的AJAX

ckeditor回显带标签1.概述 在本文中&#xff0c;我们将介绍如何在Spring Boot中使用CKEditor 。 在本教程中&#xff0c;我们将导入一个包含大量数据的XML文档&#xff0c;对使用GET请求将一组数据加载到CKEditor实例的能力进行编程&#xff0c;并执行POST请求以保存CKEditor的…

android 可行性分析,可行性研究项目分析程序与步骤

项目分析程序项目分析分析工作步骤分析程序框架分段实施方法第一阶段初期工作1、收集资料。包括业主的要求&#xff0c;业主已经完成的研究成果&#xff0c;市场、厂址、原料、能源、运输、维修、共用设施、环境、劳动力来源、资金来源、税务、设备材料价格、物价上涨率等有关资…

原码一位乘法器设计_十分钟带你彻底搞懂原码、反码、补码

点击上方“程序员大白”&#xff0c;选择“星标”公众号重磅干货&#xff0c;第一时间送达编辑 | 程序员大白公众号来源丨https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html仅作学术交流&#xff0c;如有侵权&#xff0c;请联系删文本篇文章讲解了计算…

Linux 目录之 /etc/init.d/ 介绍

文章目录一、关于目录 /etc/init.d/二、关于目录 /etc/rc.d/init.d/三、关于文件 /etc/rc.local四、/etc/init.d/ 和 service 文件五、关于命令 service六、关于文件 /etc/inittab七、关于目录 /etc/init/注意&#xff1a;以 System V init 或者 Upstart 为初始化系统的 Linux …

java 异常处理发生异常_处理Java中的异常

java 异常处理发生异常每个程序员都希望编写一个完美的程序。 也就是说&#xff0c;程序运行时没有任何障碍。 好吧&#xff0c;如果希望是马&#xff0c;乞g就会骑。 除了程序员的所有愿望之外&#xff0c;有时还会发生无法预料的情况。 在Java中&#xff0c;这些无法预料的…

android提交项目到svn,Android Studio 配置SVN,通过Share project提交项目和实现忽略文件...

1&#xff1a;首先电脑本身装的SVN必须在bin目录下包含svn.exe文件&#xff0c;如下图。这个文件是在安装SVN时选择安装command line client tools才会出现。如果没有&#xff0c;需要重新安装SVN。2&#xff1a;将SVN关联到Android Studio中声明&#xff1a;在这里我使用的And…

数独游戏技巧从入门到精通_如何引导孩子入门九宫格数独?掌握4个技巧口诀,孩子思维提升快...

九宫格数独对孩子的思维训练有着非常不错的效果&#xff0c;我们完全可以用其培养孩子对数字的兴趣&#xff0c;并培养孩子严谨的逻辑推理态度。那九宫格数独有没有技巧口诀呢&#xff1f;对于孩子来说&#xff0c;过于复杂的技巧他们也掌握不了。所以&#xff0c;我们培养孩子…

Spring Boot和Apache Camel

随着软件世界的发展&#xff0c;正在开发更加复杂的系统&#xff0c;这些系统必须相互集成。 它从SOA开始&#xff0c;然后一直到微服务。 骆驼是我想到的第一大集成工具&#xff0c;因为如今的骆驼springboot是一个非常强大的组合。 第一步是将骆驼依赖项包含到我们的sprin…

苹果android投屏,iphone怎么投屏到mac?苹果手机投屏到苹果电脑方法

iphone和mac的使用人群越来越多,其中投屏功能却难倒了大部分新手用户,许多使用iPhone以及Mac的用户朋友都还不知道iPhone怎么投屏到mac,好奇的用户朋友马上点击查看iphone投屏到mac教程来实现这个具有科技革新感的功能吧。官方推荐方法1&#xff1a;用数据线- 1.使用lightning线…

微服务java模块内存管理_Java 9模块服务

微服务java模块内存管理接线与查找 Java长期以来都有一个ServiceLoader类。 它是在1.6中引入的&#xff0c;但是自Java 1.2以来就使用了类似的技术。 一些软件组件使用了它&#xff0c;但是使用并不广泛。 它可以用于模块化应用程序&#xff08;甚至更多&#xff09;&#xff0…

使用实例工厂方法实例化_一些工厂实例

使用实例工厂方法实例化我时不时地发现自己摸索了一些旧代码&#xff0c;找到了“我在哪里做过类似工厂的事情”的示例。 上周再次发生这种情况时&#xff0c;我决定只查找所有示例&#xff0c;并创建一个示例项目和有关该示例的博客文章。 所以在这篇文章中&#xff0c;我&a…

linux内核设计与实现 epub_Epoll学习服务器的简单实现-Linux内核Epoll结构

1.Begins~有的人学习linux编程很久&#xff0c;只知道网络编程是socket&#xff0c;bind&#xff0c; listen。。。&#xff0c;然而这些都是网络通信软件最基本的接口。在某网络公司待了y&#xff0c;也了解到公司的基础就是网络转发 &#xff0c;然而网络转发实现并非我们平时…

鸿蒙有安卓内核吗,华为鸿蒙2.0可以替代安卓吗,华为鸿蒙2.0优势在哪

在华为开发者大会上&#xff0c;华为消费业务CEO 余承东&#xff0c;正式发布鸿蒙OS2.0&#xff0c;并宣布华为鸿蒙OS将全面启用全场景生态&#xff0c;并将于2020年12月发布手机版。余承东还表示&#xff0c;明年&#xff0c;华为的智能手机将全面升级&#xff0c;以支持鸿蒙操…