Ireport+struts2+javabean数据源子报表

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

举个例子说明问题:

一、po类
  User.java
package com.ansure.moudle;

import java.util.List;

public class User {
private int u_id;
private String u_name;
private String u_pwd;
private List addresses;

public User() {
}

public User(int id, String name, String pwd, List addresses) {
this.u_id = id;
this.u_name = name;
this.u_pwd = pwd;
this.addresses = addresses;
}

public int getU_id() {
return u_id;
}

public void setU_id(int uId) {
u_id = uId;
}


public List getAddresses() {
return addresses;
}

public void setAddresses(List addresses) {
this.addresses = addresses;
}

public String getU_name() {
return u_name;
}

public void setU_name(String uName) {
u_name = uName;
}

public String getU_pwd() {
return u_pwd;
}

public void setU_pwd(String uPwd) {
u_pwd = uPwd;
}

}


  Address.java
package com.ansure.moudle;

public class Address {

private User user;

private String address;

private String zip;

private String email;

/**
*
*/
public Address() {
super();
// TODO Auto-generated constructor stub
}

/**
* @param address
* @param zip
* @param email
*/
public Address(User user, String address, String zip, String email) {
this.user = user;
this.address = address;
this.zip = zip;
this.email = email;
}


public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

public String getZip() {
return zip;
}

public void setZip(String zip) {
this.zip = zip;
}

}

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

二、实现的java类
package com.ansure.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ansure.moudle.Address;
import com.ansure.moudle.User;
import com.opensymphony.xwork2.ActionSupport;

public class TestAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private List<User> userList = new ArrayList<User> ();
public Map<String,Object> map = new HashMap<String,Object>();

