3

Я пытаюсь создать отчет 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; 
    } 

enter image description here

enter image description here

Но, если бы я сделать небольшие изменения в функцию так, что мой DataTable действительно динамичен, путем заполнения столбцов из базы данных, моя функция, то не показывает в мастере отчетов.

Это моя измененная функция

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.

Моей целью является создание отчета, относящегося к данным, с использованием результатов базы данных. Пожалуйста, помогите мне.

ответ

1

Я не уверен, что ваш вопрос оформлен слишком элегантно. Невозможно создать действительно специальный отчет. Работа над этим. - Создайте файл 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()

ключевым моментом здесь является имя источника данных отчета. Он должен точно соответствовать фиктивному набору данных/datatable, который вы создали для разработки вашего отчета.

3

У меня был такой же спрос, и я сделал небольшой обзор решений.
Я не пробовал их всех, но все же перечислял те, которые, как мне кажется, имеют смысл.

  1. Использование RDL вместо RDLC
    Поскольку RDLC не легко достигнуть динамических столбцов. Вы можете просто изменить RDL.
  2. Список всех столбцов затем скрыть те, что вам не нужно
    Это работает, когда ваши колонки имеют максимальное ограничение и довольно легко осуществить, установив «видимость столбца» с выражением.

  3. Создать RDLC во время выполнения
    RDLC основан на XML, так что имеет смысл, что вы генерировать RDLC во время выполнения, который соответствовать вашей структуре данных.
    Ну, я не выбрал это, так как я думаю, что схема RDLC немного сложна, плюс моя таблица на самом деле простая, даже для нее нужны динамические столбцы.
    Если вам действительно нужно использовать это окончательное решение, вы можете захотеть найти, есть ли какие-то библиотеки, которые могут помочь вам в построении.

  4. Разделить таблицу в список ячеек и сборка их группы строки и столбцы идентичность
    Это было предложено моей коллегой Джимми. Немного взломанный, но я нашел его очень полезным, если ваш стол не имеет сложных структур, таких как 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 добавьте таблицу. Удалите все, кроме поля данных.
Задайте данные с помощью свойства «Значение». enter image description here

Затем добавить родительскую группу По свойству «ColumnName» (Удалить сортировку) enter image description here

и сделать Подробности группы по недвижимости «RowId» enter image description here Теперь RDLC должен иметь возможность показать все точно сформированную как DataTable.

Для лучшего понимания, я сделал демонстрационный проект на my GitHub.

Смежные вопросы