那些年我用ireport爬过的坑

最近使用ireport整合项目框架,并且使用PDF打印,遇到了很多坑,也学到了很多东西,所以特意来总结一番,也让其他人少走点弯路;

开发工具:Ireport 5.1.0,JDK7,eclipe,jasperReport6.1

ireport模板使用:

可以参考一下我上一篇转载的博客http://blog.csdn.net/liaodehong/article/details/51175917;

ireport的坑:

PDF不显示中文,或者乱码;

点击打开链接

ireport报错:

我们看XML里面生成的field;

<field name="traceId" class="java.lang.String">
		<fieldDescription><![CDATA[追溯号]]></fieldDescription>
	</field>

记得把 fieldDescription 给去掉,不然用java生成报表的时候会报错;

ireport日期格式的问题:

点击日期找到属性里面的

那些年我用ireport爬过的坑_第1张图片

pattern可以格式化属性;然后再去修改一下XML里面的配置

<field name="docArrivalDate" class="java.sql.Timestamp"/>

把这个改成java.util.Date,不然再后面会出现一些日期转换的问题;

ireport之编写表格:

编写表格有两种方式,一种是点击属性面板里面的table组件进行编辑

另外一种就是给text添加padding;

那些年我用ireport爬过的坑_第2张图片

ireport模板基本上就这些,以后用到的话还会整理;接下来关键是和现有的系统进行整合;

我们采用的系统是spring+springMVC+ibatis;

SpringMvc JasperReport整合

1、继承JasperReportsMultiFormatView类,并重写fillReport()方法,在该方法中增加setUrl()实现,这样就可以在controller中指定要使用的报表模板文件了。这样做的好处是,只需要一个jasperReport配置文件,可以在controller中动态的设定报表模板url。

/** 
 * SpringMVC + IReport整合 视图处理扩展 
 * @Author lyg 
 * @Create 2016-5-4 3:00
 */ 
public class ApplicationIReportView extends JasperReportsMultiFormatView{
	private JasperReport jasperReport;  
    
    public ApplicationIReportView() {  
        super();  
    }  
  
    @Override
	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);  
    }  
      
    @Override
	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.odianyun.owms.web.view.ApplicationIReportView">  
            <!-- <property name="url" value="/WEB-INF/jasper/report2.jasper"/> -->  
            <property name="reportDataKey" value="jrMainDataSource"/>  
        </bean>  
    </beans>  
3、Jasper报表的渲染需要用到XmlViewResolver视图解析器,这样你的项目中就会存在多个视图解析器。需要注意的是,项目中如果使用了多个视图解析器,则需要设置order的值来区分解析器的使用顺序,order值越小则越靠前。增加XmlViewResolver视图解析器的同时,并指定其要解析的配置文件路径。

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/"/>
		<!--
        <property name="suffix" value=".jsp"/>
        -->
	</bean>
	
	<!-- 注册XmlViewResolver,用于iReport & JasperReports报表生成 -->
	<bean id="jasperReportResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
		<property name="order">
			<value>0</value>
		</property>
		<property name="location">
			<value>WEB-INF/jasper-defs.xml</value>
		</property>
	</bean>
另外如果我们是导出PDF的话,那么请求后缀最好是改为.pdf的,这样导出的会是PDF格式的,所以要配置一下我们的拦截器
<servlet-mapping>
		<servlet-name>web</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>web</servlet-name>
		<url-pattern>*.pdf</url-pattern>
	</servlet-mapping>
这里要说一个小技巧,就是我报表页面的话,有一个字段是比较复杂的字表查询,我们没有比较去写一个很复杂的sql去关联,这里只需要给它预留一个空白字段,然后通过我们的数据源去填充就好了;

那些年我用ireport爬过的坑_第3张图片

比如说我这里面有一个属性字段,这个属性是通过另外几张表关联出来的,这里我不通过sql语句去关联,而是先把整个收货明细给查出来,再去遍历这个明细去查这个货品属性;

还有一个小技巧就是我们通过javaBean给ireport模板填充数据,所以模板里面不需要传入查询条件,只要数据源去过滤一遍查询条件就OK了;

	/**
	 * 返回iReport报表视图
	 * 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = ReportConstant.ASN_TASK_LIST+ReportConstant.PDF, method = RequestMethod.POST)
	public String report(String docGuid,HttpServletRequest request,Model model) throws Exception {
		List listBean=new ArrayList<>();
		// 报表数据源
		SysUserPO user = (SysUserPO) OwmsUtils.getCurrentUser(request);
		DocAsnItemVO areaVO=new DocAsnItemVO();
		areaVO.setDocGuid(docGuid);
		//areaVO.setDocGuid("5be937b0-6899-48e8-8a63-62d1837edae4");
		listBean=DocAsnItemManager.listDocAsnItemReport(areaVO, user);
		JRDataSource jrDataSource = new JRBeanCollectionDataSource(listBean);
		// 动态指定报表模板url
		model.addAttribute("url", "/WEB-INF/jasper/asnTaskRepost.jasper");
		model.addAttribute("format", "pdf"); // 报表格式
		model.addAttribute("jrMainDataSource", jrDataSource);
		return "iReportView"; // 对应jasper-defs.xml中的bean id
	}

最后是js和html页面:

	<button class="btn btn-primary btn-sm"   ng-click="asnReport()"  type="button">打印</button>
我们在一个form里面放了一个button,然后botton点击事情去提交这个请求;

$scope.asnReport =function(){
		$scope.docGuid=$scope.saveContent.docGuid;
		  document.getElementById("docGuid").value=$scope.saveContent.docGuid;
		//$("#docGuid").attr("value",$scope.saveContent.docGuid);
		var  form=$("#headerForm");
		form.attr("action","asnTaskList.pdf");
		form.attr("method","post");
		form.attr("target","_blank");
		form.submit();
	};

你可能感兴趣的:(那些年我用ireport爬过的坑)