zoukankan      html  css  js  c++  java
  • WPF中RDLC报表的钻取实现

    1、新建wpf项目,并引入3个程序集:

    Microsoft.ReportViewer.WinForms

    WindowsFormsIntegration

    System.Windows.Forms

    如果无法搜索到,可能是VS没有安装相关组件,请如图添加:

    2、新建Entities文件夹,在其中添加Entities.cs文件,其中创建两个实体类,Department和Employee

    class Department
        {
            public int DepartmentId { get; set; }
            public string DepartmentName { get; set; }
            public string DepartmentInfo { get; set; }
        }
    
        class Employee
        {
            public int EmployeeId { get; set; }
            public int DepartmentId { get; set; }
            public string Name { get; set; }
            public string NickName { get; set; }
        }
    View Code

    3、创建钻取表——部门表Department.rdlc,内部控件可在工具箱窗口创建:

      3.1、绑定数据集/源,在Report Data中的数据集项目右键-添加数据集(名称为:DepartmentDS)-新建数据源-对象,下一步选择sep2中建立的Department对象。

      3.2、完成后即可将数据源的字段添加如报表中。

      3.3、在DepartmentId中右键-文本框属性-操作-选择“转到报表”,指定报表填入“Emploee”(此报表下一步创建)参数填入DepartmentId:

      

      再设置一下钻取关键字的字体样式,钻取表配置完成。

    4、创建目标表——员工表Employee:

      4.1、添加绑定Employee对象,操作如部门表,数据集名称指定为:(名称为:EmployeeDS)。

      4.2、定义参数,Report Data窗口中:参数右键-添加参数,名称填入DepartmentId,类型为Integer(要与传入类型一致)。

      4.3、添加筛选器,筛选器可以采用指定参数来自动过滤数据,选择数据集所在行右键-tablix属性-筛选器-点击fx进入表达式编写。

      其中表达式填入:=CInt(Fields!DepartmentId.Value)类型为Integer,运算符为“=”,值填入:=CInt(Parameters!DepartmentId.Value)

      到此,报表主要设计完成。

    5、在MainWindow窗体中放入ReportViewer:

      5.1、xaml窗口代码,先引入命名空间:xmlns:rv="clr-namespace:Microsoft.Reporting.WinForms;assembly=Microsoft.ReportViewer.WinForms" 

      然后主体部分:

      

        <Grid>
            <WindowsFormsHost>
                <rv:ReportViewer x:Name="reportViewer"/>
            </WindowsFormsHost>
        </Grid>
    View Code

      5.2、窗口交互代码,功能是为报表填充数据,数据介质是DataTable,内容正是对应的实体类。

      

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.Loaded += DepartmentLoaded;
                //this.Loaded += EmployeeLoaded;
            }
    
            // 载入部门报表
            private void DepartmentLoaded(object sender, RoutedEventArgs e)
            {
                // 模拟一个DataTable
                DataTable dt = new DataTable();
                dt.Columns.Add("DepartmentId", typeof(int));
                dt.Columns.Add("DepartmentName", typeof(string));
                dt.Columns.Add("DepartmentInfo", typeof(string));
    
                dt.Rows.Add(123, "内勤", "B3456123");
                dt.Rows.Add(234, "外勤", "U3884912");
    
                ReportDataSource reportDataSource = new ReportDataSource();
    
                reportDataSource.Name = "DepartmentDS";
                reportDataSource.Value = dt;
    
                reportViewer.Reset();
    
                reportViewer.LocalReport.ReportPath = Directory.GetCurrentDirectory() + "\Department.rdlc";
                reportViewer.LocalReport.DataSources.Add(reportDataSource);
                reportViewer.Drillthrough += new DrillthroughEventHandler(report_Drillthrough);// 处理钻取事件
    
                reportViewer.RefreshReport();
            }
    
    
            // 载入员工报表
            private void EmployeeLoaded(object sender, RoutedEventArgs e)
            {
                // 模拟一个DataTable
                DataTable dt = MakeEmployeeDT();
    
                ReportDataSource reportDataSource = new ReportDataSource();
    
                reportDataSource.Name = "EmployeeDS";
                reportDataSource.Value = dt;
    
                reportViewer.Reset();
    
                reportViewer.LocalReport.ReportPath = Directory.GetCurrentDirectory() + "\Employee.rdlc";
                reportViewer.LocalReport.DataSources.Add(reportDataSource);
    
                ReportParameter departmentId = new ReportParameter("DepartmentId", "1");
                reportViewer.LocalReport.SetParameters((new ReportParameter[] { departmentId }));// 放入参数测试
    
                reportViewer.RefreshReport();
            }
    
            // 填充钻取的数据
            private void report_Drillthrough(object sender, DrillthroughEventArgs e)
            {
                int dId = 0;
                DataTable dt = MakeEmployeeDT();
    
                ReportDataSource reportDataSource = new ReportDataSource();
    
                reportDataSource.Name = "EmployeeDS";
                reportDataSource.Value = dt;
    
                Report newRV = e.Report;
    
                if (newRV.GetParameters().Count > 0 && newRV.GetParameters()["DepartmentId"] != null)
                {
                    string tmp = newRV.GetParameters()["DepartmentId"].Values[0].Trim();
                    dId = Int32.Parse(tmp, 0);
                }
                LocalReport localReport = (LocalReport)e.Report;
                localReport.DataSources.Add(reportDataSource);
    
                //reportViewer.RefreshReport();// 钻取操作不能refresh,否则会导致刷新窗口,清除钻取记录
            }
    
            // 创建员工数据表
            private DataTable MakeEmployeeDT()
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("EmployeeId", typeof(int));
                dt.Columns.Add("Name", typeof(string));
                dt.Columns.Add("NickName", typeof(string));
                dt.Columns.Add("DepartmentId", typeof(string));
    
                dt.Rows.Add(001, "张三", "John", 123);
                dt.Rows.Add(002, "李四", "Joo", 234);
                return dt;
            }
    
        }
    View Code

    总结/说明:

      1、本例使用实体对象作为绑定数据源,可以较好的整合进当前项目,维持现有架构的层级关系,另外也可直接配置数据库或WCF服务,请自行测试;

      2、新建数据源时若找不到step2建立的实体类,请重新编译项目

      3、初次接触者RDLC文件的xml源码图形化的布局设计都定义在里面。

      4、钻取目标表的结构结果筛选即可由rdlc定义完成,也可以获取参数后自行组装DataTable,前者简单省事,后者性能高一些,看需求~。

    最后,贴一张运行效果图:

    程序打包下载

  • 相关阅读:
    微信小程序订阅消息
    自动生成小学四则运算题目
    个人项目作业
    自我介绍+软工5问
    软件工程之获小黄衫感言
    2020软件工程个人作业06——软件工程实践总结作业
    2020软件工程作业05
    2020软件工程作业00——问题清单
    2020软件工程作业04
    2020软件工程作业03
  • 原文地址:https://www.cnblogs.com/lbhqq/p/5909827.html
Copyright © 2011-2022 走看看