昨天给大家讲了一种方式,今天换一种方式,就是说,将主报表的某一参数直接传递给子报表作为数据源,当然,这个参数是包含子报表的,这个主要是基于Web开发,也是从网友那边拿来的,结合自己的经验再做一遍。
首先创建我们需要的JavaBean
ProvinceBean.java
package test;
import java.util.ArrayList;
public class ProvinceBean
{
private String provinceName;
private ArrayList<CityBean> cities;
public String getProvinceName()
{
return provinceName;
}
public void setProvinceName(String provinceName)
{
this.provinceName = provinceName;
}
public ArrayList<CityBean> getCities()
{
return cities;
}
public void setCities(ArrayList<CityBean> cities)
{
this.cities = cities;
}
}
CityBean,java
package test;
public class CityBean
{
private String cityName;
public String getCityName()
{
return cityName;
}
public void setCityName(String cityName)
{
this.cityName = cityName;
}
}
注意一下,这里Province是主表的元素其中他包含了cityBean,那么显然CityBean要作为子表之中的元素
下面创建Servlet类这个类我“本地化”一下,改动了一点
package test; import java.io.IOException; import java.io.OutputStream; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sun.net.ssl.internal.ssl.Debug; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.export.JRPdfExporter; import net.sf.jasperreports.engine.util.JRLoader; public class ChildReportServlet extends HttpServlet { private static final long serialVersionUID = -1233414483047719876L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { String root_path = this.getServletContext().getRealPath("/"); root_path = root_path.replace('\\', '/'); String reportFilePath = root_path + "ireport/parent_sub.jasper"; //Debug.println(reportFilePath, root_path); JRDataSource dataSource = this.createDataSource(); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("SUBREPORT_DIR", root_path + "ireport/"); JasperReport report = (JasperReport)JRLoader.loadObject(reportFilePath); JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, dataSource); OutputStream ouputStream = resp.getOutputStream(); resp.setContentType("application/pdf"); resp.setCharacterEncoding("UTF-8"); resp.setHeader("Content-Disposition", "attachment; filename=\"" +URLEncoder.encode("PDF报表", "UTF-8")+ ".pdf\""); // 使用JRPdfExproter导出器导出pdf JRPdfExporter exporter = new JRPdfExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream); exporter.exportReport(); ouputStream.close(); }catch(Exception ex) { ex.printStackTrace(); } } private JRDataSource createDataSource() { //生成测试数据 ArrayList<ProvinceBean> provinces = new ArrayList<ProvinceBean>(); ProvinceBean province = new ProvinceBean(); province.setProvinceName("山东"); ArrayList<CityBean> cities = new ArrayList<CityBean>(); CityBean city = new CityBean(); city.setCityName("济南"); cities.add(city); city = new CityBean(); city.setCityName("青岛"); cities.add(city); city = new CityBean(); city.setCityName("潍坊"); cities.add(city); province.setCities(cities); provinces.add(province); province = new ProvinceBean(); province.setProvinceName("江苏"); cities = new ArrayList<CityBean>(); city = new CityBean(); city.setCityName("南京"); cities.add(city); city = new CityBean(); city.setCityName("无锡"); cities.add(city); city = new CityBean(); city.setCityName("苏州"); cities.add(city); province.setCities(cities); provinces.add(province); return new JRBeanCollectionDataSource(provinces); } }
我的文件列表

注意一下,要把jasperreport的jar文件拷贝到lib文件夹下,不然出错找度娘或者问我好了
下面用iReport制作我们需要的报表模板
这两个
打开iReport新建一个报表,数据源的话可以选择空数据源
在主表左侧属性Fields中新建字段;从上面我们创建的Bean中可以知道有两个字段需要建立一个是provinceName一个是cities
创建时候要注意cities的数据类型是list
之后创建子表,这个一路next下去就OK了,将其放到任意一个bands中,如果没有特殊的偏好设置,在主表中点击子表它的属性应该会在右边栏显示,上上次的文章我已经说过要注意Connection type属性,一个是不用,一个是和父表相同,还有一个use datasource。。。。这是这次我们要使用的,选择它然后在下面Data Source Exception 中填入
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cities})

如下图:$F{cities}就是我们要传递给字表的数据,只注重技术,不考虑美观,做的就随意了些

下面切换到子表的设计界面,把那些没有用到的bands删掉或者高度设为0
不知道你还记不记得上面我们创建的CityBean,它包含一个属性参数,而我们传给子表的是一个City列表,那么在子表中我们要把它提取出来
所以,在子表的fields中新建字段cityName这个字段属性要和CityBean里面的完全一样,不然就会出错的。
之后点击preview,当然是在主表中点击,会跳出些让输入什么的,不用管它,我们只要是想让iReport编译我们的文件形成后缀名为.jasper,也借此检查一下是否有错。
编译之后把主表和子表拷贝到之前说的那位置,运行服务器

打开:

需要源码请留邮箱,欢迎来探讨
|