【问题标题】:Generate columns dynamically in RDLC在 RDLC 中动态生成列
【发布时间】:2015-05-08 00:24:12
【问题描述】:

我正在尝试在 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 报告。

我的目标是使用数据库结果生成报告数据表。请帮帮我。

【问题讨论】:

    标签: c# asp.net reporting-services rdlc dynamic-rdlc-generation


    【解决方案1】:

    我有同样的需求,对解决方案做了一些调查。
    我没有全部尝试,但仍然列出了我认为有意义的那些。

    1. 使用 RDL 代替 RDLC
      因为RDLC不容易实现动态列。您可能只想更改为 RDL。
    2. 列出所有列,然后隐藏不需要的列
      当您的列有最大限制并且通过使用表达式设置“列可见性”很容易实现时,此方法有效。

    3. 在运行时创建 RDLC
      RDLC 基于 XML,因此您可以在运行时生成适合您的数据结构的 RDLC。
      好吧,我没有选择这个,因为我认为 RDLC 的架构有点复杂,而且我的表实际上很简单,即使它需要动态列。
      如果您真的需要使用这个终极解决方案,您可能需要搜索是否有某种库可以帮助您进行构建。

    4. 将表格分成单元格列表并按组行和列标识重新组合它们
      这是我的同事吉米建议的。 有点老套,但我发现如果您的表没有像 ColumnSpan 或其他东西这样的复杂结构,它非常有用。详情如下例

    产品名称 |数量 |日期 ------------ | ------ | --------- 产品A | 1 | 2016-01-01 产品A | 2 | 2016-01-15 产品A | 3 | 2016-01-31 产品A | 1 | 2016-02-01 产品A | 2 | 2017-01-01 产品A | 3 | 2017-01-15 产品A | 1 | 2017-01-31 产品A | 2 | 2017-02-01 产品A | 3 | 2017-02-15 产品A | 1 | 2017-02-28 产品B | 2 | 2016-01-01 产品B | 3 | 2016-01-15 产品B | 1 | 2016-01-30 产品B | 2 | 2016-02-01 产品B | 3 | 2017-01-01

    我需要按月或年汇总数量,结果需要形成

    产品名称 |一月 |二月 ------------ | ------ | ------ 产品A | 12 | 7 产品B | 9 | 2 产品名称 | 2016 | 2017 ------------ | ------ | ------ 产品A | 7 | 12 产品B | 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;
        }
    }
    

    第三,使用这个List作为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 中添加一个表。删除除数据字段之外的所有内容。
    使用“值”属性设置数据。

    然后通过“ColumnName”属性添加父组(删除排序)

    并在“RowId”属性上创建详细信息组 现在 rdlc 应该能够显示与 DataTable 完全相同的所有内容。

    为了更好的理解,我在my GitHub做了一个演示项目。

    【讨论】:

      【解决方案2】:

      我不确定您的问题是否过于优雅。 不可能创建真正的临时报告。解决方法是这样的。 - 创建 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()

      这里的关键是报表数据源的名称。它应该与您为设计报告而创建的虚拟数据集/数据表完全匹配

      【讨论】:

        猜你喜欢
        • 2014-10-24
        • 1970-01-01
        • 1970-01-01
        • 2017-02-08
        • 1970-01-01
        • 2018-01-10
        • 1970-01-01
        • 1970-01-01
        • 2012-07-01
        相关资源
        最近更新 更多