Ireport+struts2+javabean数据源子报表

  Ireport+struts2+javabean数据源解决子报表问题一直很难搞,前2天我终于解决了。(*^__^*) 嘻嘻……
  其实我们一直弄不通,并不是程序的问题,而是报表设计的时候一些参数没有设置正确。把理论搞清楚一切问题迎刃而解。

举个例子说明问题:

一、po类
  User.java
Java代码   收藏代码
  1. package com.ansure.moudle;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class User {  
  6.     private int u_id;  
  7.     private String u_name;  
  8.     private String u_pwd;  
  9.     private List addresses;  
  10.   
  11.     public User() {  
  12.     }  
  13.   
  14.     public User(int id, String name, String pwd, List addresses) {  
  15.         this.u_id = id;  
  16.         this.u_name = name;  
  17.         this.u_pwd = pwd;  
  18.         this.addresses = addresses;  
  19.     }  
  20.   
  21.     public int getU_id() {  
  22.         return u_id;  
  23.     }  
  24.   
  25.     public void setU_id(int uId) {  
  26.         u_id = uId;  
  27.     }  
  28.   
  29.   
  30.     public List getAddresses() {  
  31.         return addresses;  
  32.     }  
  33.   
  34.     public void setAddresses(List addresses) {  
  35.         this.addresses = addresses;  
  36.     }  
  37.   
  38.     public String getU_name() {  
  39.         return u_name;  
  40.     }  
  41.   
  42.     public void setU_name(String uName) {  
  43.         u_name = uName;  
  44.     }  
  45.   
  46.     public String getU_pwd() {  
  47.         return u_pwd;  
  48.     }  
  49.   
  50.     public void setU_pwd(String uPwd) {  
  51.         u_pwd = uPwd;  
  52.     }  
  53.   
  54. }  


  Address.java
Java代码   收藏代码
  1. package com.ansure.moudle;  
  2.   
  3. public class Address {  
  4.       
  5.     private User user;  
  6.       
  7.     private String address;  
  8.       
  9.     private String zip;  
  10.       
  11.     private String email;  
  12.   
  13.     /** 
  14.      *  
  15.      */  
  16.     public Address() {  
  17.         super();  
  18.         // TODO Auto-generated constructor stub  
  19.     }  
  20.   
  21.     /** 
  22.      * @param address 
  23.      * @param zip 
  24.      * @param email 
  25.      */  
  26.     public Address(User user, String address, String zip, String email) {  
  27.         this.user = user;  
  28.         this.address = address;  
  29.         this.zip = zip;  
  30.         this.email = email;  
  31.     }  
  32.       
  33.       
  34.     public String getAddress() {  
  35.         return address;  
  36.     }  
  37.   
  38.     public void setAddress(String address) {  
  39.         this.address = address;  
  40.     }  
  41.   
  42.     public String getEmail() {  
  43.         return email;  
  44.     }  
  45.   
  46.     public void setEmail(String email) {  
  47.         this.email = email;  
  48.     }  
  49.   
  50.     public User getUser() {  
  51.         return user;  
  52.     }  
  53.   
  54.     public void setUser(User user) {  
  55.         this.user = user;  
  56.     }  
  57.   
  58.     public String getZip() {  
  59.         return zip;  
  60.     }  
  61.   
  62.     public void setZip(String zip) {  
  63.         this.zip = zip;  
  64.     }  
  65.       
  66. }  

  这个报表想展示的就是一个这样的结果,报表的上半部分为用户的基本信息,下半部门为用户的地址信息,因为用户的联系地址可能有多个,所以我们想到了用子报表的形式来实现。

