1. 程式人生 > >【iReport+JasperReport】2.在Java工程中利用jasper匯出PDF報表

【iReport+JasperReport】2.在Java工程中利用jasper匯出PDF報表

我們上一次成功的利用iReport工具製作了一張報表,並且預覽了報表最後的效果,也生成了格式為“jrpxml”、“jrxml”與“jasper”的檔案。這次,我們使用jasper提供的java的api去利用在iReport中製作的報表jasper檔案來生成真正的報表檔案。

本文以生成pdf格式的報表檔案為例,該報表檔案包含所有男使用者的資訊。

首先我們開啟MyEclipse,在其中建立一個java工程:

新建一個lib資料夾,然後在lib中加入我們準備好的jar包:

然後將這些jar包全部新增到環境中(右鍵build path)


然後編寫獲取資料庫連線的類,用於連線資料庫並獲取相應連線物件,以便於後期操作資料庫:
package com.cn.org.ireport.test;

import java.sql.Connection;
import java.sql.DriverManager;

public class JDBCConnection {
    
    public static Connection getConnection(){
        try {
             String url = "jdbc:mysql://localhost:3306/db_film";
             Class.forName("org.gjt.mm.mysql.Driver");
             Connection con = DriverManager.getConnection(url, "root", "1234");
             return con;
         }catch(Exception e){
              e. printStackTrace();
         }
         return null;
    }
}

接下來編寫dataSource類(也就是資料填充類),實現JRDataSource介面,通過放在list裡面的Map物件迭代實現資料對應:
package com.cn.org.ireport.test;

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

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;
/**
*  dataSource類(也就是資料填充類),實現JRDataSource介面
*  通過放在list裡面的Map物件迭代,實現資料對應
*/
public class ReportDataSource implements JRDataSource{

    private Iterator iter;
    
    //建立一個,map物件用與資料對應
    Map map = new HashMap();
    
    //無參的建構函式
    public ReportDataSource(){
        
    }
    
    //以sex為引數的有參建構函式,用於資料初始化
    public ReportDataSource(String sex){
        //通過性別獲取相應使用者的資料
        List datas=DateSourceBaseFactory.createBeanCollection(sex);
        //要將List中的資料迭代,需要使用Iterator迭代物件
        iter=datas.iterator();
    }
    
    //通過key獲取value值
    public Object getFieldValue(JRField arg0) throws JRException {
        return map.get(arg0.getName());
    }

    //介面JRDataSource的方法,判斷是否有下一個資料
    public boolean next() throws JRException {
        if(iter.hasNext()){
            map=(Map)iter.next();
            return true;
        }
        return false;
    }

}

接下來實現上個類中的DateSourceBaseFactory(提供資料的資料來源工廠),它是實際從資料庫中取出相應資料,然後將其封裝在map中,然後又將相應的map裝在List容器中。
package com.cn.org.ireport.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * Map中的鍵值要與模板中的file值對應
 * */
public class DateSourceBaseFactory {

    public static List createBeanCollection(String sex) {
        
        int num=0;
        if(sex.equals("男")){
            num=1;
        }else{
            num=2;
        }
        
        ResultSet rs=null;
        Statement st=null;
        Connection con=null;
        List datas=new ArrayList();
        
        try {
            con=JDBCConnection.getConnection();
            st=con.createStatement();
            rs=st.executeQuery("select name,brithday,province,Email from user where sex="+num);
            while(rs.next()){
                Map attris=new HashMap();
                attris.put("name", rs.getString("name"));
                attris.put("brithday", rs.getString("brithday"));
                attris.put("province", rs.getString("province"));
                attris.put("Email", rs.getString("Email"));
                datas.add(attris);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
                try {
                    if(rs!=null) rs.close();
                    if(st!=null) st.close();
                    if(con!=null) con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        }
        
        return datas;
    }

}

接下來編寫dataSource的javaBean類。用於建立模板
package com.cn.org.ireport.test;

import java.io.Serializable;

public class DataSoruceBean implements Serializable{

    private static final long serialVersionUID = 1L;
    
    private String name;
    private String brithday;
    private String province;
    private String Email;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getBrithday() {
        return brithday;
    }
    public void setBrithday(String brithday) {
        this.brithday = brithday;
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getEmail() {
        return this.Email;
    }
    public void setEmail(String email) {
        this.Email = email;
    }
}

接下來是重頭戲,編寫測試入口類,生成pdf檔案。JasperFillManager中有多個生成檔案的方法
,除了可以生成pdf檔案外還可以生成ofice文件檔案。這裡我們就將取出的資料列印到報表中去:
package com.cn.org.ireport.test;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JRAbstractExporter;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;

public class TestReportHere {
    public static void main(String[] args) {
        Map parameters=new HashMap();
        ByteArrayOutputStream outPut=new ByteArrayOutputStream();
        FileOutputStream outputStream=null;
        File file=new File("F:/Temp/report.pdf");
        String reportModelFile="C:/Users/jack/report2.jasper";
        
        try {
            JasperPrint jasperPrint=JasperFillManager.fillReport(reportModelFile,
                    parameters,new ReportDataSource("男"));
            JRAbstractExporter exporter=new JRPdfExporter();
            //建立jasperPrint
            exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
            //生成輸出流
            exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outPut);
            //遮蔽copy功能
            exporter.setParameter(JRPdfExporterParameter.IS_ENCRYPTED,Boolean.TRUE);
            //加密
            exporter.setParameter(JRPdfExporterParameter.IS_128_BIT_KEY,Boolean.TRUE);
            exporter.exportReport();
            outputStream=new FileOutputStream(file);
            outputStream.write(outPut.toByteArray());
        } catch (JRException e) {
            e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                outPut.flush();
                outPut.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

我們點選右鍵“Run JavaAppliacrion”,來執行我們的報表生成樣例。
執行結果,我們在F盤下的Temp下發現了新生成的pdf檔案:

雙擊開啟,就是我們之前需要的資料的報表資訊。

注意:報表Pdf時,會出現中文無法顯示問題,可以設定相關元件的以下屬性。需同時設定,其他字型,可自行嘗試。
1、Font name :宋體
2、pdf Font name is now deprecated:STSong-Light
3、pdf Encoding : UniGB-UCS2-H(China Simplified)

至此我們實現了使用jasper提供的java的api來實現封裝資料列印報表的功能。