(1)前言


使用了VS好多年,一直认为制作报表是件很头痛的事,不是自己没有研究过,但说真的的确是很头痛的事,尤其是C#下面的各种数据绑定,网上蜡人张的BLOG对RDLC就有很透彻的详细说明,我看了半天,就给那些报表结构回路搞得莫名其妙,大师级别的人果然功力与我不一样。因为项目的需要,这两天回炉一下自己从前的报表知识,顺便写篇东西,好让后来者别多太多像我一般的无谓脑力跟体力劳动。


本人是位明显的实用主义者,程序开发有太多的理论,量你一辈子的时间也绝对不可能全部了解清楚的,可当你实际操作过一个工程的话,有些理论或许会不言而喻,很多专家都说,RDLC是很容易上手的,个人实践证明,确实不难——只要你能硬着头皮撑过我这篇入门级别的教程就好了,进阶的时候就真别问我,我也是菜鸟。


(2)自定义数据集(DataSet)


网上挺多关于RDLC的例子其实都用了Northwind的那个例子,个人认为,只是报表练练手就要动用数据库好样的庞然大物显得有点过份,所以在本教程里我宁愿选择自定义的数据,代码填充数据的内容,作为一个简单的教程而言,单独的示例工程就能运行很重要,而且,不管是自定义的数据集还是取自SQLServer的数据集,在实际报表操作上没什么差别,个人认为自定义的数据集更灵活一点。


DataSet在VS上面的昵称是“数据集”,可能探讨过数据库的童鞋对这个的理解得比我要多,我的理解是比较像图形化的Struct集合体,可以更方便更灵活创建你所需要的数据结构体,接下来就依照这样定义好的结构生成一个实例(myDataSet),再填充你获得的数据,一但你的报表跟实例作了绑定,那样数据呈现就不需要我们多想了,微软会自动帮你做好的——这便是RDLC的整个开发思路而已,内容不多。


下面是实操部分,我的开发环境是VS2012,好像以前用VS2008也是差不多的样子。


1)新建一个VS2012的WinFrom工程项目,我的工程命名是“RdlcTest”;


2)在解决方案资源管理器中,右键工程,“添加”--“新建项”,选择“数据集(DataSet)”,工程便增加了一个MyDataSet.xsd的项,这个就是你自己定义的数据集啦;


3)双击MyDataSet.xsd,在图形界面下新建你自己的数据结构体,以下是我自己的例子,数据类型全部是String(右键打开列的属性可以设置),有什么意义你就自己猜吧;

自定义数据的RDLC报表开发入门(一)_第1张图片


(2)新建报表及关联数据集


1)在工程中添加一张报表(Report1.rdlc),我这里没用“报表向导”,新建好后双击打开,你会看到一个报表设计页面跟一个“报表数据”的窗口(话说VS2012查找窗口还是相当的方便的),在“报表窗口”里添加一个数据集,你会看到下面这个对话框,选好刚刚建好的DataSet后,点确定即可。

自定义数据的RDLC报表开发入门(一)_第2张图片


2)添加报表数据集后的“报表数据”窗体是这样一副模样:

自定义数据的RDLC报表开发入门(一)_第3张图片


3)在报表设计窗口新建一个表,我们一条数据是7条个变量,就建一个七列的表(添加列的操作不需要详解了吧),然后用鼠标将“报表数据”里的DataSet1下的项逐个拖到表头里去,会有下面的效果。

自定义数据的RDLC报表开发入门(一)_第4张图片


4)虽然新建好了表跟添加数据集,但现在因为还没填充数据,所以也不可能有东西出来,何况你报表的容器还没有弄好呢是吧。回顾一下上面的步骤,我们姑且可以这么理清一下思路:一张报表(RDLC)、一个与报表关联的数据集(DataSet)、N多数据的容器(表或文本框)构成一张报表的全部元素,ReportView只是用来装报表的容器而已。


(3)添加ReportViewer及关联报表


1)打开你工程的MainForm的设计窗体,从“工具箱”中将“ReportViewer”拖到你的MainForm里去,当你选择ReportViewer时,其右上角有个小三角形,点击一下,可以看到很多选项:

自定义数据的RDLC报表开发入门(一)_第5张图片


2)第一项选择报表,当然选刚刚你添加的“Report1.rdlc”,意思就是这个ReportViewer只显示Report1.rdlc这张表;第二项选择数据源,这里需要点思考,如下图所示,报表数据源“DataSet1”是刚刚在“报表数据”窗口添加的一个数据集,而数据源实例又是什么呢?我选了项目里的MyDataSet--TestRecord,于是在这个MainForm的窗体下面会自动生成一个myDataSet的数据集实例及testRecordBindingSource的绑定实例(同参考下图),我的想法是“DataSet1”像个接口,“myDataSet”则是已经实例化的变量,类似吧?至于“父容器停靠”的选项,个人建议还是选了吧,好看一点。

自定义数据的RDLC报表开发入门(一)_第6张图片


3)假如你myDataSet里面已经有内容的话,你可以生成看到以下的这副样子:

自定义数据的RDLC报表开发入门(一)_第7张图片


4)如何填充myDataSet的数据,参见下面MainForm的窗体代码,代码应该是不难理解的,重要的是我想数据多样化一点,方便进行下一步的报表呈现讲解,示例工程我放到51CTO下载里了,编译环境是VS2012,下载地址是http://down.51cto.com/data/898719,下面博文的上传机制貌似有问题,有兴趣的朋友可以随便看看,高手莫拍。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RdlcTest
{
    public partial class MainFrom : Form
    {
        public MainFrom()
        {
            InitializeComponent();
        }
        /// 
        /// 加载窗体
        /// 
        /// 
        /// 
        private void Form1_Load(object sender, EventArgs e)
        {
            //更新数据集的内容
            this.UpdateDataSet();
            //刷新报表
            this.reportViewer1.RefreshReport();
        }
        /// 
        /// 为myDataSet手动添加数据
        /// 
        private void UpdateDataSet()
        {
            for (int i = 0; i < 5; i++)
            {
                string id = DateTime.Now.ToString() + "-" + i.ToString("D2");
                for (int j = 0; j < 4; j++)
                {
                    this.myDataSet.TestRecord.AddTestRecordRow(id, "001", "shengqin", "Man", "Change Road", DateTime.Now, "describe : " + i.ToString("D3"));
                }
            }
            for (int j = 0; j < 4; j++)
            {
                this.myDataSet.TestRecord.AddTestRecordRow(DateTime.Now.ToString() + "-10", "002", "Joey", "Man", "Testing Speed", DateTime.Now, "describe : Joey's testing.");
            }
            for (int j = 0; j < 4; j++)
            {
                this.myDataSet.TestRecord.AddTestRecordRow(DateTime.Now.ToString() + "-11", "003", "Lily", "Woman", "Testing Speed", DateTime.Now, "describe : Lily's testing.");
            }
            for (int i = 20; i < 25; i++)
            {
                string id = DateTime.Now.ToString() + "-" + i.ToString("D2");
                for (int j = 0; j < 4; j++)
                {
                    this.myDataSet.TestRecord.AddTestRecordRow(id, "001", "shengqin", "Man", "Testing Speed", DateTime.Now, "describe : " + i.ToString("D3"));
                }
            }
        }
    }
}