2019独角兽企业重金招聘Python工程师标准>>>

项目原因需要在springmvc的基础上整合jasperreports生成报表。其实springmvc已经提供了对jasperreports的支持,感觉springmvc采用的一个比较好的方式是将报表的生成作为一个view处理,但是需要对每一种报表配置他的jasperreports模板及视图的映射,这样的话添加报表必须变更配置,比较麻烦,所以自己想了一个方法来避免这种配置,代码可以很容易和spring整合起来。

japserreports生成报表基本流程其实就是根据一个模板和数据源生成一个中间类型,然后可以在此基础上可以导出几种格式。我的想法是提供方法供springmvc的controller调用产生中间文件,然后在view里面向客户端导出请求的格式。

首先是ReportPrint类,很简单,只是包含一个JasperPrint对象(既上述的中间文件),代码很简单,不解释

public class ReportPrint {JasperPrint jasperPrint = null;public JasperPrint getJasperPrint() {return jasperPrint;}public void setJasperPrint(JasperPrint jasperPrint) {this.jasperPrint = jasperPrint;}}

接下来就是ReportCreater类,该类可通过spring注入到其他类中,调用它的createReport方法

public class ReportCreater {private static final Log logger = LogFactory.getLog(ReportCreater.class);private String jasperReportPath = null;//报表的模板文件存放路径(相对classpath,通过spring注入)/*** jasperDesignMap作为一个缓存来存储编译后的JasperReport模板*/private Map<String, JasperReport> jasperDesignMap = new ConcurrentHashMap<String, JasperReport>();public void resetJasperDesignCache() {jasperDesignMap.clear();}/*** controller调用该方法来产生ReportPrint对象*/public ReportPrint createReport(final String reportKey, final ResultSet rs, Map<String, ?> reportParams) throws ReportException {try {return _createReport(reportKey, rs, reportParams);} catch (JRException e) {logger.error(null, e);throw new ReportException("产生报表出错" + reportKey);}}private ReportPrint _createReport(final String reportKey, final ResultSet rs, Map<String, ?> reportParams) throws ReportException, JRException {JasperReport jasperReport = getJasperReport(reportKey);     ReportPrint reportPrint = new ReportPrint();JRResultSetDataSource resultSetDataSource = new JRResultSetDataSource(rs);JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, reportParams, resultSetDataSource);reportPrint.setJasperPrint(jasperPrint);return reportPrint;}private JasperReport getJasperReport(final String reportKey) {try {return _getJasperReport(reportKey);} catch (IOException e) {logger.error(null, e);throw new ReportException("关闭文件流异常:" + reportKey);} catch (JRException e) {logger.error(null, e);throw new ReportException("产生报表异常:" + reportKey);}}private JasperReport _getJasperReport(final String reportKey) throws IOException, JRException {JasperReport jasperReport = null;if (jasperDesignMap.containsKey(reportKey)) {jasperReport = jasperDesignMap.get(reportKey);} else {jasperReport = getJasperReportFromFile(final String reportKey);jasperDesignMap.put(reportKey, jasperReport);}return jasperReport;}/*** 从模板文件编译获得模板对象*/private JasperReport getJasperReportFromFile(final String reportKey)  throws IOException, JRException {String filePath = jasperReportPath + reportKey + ".jrxml";//图省事只支持jrxml的InputStream jasperFileIS = null;JasperReport jasperReport = null;try {jasperFileIS = this.getClass().getClassLoader().getResourceAsStream(filePath);if (jasperFileIS == null) {throw new ReportException("报表文件不存在:" + filePath);}JasperDesign jasperDesign = JRXmlLoader.load(jasperFileIS);jasperReport = JasperCompileManager.compileReport(jasperDesign);} finally {if (jasperFileIS != null) {jasperFileIS.close();}}return jasperReport;}public String getJasperReportPath() {return jasperReportPath;}public void setJasperReportPath(String jasperReportPath) {this.jasperReportPath = jasperReportPath;}public static void main(String[] argv) {}}

以上就可以产生中间文件了,接下来就是按照spring的view规范写一个导出各种格式的视图就可以了

public class ReportView extends AbstractView  {private static final Log logger = LogFactory.getLog(ReportView.class);private static final String XLS = "xls";private static final String PDF = "pdf";private static final String CSV = "csv";private static final String REPORT_NAME = "reportName";private static final String FORMAT = "format";private static final String REPORT_PRINT = "reportPrint";private static final String HTML = "html";private static Map<String, IReportFileExporter> EXPORTER_MAP =new HashMap<String, IReportFileExporter>(4);static {EXPORTER_MAP.put(XLS, new ReportXlsExporter());EXPORTER_MAP.put(PDF, new ReportPdfExporter());EXPORTER_MAP.put(CSV, new ReportCsvExporter());EXPORTER_MAP.put(HTML, new ReportHtmlExporter());}@Overrideprotected void renderMergedOutputModel(Map model, HttpServletRequest request,HttpServletResponse response) {String reportName = (String) model.get(REPORT_NAME);//报表的文件名String format = (String) model.get(FORMAT);//报表的格式pdf xls .....ReportPrint reportPrint = (ReportPrint) model.get(REPORT_PRINT);//这就是之前生成的中间文件response.setContentType("application/x-msdown;charset=utf-8");try {/* http头里的文件名貌似不支持utf-8,gbk之类的编码,需要转换一下* 另外发现如果用new String(reportName.getBytes("UTF-8"), "iso-8859-1")的话Chrome和FF的* 下载对话框的文件名是正常的,IE却是乱码,只能用GBK才正常*/response.setHeader("Content-Disposition","attachment;filename=\"" + new String(reportName.getBytes("GBK"), "iso-8859-1") + "\"");} catch (UnsupportedEncodingException e) {logger.error(null, e);}exportFile(reportPrint, format, response);}private void exportFile(ReportPrint reportPrint, String format, HttpServletResponse response) {try {_exportFile(reportPrint, format, response);} catch (JRException e) {logger.error("导出报表异常", e);} catch (IOException e) {logger.error(null, e);}}private void _exportFile(ReportPrint reportPrint, String format, HttpServletResponse response) throws IOException, JRException {OutputStream buffOS = null;try {buffOS = new BufferedOutputStream(response.getOutputStream());IReportFileExporter exporter = null;if (EXPORTER_MAP.containsKey(format)) {exporter = EXPORTER_MAP.get(format);//获取需要格式的导出类exporter.export(reportPrint, buffOS);} else {logger.error("错误的报表格式:" + format);}} finally {if (buffOS != null) {buffOS.close();}}}}

导出器是一个简单的接口,各种格式只要实现export方法就可以了

public interface IReportFileExporter {public void export(ReportPrint reportPrint, OutputStream os) throws JRException;
}

给一个导出PDF格式的例子,很简单

public class ReportPdfExporter implements IReportFileExporter {public void export(ReportPrint reportPrint, OutputStream os) throws JRException {JRPdfExporter exporter = new JRPdfExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, reportPrint.getJasperPrint());exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, os);exporter.exportReport();}}

差不多久这样了,完整的代码已经上传。

转载于:https://my.oschina.net/onethin/blog/14360

Springmvc与jasperreport结合生成报表的一种方法相关推荐

