我试图在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;
}
但是,如果我对函数稍作修改以使我的数据表真正动态,通过从数据库中填充列,我的函数就不会显示在报表向导中.
这是我改变的功能
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;
}
您看,我对该函数所做的唯一更改是从数据库中查询并在循环内生成报告数据集列,这些列遍历数据库数据.
但由于此更改,我的功能不会显示在报表向导中.如果我省略了代码,它会再次出现.
我可以使用这个函数很好地生成GridView,但问题在于RDLC报告.
我的目标是使用数据库结果生成报告数据表.请帮我.
解决方法:
我有相同的需求,并对解决方案进行了一些调查.
我没有尝试过所有这些,但仍列出我认为有意义的那些.
>使用RDL代替RDLC
因为RDLC不容易实现动态列.您可能只想更改为RDL.
>列出所有列,然后隐藏那些您不需要的列
当您的列具有最大限制并且通过使用表达式设置“列可见性”非常容易实现时,此方法有效.
>在运行时创建RDLC
RDLC基于XML,因此在运行时生成适合您数据结构的RDLC是有意义的.
好吧,我没有选择这个,因为我认为RDLC的架构有点复杂,而且我的表实际上很简单,即使它需要动态列.
如果你真的需要使用这个终极解决方案,你可能想搜索是否有某种类型的库可以帮助你构建.
>将表格分成单元格列表,并按组行标识和列标识重新组合
这是我的同事吉米提出的.
有点hacky但我发现如果你的表没有像ColumnSpan这样复杂的结构或东西,它会非常有用.详细如下例所示
ProductName | Qty | Date ----------- | ------ | --------- ProductA | 1 | 2016-01-01 ProductA | 2 | 2016-01-15 ProductA | 3 | 2016-01-31 ProductA | 1 | 2016-02-01 ProductA | 2 | 2017-01-01 ProductA | 3 | 2017-01-15 ProductA | 1 | 2017-01-31 ProductA | 2 | 2017-02-01 ProductA | 3 | 2017-02-15 ProductA | 1 | 2017-02-28 ProductB | 2 | 2016-01-01 ProductB | 3 | 2016-01-15 ProductB | 1 | 2016-01-30 ProductB | 2 | 2016-02-01 ProductB | 3 | 2017-01-01
我需要按月或年总数量,结果需要形成
ProductName | Jan | Feb ----------- | ------ | ------ ProductA | 12 | 7 ProductB | 9 | 2
ProductName | 2016 | 2017 ----------- | ------ | ------ ProductA | 7 | 12 ProductB | 8 | 3
当我按月分组时,我可以列出所有12个月并隐藏那些我不需要的东西.
但是,它逐年不起作用.
实施解决方案4.
首先,准备完全符合您需要的DataTable.
其次,将DataTable划分为List< ReportCell>.
public class ReportCell
{
public int RowId { get; set; }
public string ColumnName { get; set; }
public string Value { get; set; }
public static List<ReportCell> ConvertTableToCells(DataTable table)
{
List<ReportCell> cells = new List<ReportCell>();
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<ReportCell> 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中添加一个表.删除除数据字段以外的所
使用“值”属性设置数据.
并在“RowId”属性上创建详细信息组
现在rdlc应该能够显示完全形成为DataTable的所有内容.
为了更好地理解,我在my GitHub做了一个演示项目.