WinForm VS2010自带报表使用心得整理
①在VS2010 WinForm中使用自带报表工具,并绑定对象
注意的是,这里绑定数据源的时候,绑定的不是具体数据库,而是某个实体数据。
现在开始记录操作步骤:
1.创建工程
2.工具箱->报表->ReportViewer 拖到窗口中
3.在右上角的菜单中选择【设计新报表】会自动创建一个.rdlc 文件 并弹出【报表向导】
4.在向导中选择要与PDF绑定的实体类
实体类
将该实体类绑定到rdlc文件
5.点击【下一步】 在这一步里 随便拖个属性过去就可以了
6.一直下一步,完成。
7.在.rdlc文件中,可以拖一些基本控件,控件拖上去之后,都可以与实体类的某个属性绑定。
例如 我拖过去一个《表》,点击单元格的时候就会有属性选项
上图中【表头】部分是可以直接输入内容的。
如果拖动的控件是文本框的话,则会发现点击的时候不会出现上图中的属性选择功能。不过可以通过下面的方法与实体对象绑定
右键单击文本框 选择 【表达式】就会弹出下面对话框
7.最后一步 将对象绑定到PDF上。
private void PDFTest_Load(object sender, EventArgs e) { //this.reportViewer1.RefreshReport(); reportViewer1.LocalReport.DataSources.Clear(); DataTable dt = new DataTable(); Person p = new Person() {Name="X",Favor="OO"}; List<Person> list = new List<Person>(); list.Add(p); dt = ListToDataTable<Person>(list); reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", dt)); reportViewer1.RefreshReport(); } /// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list">泛类型集合</param> /// <returns></returns> public DataTable ListToDataTable<T>(List<T> entitys) { //检查实体集合不能为空 if (entitys == null || entitys.Count < 1) { throw new Exception("需转换的集合为空"); } //取出第一个实体的所有Propertie Type entityType = entitys[0].GetType(); PropertyInfo[] entityProperties = entityType.GetProperties(); //生成DataTable的structure //生产代码中,应将生成的DataTable结构Cache起来,此处略 DataTable dt = new DataTable(); for (int i = 0; i < entityProperties.Length; i++) { //dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType); dt.Columns.Add(entityProperties[i].Name); } //将所有entity添加到DataTable中 foreach (object entity in entitys) { //检查所有的的实体都为同一类型 if (entity.GetType() != entityType) { throw new Exception("要转换的集合元素类型不一致"); } object[] entityValues = new object[entityProperties.Length]; for (int i = 0; i < entityProperties.Length; i++) { entityValues[i] = entityProperties[i].GetValue(entity, null); } dt.Rows.Add(entityValues); } return dt; }
因为数据源绑定的格式是DataTable,所以必须要将对象List转换成DataTable。
这样就大功告成了。
②【卸载Appdomain 时出错】Bug的解决
有个必须注意的问题是必须要在FormClosed事件的回调函数里添加两句代码
private void xxxForm_FormClosed(object sender, FormClosedEventArgs e) { xxxReportViewer.LocalReport.Dispose(); this.Dispose(); }
不添加的话,在关闭程序时会报一个错误【卸载Appdomain 时出错。 (异常来自 HRESULT:0x80131015) 】
③报表中打印多行数据
1.从工具箱将 表 拖到rdlc上
生成的表格有两部分:表头和内容,而内容则是以组的形式存在。将组设置上相关字段即可。
当绑定上有多条数据的DataTable后,就会自动显示多行数据了。
④报表中动态加载图片
如果要导入的图片已经在项目中存在的话,直接指定图片地址就可以了,但如果这个图片是根据数据动态生成的呢?(例如根据一串数字生成的条形码图片)
主要是将图片转化为字符串,然后将字符串放入图片控件
如果图片要放入表格中的话,就需要将相应的表格改变一下属性:
具体步骤:
首先将要绑定到报表的实体类添加一个属性
public string objImgStr { set; get; }
拖一个图片控件到报表设计页面,图像属性-》常规-》选择图像源 选择为数据库,并设置对应字段 objImgStr
在报表加载初期,给绑定到该报表的实例赋值的阶段,将图片转为字符串并赋给objImgStr.
这样就能动态的向报表中添加图片
如果数据有多行,且每行都要有一张对应的图片的话刚才的方法就需要改动一下了
拖动一个图片控件到对应的表格,然后右击图片控件,修改表达式 确定是这种形式: =Fields!ProductImgStr.Value
其他的操作不变