前言
本人也是ireport的初学者,因此本教程仅针对初次使用ireport制作Web报表的小白,希望起到一些小小的帮助。
一、环境搭建
1、 SSM框架的搭建(略)
2、 引入依赖Jar包
我这边是通过Maven管理Jar包的,只需将其复制进你的pom文件即可。
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>5.6.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.2.2</version>
</dependency>
3、下载iReportDesigner(V5.6.0)点击打开链接
解压后点击bin目录下的ireport.exe即可使用
安装iReportDesigner时有一点需要特变注意,如果点击ireport.exe之后出现闪退的情况,说明是你的jdk没有配置好,请打开etc目录下面的ireport.conf文件
更改图中相应位置为你自己的jdk安装目录即可(!!!注意,亲测jdk1.8不支持,本文档用的是jdk1.7版本)
二、使用iReport设计报表模板
1、打开刚刚下载好的iReport,选择文件-->new-->report 新建一个空的模板
2、建立iReport与数据库的连接(此步骤需要数据库驱动依赖)
选择JDBC connection
选择对应数据库的驱动、连接字符串以及用户名密码
点击Test 提示测试成功
3、建立模板与数据库表之间的联系
点击这个按钮
在新出来的页面的相应位置输入正确的SQL语句,正常情况下,下面会显示对应表的字段信息
点击ok,返回主界面这时候发现在模板的左边选项中Fields选项下面多了一些跟数据库字段名一致的东西
接下来就可以设计你的报表模板了,关于模板的设计百度上多的是我就不多说了。设计好模板之后,点击文件-->另存为,即可保存该模板的.jrxml文件,点击下图中的编译按钮即可得到模板的二进制文件.jasper
然后将这两个文件都拷贝至\WEB-INF\jasper目录下:
三、SpringMvc与 JasperReport整合
下面部分内容转自 记录的习惯 大神的一篇帖子SpringMVC与iReport(JasperReports) 5.6整合开发实例。
1、继承JasperReportsMultiFormatView类,并重写fillReport()方法,在该方法中增加setUrl()实现,这样就可以在controller中指定要使用的报表模板文件了。这样做的好处是,只需要一个jasperReport配置文件,可以在controller中动态的设定报表模板url。
package com.pes_soft.example;
import java.util.Map;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView;
/**
* SpringMVC + IReport整合 视图处理扩展
* @Author Jzc0816
* @Create 2015-11-7 21:38:18 */ public class ApplicationIReportView extends JasperReportsMultiFormatView { private JasperReport jasperReport; public ApplicationIReportView() { super(); } protected JasperPrint fillReport(Map<String, Object> model) throws Exception { if (model.containsKey("url")) { setUrl(String.valueOf(model.get("url"))); this.jasperReport = loadReport(); } return super.fillReport(model); } protected JasperReport getReport() { return this.jasperReport; } }
2、在/WEB-INF/jasper/目录下创建报表视图配置文件jasper-defs.xml,并指定解析器类为自定义的视图解析器类:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="iReportView" class="com.pes_soft.example.ApplicationIReportView">
<!-- <property name="url" value="/WEB-INF/jasper/report2.jasper"/> -->
<property name="reportDataKey" value="jrMainDataSource"/>
</bean>
</beans>
3、Jasper报表的渲染需要用到XmlViewResolver视图解析器,这样你的项目中就会存在多个视图解析器。需要注意的是,项目中如果使用了多个视图解析器,则需要设置order的值来区分解析器的使用顺序,order值越小则越靠前。增加XmlViewResolver视图解析器的同时,并指定其要解析的配置文件路径。那么,需要在Spring MVC配置文件中假入以下配置:
<!-- 注册XmlViewResolver,用于iReport & JasperReports报表生成 -->
<beans:bean id="jasperReportResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<beans:property name="order">
<beans:value>0</beans:value>
</beans:property>
<beans:property name="location">
<beans:value>WEB-INF/jasper/jasper-defs.xml</beans:value>
</beans:property>
</beans:bean>
四、开始测试
1、根据数据库表字段创建实体类
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ylz.dao.CatalogMapper;
import com.ylz.dao.UsersMapper;
/***
*
* @author Jzc0816
*
*/
public class Catalog {
private Integer id;
private String name;
private String long_code;
private Integer parent_id;
private Byte is_delete;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public String getLong_code() {
return long_code;
}
public void setLong_code(String long_code) {
this.long_code = long_code == null ? null : long_code.trim();
}
public Integer getParent_id() {
return parent_id;
}
public void setParent_id(Integer parent_id) {
this.parent_id = parent_id;
}
public Byte getIs_delete() {
return is_delete;
}
public void setIs_delete(Byte is_delete) {
this.is_delete = is_delete;
}
public Catalog() {
// TODO Auto-generated constructor stub
}
public Catalog(Integer id, String name, String long_code, Integer parent_id, Byte is_delete) {
super();
this.id = id;
this.name = name;
this.long_code = long_code;
this.parent_id = parent_id;
this.is_delete = is_delete;
}
@Override
public String toString() {
return "Catalog [id=" + id + ", name=" + name + ", long_code=" + long_code + ", parent_id=" + parent_id
+ ", is_delete=" + is_delete + "]";
}
/***
* 通过mybatis查询所有记录并返回一个集合
* @return
*/
public static List<Catalog> getList() {
List<Catalog> list = new ArrayList<Catalog>();
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml", "mybatis-config.xml");
CatalogMapper cm = null;
cm = context.getBean(CatalogMapper.class);
list = cm.getAll();
return list;
}
}
2、编写Controller方法
/**
* 返回iReport报表视图
* @param model
* @return
*/
@RequestMapping(value = "/report", method = RequestMethod.GET)
public String report(Model model) {
// 报表数据源
JRDataSource jrDataSource = new JRBeanCollectionDataSource(JavaBeanPerson.getList());
// 动态指定报表模板url
model.addAttribute("url", "/WEB-INF/jasper/MvcIReportExample.jasper");
model.addAttribute("format", "pdf"); // 报表格式
model.addAttribute("jrMainDataSource", jrDataSource);
return "iReportView"; // 对应jasper-defs.xml中的bean id
}
运行效果
BUG分析
Bug1:这是最让我头疼的一个异常,我找遍了每一行代码,都没有发现问题,最终在谷歌上发现了其中的猫腻
其实问题不是出在我的代码上,我是被iReport给坑了一波,请看下图:
原来问题出在这个扯淡的字段描述上,这句代码会把我们的字段名描述为“”,当然会报异常了。
在iReport中把.jrxml文件中所有<fieldDescription><![CDATA[]]></fieldDescription>这样的代码给删除掉,然后重新编译后,把这两个文件再次拷贝到/WEB-INF/jasper/,你会惊喜的发现恢复正常了?
什么鬼?为啥有一列是空的?
别紧张,先在iReport中预览一些报表
你会发现在iReport中它是正常的,只不过在Web上它没显示出含有中文内容的那一列而已。
再次回到iReport,调整那一列的属性<Pdf Font name>和<Pdf Encoding>两项参数:
然后在项目POM文件中添加itextasian依赖:
<!-- iReport PDF中文支持 -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itextasian</artifactId>
<version>2.1.7.js2</version>
</dependency>
这时,在重新编译模板文件拷贝到项目中,重新运行
至此,大功告成!!!