在RDLC中动态生成列
我试图在ASP.NET中生成一个RDLC报告,其中我的数据集的列将是动态的,并且仅在运行时确定。
我有一个返回DataTable的函数,通过在RDLC报告向导中选择此函数, 我可以成功生成我的报告。
public DataTable GetTable() { // Here we create a DataTable with four columns. DataTable table = new DataTable(); table.Columns.Add("Dosage", typeof(int)); table.Columns.Add("Drug", typeof(string)); table.Columns.Add("Patient", typeof(string)); table.Columns.Add("Date", typeof(DateTime)); table.Columns.Add("testColumn", typeof(DateTime)); // Here we add five DataRows. table.Rows.Add(25, "Indocin", "David", DateTime.Now); table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now); table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now); table.Rows.Add(21, "Combivent", "Janet", DateTime.Now); table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now); return table; }
但是,如果我对函数稍作更改以使我的数据表真正动态,通过从数据库填充列,我的函数就不会显示在报表向导中。
这是我改变的function
public DataTable GetTable2() { // Here we create a DataTable with four columns. DataTable table = new DataTable(); table.Columns.Add("Dosage", typeof(int)); table.Columns.Add("Drug", typeof(string)); table.Columns.Add("Patient", typeof(string)); table.Columns.Add("Date", typeof(DateTime)); table.Columns.Add("testColumn", typeof(DateTime)); SqlConnection connection = new SqlConnection(); connection = Connection.getConnection(); connection.Open(); string tableName = ""; tableName += "Subject"; string Query = "select * from " + tableName + " where Status = 0;"; SqlDataAdapter da = new SqlDataAdapter(Query, connection); DataSet ds = new DataSet(); da.Fill(ds); DataRowCollection collection = ds.Tables[0].Rows; foreach (DataRow row in collection) { // Here we add five DataRows. table.Rows.Add(25, "Indocin", "David", DateTime.Now); table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now); table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now); table.Rows.Add(21, "Combivent", "Janet", DateTime.Now); table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now); } connection.Close(); return table; }
您看,我对该函数所做的唯一更改是从数据库中查询并在循环内生成报告数据集列,这些列遍历数据库数据。 但由于此更改,我的function不会显示在报表向导中。 如果我省略代码,它会再次出现。
我可以使用这个函数很好地生成GridView,但问题在于RDLC报告。
我的目标是使用数据库结果生成报告数据表。 请帮我。
我有相同的需求,并对解决方案进行了一些调查。
我没有尝试过所有这些,但仍列出我认为有意义的那些。
- 使用RDL代替RDLC
因为RDLC不容易实现动态列。 您可能只想更改为RDL。 -
列出所有列,然后隐藏那些您不需要的列
当您的列具有最大限制并且通过使用表达式设置“列可见性”而非常容易实现时,此方法有效。 -
在运行时创建RDLC
RDLC基于XML,因此在运行时生成适合您数据结构的RDLC是有意义的。
好吧,我没有选择这个,因为我认为RDLC的架构有点复杂,而且我的表实际上很简单,即使它需要动态列。
如果你真的需要使用这个终极解决方案,你可能想搜索是否有某种类型的库可以帮助你构建。 -
将表划分为单元格列表,并按组行标识和列标识重新组合
这是我的同事吉米提出的。 有点hacky但我发现如果你的表没有像ColumnSpan这样的复杂结构或东西,它会非常有用。 详细如下例所示
产品名称| 数量| 日期 ----------- ------ | --------- ProductA | 1 | 2016年1月1日 ProductA | 2 | 2016年1月15日 ProductA | 3 | 2016年1月31日 ProductA | 1 | 2016年2月1日 ProductA | 2 | 2017年1月1日 ProductA | 3 | 2017年1月15日 ProductA | 1 | 2017年1月31日 ProductA | 2 | 2017年2月1日 ProductA | 3 | 2017年2月15日 ProductA | 1 | 2017年2月28日 ProductB | 2 | 2016年1月1日 ProductB | 3 | 2016年1月15日 ProductB | 1 | 2016年1月30日 ProductB | 2 | 2016年2月1日 ProductB | 3 | 2017年1月1日
我需要按月或年总数量,结果需要形成
产品名称| Jan | 二月 ----------- ------ | ------ ProductA | 12 | 7 ProductB | 9 | 2
产品名称| 2016 | 2017年 ----------- ------ | ------ ProductA | 7 | 12 ProductB | 8 | 3
当我按月分组时,我可以列出所有12个月并隐藏那些我不需要的东西。
但是,一年又一年不会起作用。
实施解决方案4。
首先,准备完全符合您需要的DataTable。
其次,将DataTable划分为List
。
public class ReportCell { public int RowId { get; set; } public string ColumnName { get; set; } public string Value { get; set; } public static List ConvertTableToCells(DataTable table) { List cells = new List (); foreach (DataRow row in table.Rows) { foreach (DataColumn col in table.Columns) { ReportCell cell = new ReportCell { ColumnName = col.Caption, RowId = table.Rows.IndexOf(row), Value = row[col.ColumnName].ToString() }; cells.Add(cell); } } return cells; } }
第三,使用此列表作为ReportViewer的源。
// in DAO public List GetReportCells(DataTable table) { return ReportCell.ConvertTableToCells(table); } // in aspx.cs ReportViewer_main.LocalReport.ReportPath = Server.MapPath("~/RDLC/Report_main.rdlc"); ReportViewer_main.LocalReport.DataSources.Add( new ReportDataSource("DataSet1", dao.GetReportCells(tableGroupByMonth))); ReportViewer_main.LocalReport.Refresh();
最后,在RDLC中添加一个表。 删除除数据字段以外的所
使用“Value”属性设置数据。
然后通过“ColumnName”属性添加父组(删除排序)
并在“RowId”属性上创建详细信息组 现在,rdlc应该能够显示完全形成为DataTable的所有内容。
为了更好地理解,我在GitHub上制作了一个演示项目。
我不确定你的问题是否过于优雅。 无法创建真正的临时报告。 解决这个问题的方法。 – 创建rdlc文件 – 以您从中获取数据的格式创建数据集xsd文件。 您必须手动执行此操作,并且每列应与最终输出匹配 – 将rdlc文件绑定到此数据集数据源 – 设计报表
现在在查询生成部分中,您必须将动态数据绑定到rdlc,就像这样
Dim repDS As New Microsoft.Reporting.WebForms.ReportDataSource repDS.Value = dT repDS.Name = "dsConsolReq_dt1" 'hard coded here, but you should get it dynamically perhaps from the querystring or the db RV1.LocalReport.DataSources.Clear() RV1.LocalReport.DataSources.Add(repDS) RV1.LocalReport.ReportPath = "Reports\rep_itemr1.rdlc" 'same again, use dynamic values RV1.ProcessingMode = Microsoft.Reporting.WebForms.ProcessingMode.Local RV1.LocalReport.Refresh()