二、实现的java类
Java代码   收藏代码
  1. package com.ansure.action;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. import com.ansure.moudle.Address;  
  9. import com.ansure.moudle.User;  
  10. import com.opensymphony.xwork2.ActionSupport;  
  11.   
  12. public class TestAction extends ActionSupport {  
  13.     private static final long serialVersionUID = 1L;  
  14.     private List<User> userList = new ArrayList<User> ();  
  15.     public Map<String,Object> map = new HashMap<String,Object>();  
  16.   
  17.     //普遍报表  
  18.     public String reportUserInfo() {  
  19.         try {  
  20.             userList= getDateSouce();  
  21.         } catch (Exception e) {  
  22.             e.printStackTrace();  
  23.             return ERROR;  
  24.         }  
  25.         return SUCCESS;  
  26.     }  
  27.     //带子报表的报表,通过参数传递子报表数据源  
  28.     public String reportUserAddress(){  
  29.         try {  
  30.             userList= getDateSouce();  
  31.               
  32.             List sublist = getSubDateSouce();  
  33.             map.put("sublist", sublist);  
  34.         } catch (Exception e) {  
  35.             e.printStackTrace();  
  36.             return ERROR;  
  37.         }  
  38.         return SUCCESS;  
  39.     }  
  40. //  带子报表的报表,通过主报数据源对象的属性参数传递子表数据源(不可行)  
  41.     public String reportUserAllInfo(){  
  42.         try {  
  43.             userList= getAllDateSouce();  
  44.         } catch (Exception e) {  
  45.             e.printStackTrace();  
  46.             return ERROR;  
  47.         }  
  48.         return SUCCESS;  
  49.     }  
  50.     private List getDateSouce()throws Exception{  
  51.         List list = new ArrayList();  
  52.         try{  
  53.             User user = new User();  
  54.             user.setU_id(1);  
  55.             user.setU_name("吴明");  
  56.             user.setU_pwd("123456");  
  57.             list.add(user);  
  58.               
  59.             return list;  
  60.         }catch(Exception e){  
  61.             e.printStackTrace();  
  62.             return null;              
  63.         }     
  64.     }  
  65.     private List getSubDateSouce()throws Exception{  
  66.         List sublist = new ArrayList();  
  67.         try{  
  68.             Address add1 = new Address();  
  69.             add1.setZip("100000");  
  70.             add1.setAddress("北京市**********");  
  71.             add1.setEmail("[email protected]");            
  72.             sublist.add(add1);  
  73.               
  74.             Address add2 = new Address();  
  75.             add2.setZip("200000");  
  76.             add2.setAddress("上海市**********");  
  77.             add2.setEmail("[email protected]");  
  78.             sublist.add(add2);  
  79.               
  80.             Address add3 = new Address();  
  81.             add3.setZip("300000");  
  82.             add3.setAddress("天津市**********");  
  83.             add3.setEmail("[email protected]");  
  84.             sublist.add(add3);  
  85.               
  86.               
  87.             return sublist;  
  88.         }catch(Exception e){  
  89.             e.printStackTrace();  
  90.             return null;              
  91.         }         
  92.     }  
  93.       
  94.     private List getAllDateSouce()throws Exception{  
  95.         List list = new ArrayList();  
  96.         List sublist = new ArrayList();  
  97.         try{  
  98.             User user1 = new User();  
  99.             user1.setU_id(1);  
  100.             user1.setU_name("吴明");  
  101.             user1.setU_pwd("123456");  
  102.               
  103.             Address add1 = new Address();  
  104.             add1.setZip("100000");  
  105.             add1.setAddress("北京市**********");  
  106.             add1.setEmail("[email protected]");            
  107.             sublist.add(add1);  
  108.               
  109.             Address add2 = new Address();  
  110.             add2.setZip("200000");  
  111.             add2.setAddress("上海市**********");  
  112.             add2.setEmail("[email protected]");  
  113.             sublist.add(add2);  
  114.               
  115.             Address add3 = new Address();  
  116.             add3.setZip("300000");  
  117.             add3.setAddress("天津市**********");  
  118.             add3.setEmail("[email protected]");  
  119.             sublist.add(add3);  
  120.               
  121.             user1.setAddresses(sublist);  
  122.             list.add(user1);  
  123.               
  124.             User user2 = new User();  
  125.             user1.setU_id(2);  
  126.             user1.setU_name("张三");  
  127.             user1.setU_pwd("121212");  
  128.               
  129.             List sublist2 = new ArrayList();  
  130.             sublist2.add(add3);  
  131.             sublist2.add(add2);  
  132.             user2.setAddresses(sublist2);  
  133.               
  134.             list.add(user2);  
  135.               
  136.             return list;  
  137.         }catch(Exception e){  
  138.             e.printStackTrace();  
  139.             return null;              
  140.         }         
  141.     }  
  142.   
  143.     public List<User> getUserList() {  
  144.         return userList;  
  145.     }  
  146.   
  147.     public void setUserList(List<User> userList) {  
  148.         this.userList = userList;  
  149.     }  
  150.     public Map<String, Object> getMap() {  
  151.         return map;  
  152.     }  
  153.     public void setMap(Map<String, Object> map) {  
  154.         this.map = map;  
  155.     }  
  156.       
  157.       
  158. }  


上面代码提供3个方法,第二个方法是本文要讲的内容。userList为主报表数据源,而子报表数据源是作为参数传递的。在ireport中把这 个参数作为子报表的数据源(new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})) 传递过去

