In practical applications, it may be necessary to dynamically change the data source according to the table name. For example, in the program data set, the corresponding table is retrieved from the database as the data source through the table name parameter passed in. For example, FineReport reads the data source through the AbstractTableData abstract class, and all the above data sources inherit and implement its abstract methods, so as long as the user implements the AbstractTableData abstract class, they can also use the data source of a custom type (program Dataset), which is the method for a parameterized program dataset connection.
The FineReport report engine can read the defined data source and use it as the report data source. The principle is to inherit AbstractTableData.
1. Define parameters
Define a parameter and define the data table structure, the code is as follows:
public ParamTableDataDemo() { // Define the tableName parameter this.parameters = new Parameter[] { new Parameter("tableName") }; // Define program dataset column names columnNames = new String[columnNum]; for (int i = 0; i < columnNum; i++) { columnNames[i] = "column#" + String.valueOf(i); } }
2. Setting data
Put the data into the defined table, the code is as follows:
public void init() { // make sure it's only executed once if (valueList != null) { return; } // Save the obtained database table name String tableName = parameters[0].getValue().toString(); // Construct the SQL statement and print it out String sql = "select * from " + tableName + ";"; FRContext.getLogger().info("Query SQL of ParamTableDataDemo: \n" + sql); // save the result set valueList = new ArrayList(); // Now start to establish a database connection and query according to the SQL statement just now Connection conn = this.getConnection(); try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); // get the details of the record, then get the total number of columns ResultSetMetaData rsmd = rs.getMetaData(); colNum = rsmd.getColumnCount(); // save data with object Object[] objArray = null; while (rs.next()) { objArray = new Object[colNum]; for (int i = 0; i < colNum; i++) { objArray[i] = rs.getObject(i + 1); } // Add this row of data to valueList valueList.add(objArray); } // release database resources rs.close(); stmt.close(); conn.close(); // print the total number of data rows fetched FRContext.getLogger().info( "Query SQL of ParamTableDataDemo: \n" + valueList.size() + " rows selected"); } catch (Exception e) { e.printStackTrace (); } }
3. Complete dataset code
The code for the entire data set with parameters is as follows
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.Env; import com.fr.base.FRContext; import com.fr.data.AbstractTableData; import com.fr.base.Parameter; public class ParamTableDataDemo extends AbstractTableData { // Array of column names, save all column names of the program dataset private String[] columnNames = null; // Define the number of columns in the program dataset private int columnNum = 10; // Save the actual number of columns in the query table private int colNum = 0; // save the query to get the column value private ArrayList valueList = null; // Constructor, define the table structure, the table has 10 data columns, the column names are column#0, column#1,. . . . . . column#9 public ParamTableDataDemo() { // Define the tableName parameter setDefaultParameters(new Parameter[] { new Parameter("tableName") }); // Define program dataset column names columnNames = new String[columnNum]; for (int i = 0; i < columnNum; i++) { columnNames[i] = "column#" + String.valueOf(i); } } // Implement the other four methods 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]; } // prepare data public void init() { // make sure it's only executed once if (valueList != null) { return; } // Save the obtained database table name String tableName = parameters[0].getValue().toString(); // Construct the SQL statement and print it out String sql = "select * from " + tableName + ";"; FRContext.getLogger().info("Query SQL of ParamTableDataDemo: \n" + sql); // save the result set valueList = new ArrayList(); // Now start to establish a database connection and query according to the SQL statement just now Connection conn = this.getConnection(); try { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); // get the details of the record, then get the total number of columns ResultSetMetaData rsmd = rs.getMetaData(); colNum = rsmd.getColumnCount(); // save data with object Object[] objArray = null; while (rs.next()) { objArray = new Object[colNum]; for (int i = 0; i < colNum; i++) { objArray[i] = rs.getObject(i + 1); } // Add this row of data to valueList valueList.add(objArray); } // release database resources rs.close(); stmt.close(); conn.close(); // print the total number of data rows fetched FRContext.getLogger().info( "Query SQL of ParamTableDataDemo: \n" + valueList.size() + " rows selected"); } catch (Exception e) { e.printStackTrace (); } } // Get database connection driverName and url can be replaced with what you need public Connection getConnection() { String driverName = "org.sqlite.JDBC"; String url = "jdbc:sqlite://D:\\FineReport_8.0\\WebReport\\FRDemo.db"; 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; } // Release some resources, because there may be repeated calls, so you need to release the valueList and release the result of the last query public void release() throws Exception { super.release(); this.valueList = null; } }
Compile ParamTableDataDemo.java and copy the generated ParamTableDataDemo.class class file to the report project/WEB-INF/classes directory. Since the class is in the com.fr.data package, it should end up under /WEB-INF/classes/com/fr/data. The program data source is now defined.
4. Configure the program dataset
Create a new report, create a new program data source in the report data set, select the program data set we defined, as shown below, the name can be customized, such as divtable
5. Using Program Datasets
After configuring the program data source, you can use the defined program data set, select the data set and click Preview
button, you can enter the table name to dynamically obtain the corresponding data table, and make a template, as shown below
If the data cannot be previewed, please confirm whether the URL address of the database connection defined in the code segment is correct.
It can be seen that the data in the STSCORE table has been extracted into the program data set table. Like other types of data sets, the cell data column binding can be realized by dragging and dropping.