如何在ReportViewer中显示一维数组及WinForm文件列表的数据表?
在ReportViewer中展示一维数组/自定义列表的完整方案
嘿,我来帮你搞定这两个关于WinForm里ReportViewer展示数据的问题,一步步给你讲清楚:
一、从一维数组生成DataTable并在ReportViewer中显示
一维数组的元素其实就是我们要展示的每行数据,核心思路是先把数组转成符合报表要求的DataTable,再绑定到ReportViewer上。
步骤1:把一维数组转成DataTable
假设你的一维数组是字符串类型(比如文件名数组),代码可以这么写:
// 示例一维数组 string[] fileNames = { "20240501_笔记.txt", "20240502_照片.jpg", "20240503_文档.docx" }; // 创建DataTable并定义列 DataTable arrayTable = new DataTable("ArrayData"); arrayTable.Columns.Add("文件名", typeof(string)); // 列名可以根据需求改 // 把数组元素逐行添加到DataTable foreach (string name in fileNames) { arrayTable.Rows.Add(name); }
如果是其他类型的数组(比如int、DateTime),只要把列的typeof()改成对应类型就行。
步骤2:配置RDLC报表
打开你的report.rdlc文件:
- 右键报表空白处 → 添加数据源 → 选择刚才创建的DataTable结构(或者手动新建数据集,字段和DataTable列名对应)
- 拖一个表格控件到报表里,把DataTable的列拖到表格单元格中,调整好样式。
步骤3:在WinForm中绑定到ReportViewer
回到WinForm的代码里,在合适的地方(比如按钮点击事件、窗体加载事件)执行绑定:
// 清空原有数据源,避免冲突 reportViewer1.LocalReport.DataSources.Clear(); // 创建报表数据源,注意第二个参数是我们的DataTable,第一个参数要和RDLC里的数据集名称完全一致 ReportDataSource rds = new ReportDataSource("ArrayDataSet", arrayTable); reportViewer1.LocalReport.DataSources.Add(rds); // 如果还没指定RDLC路径,加上这行(路径根据你的实际文件位置调整) // reportViewer1.LocalReport.ReportPath = @"Reports\report.rdlc"; // 刷新报表,就能看到数据了 reportViewer1.RefreshReport();
二、将BackgroundWorker生成的allfiles列表转成DataTable并展示
你提到的思路是对的——把列表转成DataTable再绑定,我先给你补全列表转DataTable的通用方法,再讲后续的报表绑定步骤。
步骤1:完善列表转DataTable的通用方法
不管你的allfiles是List<FileInfo>还是自定义类的列表,这个通用方法都能搞定:
using System.Reflection; // 要引入这个命名空间 public static DataTable ConvertListToDataTable<T>(List<T> dataList) { DataTable resultTable = new DataTable(); // 获取列表中元素的所有公共属性 PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); // 给DataTable添加列,列名就是属性名,类型和属性类型一致 foreach (PropertyInfo prop in properties) { // 处理可空类型,比如int?、DateTime? Type columnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; resultTable.Columns.Add(prop.Name, columnType); } // 把列表中的每个元素转成DataTable的一行 foreach (T item in dataList) { DataRow row = resultTable.NewRow(); foreach (PropertyInfo prop in properties) { // 处理空值,避免报错 row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; } resultTable.Rows.Add(row); } return resultTable; }
然后调用这个方法把allfiles转成DataTable:
// 假设allfiles是List<FileInfo>(如果是自定义类,替换成你的类名就行) DataTable fileTable = ConvertListToDataTable(allfiles);
步骤2:绑定到ReportViewer并展示
这里要注意:必须在BackgroundWorker的RunWorkerCompleted事件里执行报表绑定,因为后台线程不能直接操作UI控件。代码示例:
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // 这里获取后台线程生成的allfiles列表 List<FileInfo> allfiles = e.Result as List<FileInfo>; if (allfiles == null || allfiles.Count == 0) { MessageBox.Show("没有符合条件的文件"); return; } // 转成DataTable DataTable fileTable = ConvertListToDataTable(allfiles); // 绑定到ReportViewer reportViewer1.LocalReport.DataSources.Clear(); // 注意"FileDataSet"要和RDLC报表里的数据集名称完全匹配 ReportDataSource reportDataSource = new ReportDataSource("FileDataSet", fileTable); reportViewer1.LocalReport.DataSources.Add(reportDataSource); reportViewer1.LocalReport.ReportPath = @"Reports\report.rdlc"; // 你的RDLC路径 reportViewer1.RefreshReport(); }
关键注意点
- RDLC报表里的数据集字段名必须和DataTable的列名完全一致(大小写都要匹配),否则报表会显示空数据
- 如果
allfiles是自定义类,要确保类的属性是public的,不然反射方法获取不到属性 - 后台线程处理完数据后,一定要在
RunWorkerCompleted事件里操作ReportViewer,避免跨线程UI操作报错
内容的提问来源于stack exchange,提问作者Dallon Penney
相关产品推荐
相关产品推荐

