您的位置:首页 > 其它

那些年我用ireport爬过的坑

2016-05-15 14:00 295 查看
最近使用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日期格式的问题:

点击日期找到属性里面的



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

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

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

ireport之编写表格:

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



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



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去关联,这里只需要给它预留一个空白字段,然后通过我们的数据源去填充就好了;



比如说我这里面有一个属性字段,这个属性是通过另外几张表关联出来的,这里我不通过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();
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: