1. 程式人生 > >jasperreport 使用子報表(使用JavaBean集合作為資料來源)

jasperreport 使用子報表(使用JavaBean集合作為資料來源)

程式部分
第一步,建立與之相關的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})”,下一步,下一步完成