三、配置文件
struts.xml
Java代码   收藏代码
  1. <struts>  
  2.     <!-- 设置使用JasperReports的Action -->  
  3.     <package name="C06.3"  
  4.         extends="struts-default,jasperreports-default">  
  5.         <action name="reportUserInfo" class="com.ansure.action.TestAction" method="reportUserInfo">  
  6.             <!-- result类型设置为jasper -->  
  7.             <result name="success" type="jasper">  
  8.                 <!-- 编译后的jasper文件路径 -->  
  9.                 <param name="location">  
  10.                     /jasperreports/testReport.jasper  
  11.                 </param>  
  12.                 <!-- 视图界面中显示的数据的数据源 -->  
  13.                 <param name="dataSource">userList</param>  
  14.                 <!-- 报表生成格式 -->  
  15.                 <param name="format">PDF</param>  
  16.             </result>           
  17.         </action>  
  18.   
  19.         <action name="reportUserAddress" class="com.ansure.action.TestAction" method="reportUserAddress">  
  20.             <!-- result类型设置为jasper -->  
  21.             <result name="success" type="jasper">  
  22.                 <!-- 编译后的jasper文件路径 -->  
  23.                 <param name="location">  
  24.                     /jasperreports/test_mainReport.jasper  
  25.                 </param>  
  26.                 <!-- 视图界面中显示的数据的数据源 -->  
  27.                 <param name="dataSource">userList</param>  
  28.                 <param name="reportParameters">map</param>    
  29.                 <!-- 报表生成格式 -->  
  30.                 <param name="format">PDF</param>  
  31.             </result>           
  32.         </action>  
  33.           
  34.         <action name="reportUserAllInfo" class="com.ansure.action.TestAction" method="reportUserAllInfo">  
  35.             <!-- result类型设置为jasper -->  
  36.             <result name="success" type="jasper">  
  37.                 <!-- 编译后的jasper文件路径 -->  
  38.                 <param name="location">  
  39.                     /jasperreports/testReport.jasper  
  40.                 </param>  
  41.                 <!-- 视图界面中显示的数据的数据源 -->  
  42.                 <param name="dataSource">userList</param>  
  43.                 <!-- 报表生成格式 -->  
  44.                 <param name="format">PDF</param>  
  45.             </result>           
  46.         </action>  
  47.           
  48.     </package>  
  49. </struts>  


四、Ireport模板

设计模板的基础知识就不再多说了,说下几个注意的地方
  • 建议以javabean作为数据源时,主报表和子报表模板分别设计比较好。主报表添加子报表时选择已存在的子报表就可以了。Ireport+struts2+javabean数据源子报表
  • 因为程序为主报表传过来一个参数,比如sublist,所以要在主报表中添加参数sublist,并且通过参数属性界面更改参数类型(默认为String类型的),更改为java.lang.List.Ireport+struts2+javabean数据源子报表
  • 打开在主报表中添加的子报表控件的属性面板,查看connection type 属性,选择Use a datasource expression 选项[*]打开在主报表中添加的子报表控件的属性面板,查看Data Source Expression属性,填写new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})。。Ireport+struts2+javabean数据源子报表
  • 如果有多个子报表,需要顺序输出到页面,而且你又不确定每个子报表的所占高度,那么建议把子报表放在分组中。分组时可以添加多个header和fooder的,所以你也可以添加多个子报表。Ireport+struts2+javabean数据源子报表        


子报表
Ireport+struts2+javabean数据源子报表

运行结果
Ireport+struts2+javabean数据源子报表
五、未解决问题
  我在做这个测试前看了一个帖子,帖子的说明的是ireport以javabean为数据源解决子报表问题,用的是 javabean+sevlet的结构。使用的方法和我提供的reportUserAllInfo原理相同,但是这个方法在struts2这个框架下没有 测试通过(在我这里是这样的)。有没有人知道怎么解决?

Bug如下:
引用
javax.servlet.ServletException: Error evaluating expression :
Source text : new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{addresses})

引用
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'org.apache.struts2.views.jasperreports.ValueStackDataSource@1159cd1' with class 'org.apache.struts2.views.jasperreports.ValueStackDataSource' to class 'java.util.List'
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:340)

六、%>_<%,上传不了了呐。不过代码都贴出来了,lib文件的下载在struts2+ireport学习小结(一)和(二)中。 http://hanxin830311.iteye.com/blog/763511和http://hanxin830311.iteye.com /blog/763628

 

你可能感兴趣的:(Ireport+struts2+javabean数据源子报表)