程序部分
第一步,创建与之相关的Bean类,如下所示:
ProvinceBean.java
package lld.test.ireport;
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 lld.test.ireport;
public class CityBean
{
private String cityName;
public String getCityName()
{
return cityName;
}
public void setCityName(String cityName)
{
this.cityName = cityName;
}
}
第二步 创建Servlet类,如下所示
package lld.test.ireport;
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 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 + "WEB-INF/classes/lld/test/ireport/child_report_jbs_parent.jasper";
JRDataSource dataSource = this.createDataSource();
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("SUBREPORT_DIR", root_path + "WEB-INF/classes/lld/test/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);
}
}
如果有了以前例子的基础,这个例子应该不难看懂,需要注意的是下面这4行代码,这是新出现的特性:
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("SUBREPORT_DIR", root_path + "WEB-INF/classes/lld/test/ireport/");
JasperReport report = (JasperReport)JRLoader.loadObject(reportFilePath);
JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, dataSource);
这是因为,在使用子报表时,需要一个SUBREPORT_DIR变量,指示子报表所在的路径,在下面创建子报表的相关部分会再次进行描述,请注意对比。我在以前的例子中,调用JasperFillManager.fillReport()方法时第二个参数均为null,实际上,这个参数可传递到jasper report中的Parameters项中。
注意:如果使用了servlet 使用了SUBREPORT_DIR变量 ,那么在主报表中指定子报表的路径就可以为空,如果不为空也不会报错。
如:
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA[]]></defaultValueExpression>
</parameter>
创建报表
第一步,创建主报表,如下图所示
主报表Connection设置如下图所示:
点击main前面的那个按钮。出现:
取一个名字叫main, 工厂类如下:
package com.dnion.dayu.jasper;
import java.util.ArrayList;
import java.util.Collection;
public class WorkflowBeanFactory
{
public static Collection getBeanCollection()
{
ArrayList<ProvinceBean> provinces = new ArrayList<ProvinceBean>();
ProvinceBean province = new ProvinceBean();
province.setProvinceName("山东1");
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 provinces ;
}
}
注意:1.在这里如里指定了工厂方法,那么在iReport里可以直接预览出数据。
2.如果不在这里指定工厂方法,那么就在servlet把这个方法传过来,方法可以直接写在servlet里,而且不要是static方法。
classpath :
菜单栏:工具---->选项--->出现界面如下图:点击Add Folder,选择编译后的bean所在的文件,一定是class文件
其DataSource设置如下图所示
点击preview右边的图标,出现report query 如下图:输入 主报表bean路径,点击 :Red attriutes
下面的大框出现bean类的属性:provinceName,cities,
选中两个参数,点击 Add select field(s) ,最下面的框出现这两个参数,好了,点击OK就行了。
第二步,创建子报表,创建一个新的报表,取名叫sub, 在主报表中引用子报表,可使用工具栏的“SubReport”图标直接创建,选择已经存在的报表(use an existing report),在这里选择sub,利用系统的wizard一步一步设置,
子报表我们使用CityBean做为数据源,选择use a JRDatasource expression ,“new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cities})”,下一步,下一步完成