因项目需要,研究了下Jasperreports 5.0.4与Spring MVC 3的集成方法。在查资料的时候网上有个类似的集成方案,但是并非最新版本,而且他的代码居然都是写在JSP上的,都用Spring mvc了,还写在jsp上,太扯淡(Spring本身提供了对jasperreports的支持)。
以下为spring mvc原先的视图解析器配置:
1 | < bean |
2 | class = "org.springframework.web.servlet.view.InternalResourceViewResolver" > |
3 | < property name = "order" value = "1" /> |
4 | < property name = "prefix" value = "/jsp/" /> |
5 | < property name = "suffix" value = ".jsp" /> |
6 | </ bean > |
在此基础上添加jasperreports视图解析器的配置信息:
01 | < bean id = "jasperReportsViewResolver" class = "org.springframework.web.servlet.view.jasperreports.JasperReportsViewResolver" > |
02 | < property name = "order" value = "0" /> <!-- 视图渲染优先级,此处为0,优先于渲染JSP --> |
03 | < property name = "viewClass" value = "me.digdata.report.view.DigDataJasperReportsView" /> <!-- 自定义视图渲染类,继承于JasperReportsMultiFormatView --> |
04 | < property name = "prefix" value = "/WEB-INF/classes/report/" /> <!-- 报表模板路径 --> |
05 | < property name = "suffix" value = ".jasper" /> <!-- 模板后缀 --> |
06 | < property name = "viewNames" value = "*-report" /> <!-- 试图渲染所有以"-report"结尾的视图名(viewName) --> |
07 | < property name = "cache" value = "true" /> <!-- 缓存模板(false时,每次请求都会重新加载模板,建议debug模板时设置为false) --> |
08 | < property name = "jdbcDataSource" ref = "dataSource" /> <!-- 指定数据源 --> |
09 | < property name = "exporterParameters" > <!-- 渲染时的相关参数 --> |
10 | < map > |
11 | < entry key = "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI" value = "images/" /> <!-- HTML时的白色背景图片(px)路径 --> |
12 | < entry key = "net.sf.jasperreports.engine.export.JRHtmlExporterParameter.CHARACTER_ENCODING" value = "UTF-8" /> |
13 | </ map > |
14 | </ property > |
15 | </ bean > |
其中,me.digdata.report.view.DigDataJasperReportsView代码如下:
01 | public class DigDataJasperReportsView extends JasperReportsMultiFormatView { |
02 | public static final String ATTACHEMT_FILE_NAME_KEY = "attachmentFileName" ; //格式不为html时的下载文件名 |
03 | |
04 | @Override |
05 | protected void renderReport(JasperPrint populatedReport, |
06 | Map<String, Object> model, HttpServletResponse response) |
07 | throws Exception { |
08 | // TODO Auto-generated method stub |
09 | Object format = model.get(DEFAULT_FORMAT_KEY); |
10 | if (format== null ){ |
11 | throw new IllegalArgumentException( "model中未找到指定的输出格式(format:html、pdf、xls、csv)" ); |
12 | } |
13 | if (!format.equals( "html" )){ |
14 | Object attachmentFileName = model.get(ATTACHEMT_FILE_NAME_KEY); |
15 | if (attachmentFileName== null ){ |
16 | throw new IllegalArgumentException( "model中未指定输出文件名(attachmentFileName)" ); |
17 | } |
18 | Properties contentDispositionMappings = getContentDispositionMappings(); |
19 | contentDispositionMappings.put(format.toString(), "attachment; filename=" +attachmentFileName+ "." +format); |
20 | } |
21 | super .renderReport(populatedReport, model, response); |
22 | } |
23 | } |
于是,可像正常的调用Controller里的方法一样,实现HTML、PDF、EXCEL、CSV等报表功能,类似代码如下(Controller里的某个方法):
01 | /** |
02 | * 显示html、下载pdf、xls、cvs等报表<br> |
03 | * 请求链接必须带有reportName参数,用以指定模板名<br> |
04 | * 请求链接必须带有format参数,用以指定生成的格式(html、pdf、xls、csv) |
05 | * @param reportEntity 报表相关参数 |
06 | * @param format |
07 | * @return |
08 | */ |
09 | @RequestMapping (value = "/show_report.html" ) |
10 | public ModelAndView showReport(ReportEntity reportEntity){ |
11 | ModelAndView mv = new ModelAndView(); |
12 | Date now = new Date(); |
13 | mv.setViewName(reportEntity.getReportName()); //要调用的jasperreports的模板文件名(不包括后缀),该文件名必须以-report结尾 |
14 | mv.addObject(DigDataJasperReportsView.DEFAULT_FORMAT_KEY, reportEntity.getFormat()); //显示格式:html、pdf、xls、csv |
15 | mv.addObject(DigDataJasperReportsView.ATTACHEMT_FILE_NAME_KEY, Tools.date2Str(now, "yyyyMMddHHmmss" )); //当为pdf、xls、csv时的附件名 |
16 | Map<String,Object> params = convertParams(reportEntity); |
17 | mv.addAllObjects(params); |
18 | return mv; |
19 | } |
其中,ReportEntity代码如下:
01 | public class ReportEntity { |
02 | private String reportName; //要调用的jasperreports的模板文件名(不包括后缀),该文件名必须以-report结尾 |
03 | private String format; //显示格式:html、pdf、xls、csv |
04 | public String getReportName() { |
05 | return reportName; |
06 | } |
07 | public void setReportName(String reportName) { |
08 | this .reportName = reportName; |
09 | } |
10 | public String getFormat() { |
11 | return format; |
12 | } |
13 | public void setFormat(String format) { |
14 | this .format = format; |
15 | } |
16 | } |
放上基于maven构建的项目demo源码:下载链接
为解决中文字体在PDF不显示问题,需要将源码包中的iTextAsian-1.0.jar安装到本地maven仓库中,maven命令如下:mvn install:install-file -Dfile=iTextAsian-1.0.jar -DgroupId=com.lowagie.text -DartifactId=iTextAsian -Dversion=1.0 -Dpackaging=jar
由于本demo采用了h2数据库,所有项目启动正常后,请在地址栏输入:http://localhost:8080/report/console,其中,JDBC URL:一栏输入jdbc:h2:~/report,点连接后,将源码包下的src\main\resources\schema.sql demo数据导入进去。
运行demo效果如下: