历史版本14 :带参程序数据集 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

目录:

1. 问题描述编辑

在实际应用中,可能需要根据表名动态地改变数据源,比如在程序数据集中,通过传进的表名参数,到数据库取出对应的表作为数据源。因为FineReport是通过AbstractTableData抽象类来读取数据源的,而上述所有的数据来源都继承实现其抽象方法 ,因此用户只要实现了AbstractTableData抽象类,也就可以用自定义类型的数据源了(程序数据集),FineReport报表引擎就能够读取定义的数据源作为报表数据源使用。以下就对这种情况举例说明。

2. 实现原理编辑

简单程序数据集相同,即继承AbstractTableData。

3. 实现步骤编辑

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.doc; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileFilter; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JToolBar; import javax.swing.KeyStroke; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import com.fr.design.config.ToolBarDef; import com.fr.doc.tag.DOC; public class Main extends JFrame implements TreeSelectionListener { public static void main(String[] args) { new Main(); }    private DirectoryTree dTree; private JPanel centerCardPane; private RichDocPane rPane; public Main() { JPanel contentPane = (JPanel)this.getContentPane(); contentPane.setLayout(new BorderLayout(0, 0)); contentPane.add(createWestPane(), BorderLayout.WEST); centerCardPane = new JPanel(); contentPane.add(centerCardPane, BorderLayout.CENTER); centerCardPane.setLayout(new CardLayout()); centerCardPane.add(createEmptyPane(), "EMPTY"); centerCardPane.add(createDocumentFolderPane(), "FOLDER"); centerCardPane.add(createDocumentFilePane(), "FILE"); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setExtendedState(MAXIMIZED_BOTH); // 最大化 this.setVisible(true); } private JToolBar toolbarActions2JToolbar(ToolbarUpdateAction[] toolbarActions, JComponent keyTarget) { ToolBarDef def = new ToolBarDef(); for (int i = 0; i < toolbarActions.length; i++) { def.addShortCut(toolbarActions[i]); KeyStroke keyStroke = toolbarActions[i].getKeyStroke(); if (keyStroke != null) { String actionName = String.format("RichDoc(%s)", toolbarActions[i].getName()); keyTarget.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, actionName); keyTarget.getActionMap().put(actionName, toolbarActions[i]); } } JToolBar toolbar = ToolBarDef.createJToolBar(); def.updateToolBar(toolbar); if(rPane != null){ toolbar.add(rPane.comboBoxPane()); } return toolbar; } private JPanel createWestPane() { JPanel west = new JPanel(); west.setLayout(new BorderLayout()); JSplitPane splitPane ; dTree = new DirectoryTree(new File(DocContext.getContext().getHomePath()), new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { return !".svn".equals(pathname.getName()); } else if (pathname.isFile()) { return pathname.getName().endsWith(".src"); } return false; } }); JPanel toolPane = new JPanel(new BorderLayout()); //swicth工作目录 final DocEnvComBoxPanel envListPane = new DocEnvComBoxPanel(); String currentEnv = DocContext.getContext().getCurrentEnv(); envListPane.setSelectedItem(currentEnv); envListPane.addComboBoxActionListener(new ActionListener() {             @Override public void actionPerformed(ActionEvent evt) {                 if (envListPane.isRefreshingItems()) {                     return;                 }                 String selectedEnvName = envListPane.getSelectedItem();                 DocContext docContext = DocContext.getContext();                 DocEnv selectedEnv = docContext.getEnv(selectedEnvName);                 dTree.setWorkspaceRoot(new File(selectedEnv.getPath()));                 docContext.setCurrentEnv(selectedEnvName);                 DocContext.xmlablize();             }         }); toolPane.add(envListPane, BorderLayout.NORTH); //其他按钮 toolPane.add(toolbarActions2JToolbar(dTree.supportedActions(), dTree),BorderLayout.CENTER); splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, toolPane, new JScrollPane(dTree)); splitPane.setDividerLocation(87); splitPane.setDividerSize(1); // west.add(new JScrollPane(dTree), BorderLayout.CENTER); // west.add(toolbarActions2JToolbar(dTree.supportedActions(), dTree), BorderLayout.NORTH); west.add(splitPane,BorderLayout.CENTER); dTree.checkShortCutsEnabled(); dTree.addTreeSelectionListener(this); west.setPreferredSize(new Dimension(220, west.getPreferredSize().height)); return west; } private JPanel createEmptyPane() { return new JPanel(); } private JPanel createDocumentFolderPane() { return new JPanel(); } private JPanel createDocumentFilePane() { JPanel center = new JPanel(); center.setLayout(new BorderLayout(4, 4)); rPane = new RichDocPane(); // JScrollPane jsp = new JScrollPane(rPane); // center.add(jsp, BorderLayout.CENTER); center.add(rPane, BorderLayout.CENTER); center.add(toolbarActions2JToolbar(rPane.supportedActions(), rPane), BorderLayout.NORTH); return center; } private void showEmptyPane() { ((CardLayout)centerCardPane.getLayout()).show(centerCardPane, "EMPTY"); } private void showFolderPane() { ((CardLayout)centerCardPane.getLayout()).show(centerCardPane, "FOLDER"); } private void showFilePane() { ((CardLayout)centerCardPane.getLayout()).show(centerCardPane, "FILE"); } @Override public void valueChanged(TreeSelectionEvent e) { // Update if (e.getOldLeadSelectionPath() != null) { DefaultMutableTreeNode lastSelectedTreeNode = dTree.getTreeNodeByTreePath(e.getOldLeadSelectionPath()); Object lastSelectedUserObject = lastSelectedTreeNode.getUserObject(); if (lastSelectedUserObject instanceof DocumentFile) { updateDocumentFile((DocumentFile)lastSelectedUserObject); } else if (lastSelectedUserObject instanceof DocumentFolder) { updateDocumentFolder((DocumentFolder)lastSelectedUserObject); } } // Populate showEmptyPane(); if (e.getNewLeadSelectionPath() != null) { DefaultMutableTreeNode newSelectedTreeNode = dTree.getTreeNodeByTreePath(e.getNewLeadSelectionPath()); Object userObject = newSelectedTreeNode.getUserObject(); if (userObject instanceof DocumentFile) { showFilePane(); this.rPane.clearUndoManager(); populateDocumentFile((DocumentFile)userObject); } else if (userObject instanceof DocumentFolder) { showFilePane(); populateDocumentFolder((DocumentFolder)userObject); } } } private void populateDocumentFile(DocumentFile dFile) { this.rPane.populate(dFile.getDoc(), dFile.getFile()); this.rPane.setModified(false); } private void updateDocumentFile(DocumentFile dFile) { DOC doc = this.rPane.update(); dFile.setDoc(doc); dFile.xmlablize(); } private void populateDocumentFolder(DocumentFolder dFolder) { this.rPane.populate(dFolder.getDoc(), new File(dFolder.getFile(),".finedoc")); this.rPane.setModified(false); } private void updateDocumentFolder(DocumentFolder dFolder) { DOC doc = this.rPane.update(); dFolder.setDoc(doc); dFolder.xmlablize(); } } 
编译ParamTableDataDemo.java ,将生成的ParamTableDataDemo.class类文件拷贝到报表工程/WEB-INF/classes目录下。由于该类是在com.fr.data包中的,因此最终应该将该类放在/WEB-INF/classes/com/fr/data下面。此时该程序数据源便定义好了。
3.4 配置程序数据集
新建报表,在报表数据集中新建程序数据源,选择我们定义好的程序数据集,如下图,名字可以自定义,如divtable
222

3.5 使用程序数据集
配置好程序数据源后便可以使用定义的程序数据集了,选中该数据集点击预览按钮,即可以输入表名动态地获取相应的数据表,并制作模板,如下图

222


222

注:如果预览不出数据,请确认代码段里面定义数据库连接时URL的地址是否正确。

可以看到,我们已经将STSCORE表中的数据提取至程序数据集表中,像其他类型的数据集一样,可以通过拖拽方法实现单元格数据列绑定。