  1. java生成PDF的几种方法

    问题场景 总结一下用java生成PDF的方法: A.itext-PdfStamper pdfStamper(俗称抠模板) B.itext-Document document(正常代码撰写) C.wkh ...

  2. java 生成随机数_Java 生成随机数的 N 种方法

    原标题:Java 生成随机数的 N 种方法 www.baeldung.com/java-generating-random-numbers 1.引言 本文将探讨用 Java 生成随机数的不同方法. 2 ...

  3. PHP生成随机密码的4种方法及性能对比

    PHP生成随机密码的4种方法及性能对比 http://www.php100.com/html/it/biancheng/2015/0422/8926.html 来源:露兜博客   时间:2015-04 ...

  4. 在word文档中如何自动生成目录,两种方法制作目录,总有一种适合你

    在word文档中如何自动生成目录,两种方法制作目录,总有一种适合你 目录 在word文档中如何自动生成目录,两种方法制作目录,总有一种适合你 1.文章中的标题较多,每个单独调整格式太费劲,这里我们用一 ...

  5. 前端面试题:使用css生成田字格的四种方法

    使用css生成田字格的四种方法 html结构 css基础样式 第一种 flex布局 第二种 绝对定位 第三种 css瀑布流 第四种 float浮动 html结构 <div class=" ...

