咱們今天又來說講報表開發的事,上週開的這個系列入門文章也三四天了,瀏覽量不佳小編甚是悲傷啊,但願你們多多支持我!java
在實際應用中,可能須要根據表名動態地改變數據源,好比在程序數據集中,經過傳進的表名參數,到數據庫取出對應的表做爲數據源。由於FineReport是經過AbstractTableData抽象類來讀取數據源的,而上述全部的數據來源都繼承實現其抽象方法 ,所以用戶只要實現了AbstractTableData抽象類,也就能夠用自定義類型的數據源了(程序數據集),FineReport報表引擎就可以讀取定義的數據源做爲報表數據源使用。如下就對這種狀況舉例說明。sql
與簡單程序數據集相同,即繼承AbstractTableData。你們能夠參考我上次的文章。數據庫
3.1 定義參數
定義一個參數,並定義數據表結構,代碼以下:數組
public ParamTableDataDemo() { // 定義tableName參數 this.parameters = new Parameter[] { new Parameter("tableName") }; // 定義程序數據集列名 columnNames = new String[columnNum]; for (int i = 0; i < columnNum; i++) { columnNames[i] = "column#" + String.valueOf(i); } } **3.2 設置數據** 將數據放入到定義的表中,代碼以下: public void init() { // 確保只被執行一次 if (valueList != null) { return; } // 保存獲得的數據庫表名 String tableName = parameters[0].getValue().toString(); // 構造SQL語句,並打印出來 String sql = "select * from " + tableName + ";"; FRContext.getLogger().info("Query SQL of ParamTableDataDemo: \n" + sql); // 保存獲得的結果集 valueList = new ArrayList(); // 下面開始創建數據庫鏈接,按照剛纔的SQL語句進行查詢 Connection conn = this.getConnection(); try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); // 得到記錄的詳細信息,而後得到總列數 ResultSetMetaData rsmd = rs.getMetaData(); colNum = rsmd.getColumnCount(); // 用對象保存數據 Object[] objArray = null; while (rs.next()) { objArray = new Object[colNum]; for (int i = 0; i < colNum; i++) { objArray[i] = rs.getObject(i + 1); } // 在valueList中加入這一行數據 valueList.add(objArray); } // 釋放數據庫資源 rs.close(); stmt.close(); conn.close(); // 打印一共取到的數據行數量 FRContext.getLogger().info( "Query SQL of ParamTableDataDemo: \n" + valueList.size()+ " rows selected"); } catch (Exception e) { e.printStackTrace(); } }
3.3 完整的數據集代碼
完整的帶參程序數據集的代碼以下:函數
package com.fr.data; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; import java.util.ArrayList; import com.fr.base.FRContext; import com.fr.data.AbstractTableData; import com.fr.base.Parameter; public class ParamTableDataDemo extends AbstractTableData { // 列名數組,保存程序數據集全部列名 private String[] columnNames = null; // 定義程序數據集的列數量 private int columnNum = 10; // 保存查詢表的實際列數量 private int colNum = 0; // 保存查詢獲得列值 private ArrayList valueList = null; // 構造函數,定義表結構,該表有10個數據列,列名爲column#0,column#1,。。。。。。column#9 public ParamTableDataDemo() { // 定義tableName參數 this.parameters = new Parameter[] { new Parameter("tableName") }; // 定義程序數據集列名 columnNames = new String[columnNum]; for (int i = 0; i < columnNum; i++) { columnNames[i] = "column#" + String.valueOf(i); } } // 實現其餘四個方法 public int getColumnCount() { return columnNum; } public String getColumnName(int columnIndex) { return columnNames[columnIndex]; } public int getRowCount() { init(); return valueList.size(); } public Object getValueAt(int rowIndex, int columnIndex) { init(); if (columnIndex >= colNum) { return null; } return ((Object[]) valueList.get(rowIndex))[columnIndex]; } // 準備數據 public void init() { // 確保只被執行一次 if (valueList != null) { return; } // 保存獲得的數據庫表名 String tableName = parameters[0].getValue().toString(); // 構造SQL語句,並打印出來 String sql = "select * from " + tableName + ";"; FRContext.getLogger().info("Query SQL of ParamTableDataDemo: \n" + sql); // 保存獲得的結果集 valueList = new ArrayList(); // 下面開始創建數據庫鏈接,按照剛纔的SQL語句進行查詢 Connection conn = this.getConnection(); try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); // 得到記錄的詳細信息,而後得到總列數 ResultSetMetaData rsmd = rs.getMetaData(); colNum = rsmd.getColumnCount(); // 用對象保存數據 Object[] objArray = null; while (rs.next()) { objArray = new Object[colNum]; for (int i = 0; i < colNum; i++) { objArray[i] = rs.getObject(i + 1); } // 在valueList中加入這一行數據 valueList.add(objArray); } // 釋放數據庫資源 rs.close(); stmt.close(); conn.close(); // 打印一共取到的數據行數量 FRContext.getLogger().info( "Query SQL of ParamTableDataDemo: \n" + valueList.size()+ " rows selected"); } catch (Exception e) { e.printStackTrace(); } } // 獲取數據庫鏈接 driverName和 url 能夠換成您須要的 public Connection getConnection() { String driverName = "sun.jdbc.odbc.JdbcOdbcDriver"; String url = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=D:\\FineReport_7.0\\WebReport\\FRDemo.mdb"; String username = ""; String password = ""; Connection con = null; try { Class.forName(driverName); con = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); return null; } return con; } // 釋放一些資源,由於可能會有重複調用,因此需釋放valueList,將上次查詢的結果釋放掉 public void release() throws Exception { super.release(); this.valueList = null; } }
編譯ParamTableDataDemo.java ,將生成的ParamTableDataDemo.class類文件拷貝到報表工程/WEB-INF/classes目錄下。因爲該類是在com.fr.data包中的,所以最終應該將該類放在/WEB-INF/classes/com/fr/data下面。此時該程序數據源便定義好了。
3.4 配置程序數據集
新建報表,在報表數據集中新建程序數據源,選擇咱們定義好的程序數據集,以下圖,名字能夠自定義,如divtable
3.5 使用程序數據集
配置好程序數據源後即可以使用定義的程序數據集了,選中該數據集點擊預覽按鈕,便可以輸入表名動態地獲取相應的數據表,並製做模板,以下圖
注:若是預覽不出數據,請確認代碼段裏面定義數據庫鏈接時URL的地址是否正確。
能夠看到,咱們已經將STSCORE表中的數據提取至程序數據集表中,像其餘類型的數據集同樣,能夠經過拖拽方法實現單元格數據列綁定。
好啦今天就講到這啦!今天的程序有點多,求關注,求推薦,求收藏。this