//普遍报表
public String reportUserInfo() {
try {
userList= getDateSouce();
} catch (Exception e) {
e.printStackTrace();
return ERROR;
}
return SUCCESS;
}
//带子报表的报表,通过参数传递子报表数据源
public String reportUserAddress(){
try {
userList= getDateSouce();

List sublist = getSubDateSouce();
map.put("sublist", sublist);
} catch (Exception e) {
e.printStackTrace();
return ERROR;
}
return SUCCESS;
}
// 带子报表的报表,通过主报数据源对象的属性参数传递子表数据源(不可行)
public String reportUserAllInfo(){
try {
userList= getAllDateSouce();
} catch (Exception e) {
e.printStackTrace();
return ERROR;
}
return SUCCESS;
}
private List getDateSouce()throws Exception{
List list = new ArrayList();
try{
User user = new User();
user.setU_id(1);
user.setU_name("吴明");
user.setU_pwd("123456");
list.add(user);

return list;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
private List getSubDateSouce()throws Exception{
List sublist = new ArrayList();
try{
Address add1 = new Address();
add1.setZip("100000");
add1.setAddress("北京市**********");
add1.setEmail("emailname@mailserver.com");
sublist.add(add1);

Address add2 = new Address();
add2.setZip("200000");
add2.setAddress("上海市**********");
add2.setEmail("emailname@mailserver.com");
sublist.add(add2);

Address add3 = new Address();
add3.setZip("300000");
add3.setAddress("天津市**********");
add3.setEmail("emailname@mailserver.com");
sublist.add(add3);


return sublist;
}catch(Exception e){
e.printStackTrace();
return null;
}
}

private List getAllDateSouce()throws Exception{
List list = new ArrayList();
List sublist = new ArrayList();
try{
User user1 = new User();
user1.setU_id(1);
user1.setU_name("吴明");
user1.setU_pwd("123456");

Address add1 = new Address();
add1.setZip("100000");
add1.setAddress("北京市**********");
add1.setEmail("emailname@mailserver.com");
sublist.add(add1);

Address add2 = new Address();
add2.setZip("200000");
add2.setAddress("上海市**********");
add2.setEmail("emailname@mailserver.com");
sublist.add(add2);

Address add3 = new Address();
add3.setZip("300000");
add3.setAddress("天津市**********");
add3.setEmail("emailname@mailserver.com");
sublist.add(add3);

user1.setAddresses(sublist);
list.add(user1);

User user2 = new User();
user1.setU_id(2);
user1.setU_name("张三");
user1.setU_pwd("121212");

List sublist2 = new ArrayList();
sublist2.add(add3);
sublist2.add(add2);
user2.setAddresses(sublist2);

list.add(user2);

return list;
}catch(Exception e){
e.printStackTrace();
return null;
}
}

public List<User> getUserList() {
return userList;
}

public void setUserList(List<User> userList) {
this.userList = userList;
}
public Map<String, Object> getMap() {
return map;
}
public void setMap(Map<String, Object> map) {
this.map = map;
}


}


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

三、配置文件
struts.xml
<struts>
<!-- 设置使用JasperReports的Action -->
<package name="C06.3"
extends="struts-default,jasperreports-default">
<action name="reportUserInfo" class="com.ansure.action.TestAction" method="reportUserInfo">
<!-- result类型设置为jasper -->
<result name="success" type="jasper">
<!-- 编译后的jasper文件路径 -->
<param name="location">
/jasperreports/testReport.jasper
</param>
<!-- 视图界面中显示的数据的数据源 -->
<param name="dataSource">userList</param>
<!-- 报表生成格式 -->
<param name="format">PDF</param>
</result>
</action>

<action name="reportUserAddress" class="com.ansure.action.TestAction" method="reportUserAddress">
<!-- result类型设置为jasper -->
<result name="success" type="jasper">
<!-- 编译后的jasper文件路径 -->
<param name="location">
/jasperreports/test_mainReport.jasper
</param>
<!-- 视图界面中显示的数据的数据源 -->
<param name="dataSource">userList</param>
<param name="reportParameters">map</param>
<!-- 报表生成格式 -->
<param name="format">PDF</param>
</result>
</action>

<action name="reportUserAllInfo" class="com.ansure.action.TestAction" method="reportUserAllInfo">
<!-- result类型设置为jasper -->
<result name="success" type="jasper">
<!-- 编译后的jasper文件路径 -->
<param name="location">
/jasperreports/testReport.jasper
</param>
<!-- 视图界面中显示的数据的数据源 -->
<param name="dataSource">userList</param>
<!-- 报表生成格式 -->
<param name="format">PDF</param>
</result>
</action>

</package>
</struts>


四、Ireport模板

设计模板的基础知识就不再多说了,说下几个注意的地方
[list]
[*]建议以javabean作为数据源时,主报表和子报表模板分别设计比较好。主报表添加子报表时选择已存在的子报表就可以了。[img]http://dl.iteye.com/upload/picture/pic/76827/09cd217c-cb71-3357-8242-08d6e0af9554.jpg[/img]
[*]因为程序为主报表传过来一个参数,比如sublist,所以要在主报表中添加参数sublist,并且通过参数属性界面更改参数类型(默认为String类型的),更改为java.lang.List.[img]http://dl.iteye.com/upload/picture/pic/76823/3bc3cd33-a36e-3297-ade2-b412882ef59e.jpg[/img]
[*]打开在主报表中添加的子报表控件的属性面板,查看connection type 属性,选择Use a datasource expression 选项[*]打开在主报表中添加的子报表控件的属性面板,查看Data Source Expression属性,填写new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})。。[img]http://dl.iteye.com/upload/picture/pic/76819/c2799649-82ee-3cb3-97af-b2dec587d96c.jpg[/img]

[*]如果有多个子报表,需要顺序输出到页面,而且你又不确定每个子报表的所占高度,那么建议把子报表放在分组中。分组时可以添加多个header和fooder的,所以你也可以添加多个子报表。[img]http://dl.iteye.com/upload/picture/pic/76825/7c6a6593-c424-346f-b545-9c5151b14c91.jpg[/img]
[/list]

子报表
[img]http://dl.iteye.com/upload/picture/pic/76821/6bfaa3b4-adf8-3fe6-b771-369198b5e024.jpg[/img]

运行结果
[img]http://dl.iteye.com/upload/picture/pic/76829/fa0b9625-68b7-3694-ac21-3293b2d3b47e.jpg[/img]
五、未解决问题
  我在做这个测试前看了一个帖子,帖子的说明的是ireport以javabean为数据源解决子报表问题,用的是javabean+sevlet的结构。使用的方法和我提供的reportUserAllInfo原理相同,但是这个方法在struts2这个框架下没有测试通过(在我这里是这样的)。有没有人知道怎么解决?

Bug如下:
[quote]javax.servlet.ServletException: Error evaluating expression :
Source text : new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{addresses})
[/quote]
[quote]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)

[/quote]
六、%>_<%,上传不了了呐。不过代码都贴出来了,lib文件的下载在struts2+ireport学习小结(一)和(二)中。http://hanxin830311.iteye.com/blog/763511和http://hanxin830311.iteye.com/blog/763628
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值