  6. C++生成GUID的两种方法

    C++生成GUID的两种方法 C++生成GUID的两种方法 使用CoCreateGuid函数 使用Boost库 C++生成GUID的两种方法 GUID是软件开发中常用的组件,用于生成唯一的对象,在C# ...

  7. 用word2007自动生成目录的两种方法

                                用word2007自动生成目录的两种方法 看到很多人还在手工编写word的目录,感觉很浪费时间,下面跟大家分享一下,在word2007及word ...

  8. java生成验证码的三种方法

    java生成验证码的三种方法 第一种:导入jar包com.github.axet生成法 ①导包 <dependency><groupId>com.github.axet< ...

  9. python生成随机数方法_详解用python生成随机数的几种方法

    今天学习了用python生成仿真数据的一些基本方法和技巧,写成博客和大家分享一下. 本篇博客主要讲解如何从给定参数的的正态分布/均匀分布中生成随机数以及如何以给定概率从数字列表抽取某数字或从区间列表的 ...

  10. php 生成excel表格,PHP 生成Excel表格两种方法

    1.使用PHP header()函数  (向浏览器输出Excel,即通过浏览器方式,下载生成的excel) 实例: /** * PHP 使用heade()函数生成excel表格  ExcelName为 ...

最新文章

  1. 新年总结:2018年,是我妈最快乐的一年
  2. nginx win 启动关闭_windows下Nginx启动、关闭、重启bat工具
  3. servlet上传代码
  4. Python Django 表单类Form(py代码画form表单仅渲染页面)
  5. 79. Word Search 单词搜索
  6. (王道408考研操作系统)第二章进程管理-第三节4:信号量机制(整型、记录型信号量和P、V操作)
  7. leetcode题解62-不同路径
  8. SQL Server 2008支持将数据导出为 insert into 的脚本
  9. 现实世界的Windows Azure:采访Gizmox 研发中心的副总裁Itzik Spitzen先生
  10. 打造金刚不坏之心的秘籍
  11. Mac下使用Docker快速搭建pinpont追踪系统APM
  12. nnie yolov3 svp
  13. 计算机音乐狂浪乐谱,当代歌曲 - 听海(流行歌曲 简谱)
  14. coreldraw16开三折页_cdr怎么制作三折页?cdrX6制作三折页模板教程
  15. 金晨想在无人车上劈叉,撒贝宁与数字祝融号对话…这届百度世界大会,有被惊艳到...
  16. 别踩白块游戏java项目总结_学习小游戏别踩白块总结
  17. mscorsvw.exe关闭方法
  18. win7虚拟机iso文件
  19. 互联网时光穿梭机WayBack Machine
  20. luogu P2124 奶牛美容

热门文章

  1. idea输出目录详解
  2. 20180602_Eclipse配置Maven的本地仓库和阿里云镜像
  3. javascript 的线程问题
  4. ASP.NET MVC 分部视图
  5. DataGridView 与货币管理器的位置关联的行不能设置为不可见
  6. Objective-C语法之集合对象的那些事儿(九)
  7. Nginx 常见应用技术指南
  8. 深入浅出node.js游戏服务器开发1——基础架构与框架介绍
  9. P1589 - 【NOI2009】植物大战僵尸
  10. POJ 2739 Sum of Consecutive Prime Numbers 难度:0