2009-11-12 2 views
0

ФОН
  • Я пишу метод, который (в конечном счете) принять в качестве входных System.Data.DataTable и сделать его как (простой, табличный) Отчет SSRS в Winform с помощью Microsoft ReportViewer Control (http://www.gotreportviewer.com/)
  • Для этого мне нужно (1) динамически создавать RDL-файл на основе DataTable (2), загружать RDL в ReportViewerControl (3) свяжите ReportViewerControl с этим DataTable

ВОПРОСЫ

  • В идеале я просто хотел бы ссылку на образец, который сделал все вышеперечисленное, - я искал, но не смог его найти.
  • В противном случае мне нужна помощь, особенно с # 1 и # 3 выше.
  • Для # 1 - Есть ли простой способ генерации RDL-файла динамически во время выполнения? (Я уже начинаю писать код, чтобы исправить правильный XML, но повторное использование чего-то будет такое же меня некоторое время)
  • За # 3 - Мне непонятно, как связать ReportViewerControl с DataTable у меня локально. Большинство примеров, которые я нашел, предполагают, что элемент управления ReportViewer будет извлекать данные, которые находятся на удаленном SQL-сервере (что следует ожидать), вместо того, чтобы получать его из локального DataTable.

КОНТЕКСТ

  • Я только недавно, начиная работать с контролем ReportViewer - я нашел образцы прибегая к помощи - но никто, кажется, не охватывают весь СЦЕНАРИЙ
  • Я не знаю, схемы из DataTable раньше времени. Схема DataTable даже не будет постоянной во время вызовов моего метода, который будет отображать его.
  • Я не могу использовать другой элемент управления отчетами - я должен использовать элемент управления ReportViewer. Если вы знаете о других средствах управления отчетами, которые делают эту задачу легкой, пожалуйста, дайте мне знать. Даже если это не решит мою текущую проблему, это полезно позже.
  • Лицо, просматривающее этот отчет, является конечным пользователем и не имеет каких-либо прав на публикацию RDL на сервере SSRS
  • DataTable уже будет сортироваться, фильтроваться и т. Д. Все типы будут просто значениями строк, ints, doubleles и date. DataTable будет иметь разумный размер - 1-30 столбцов и имеет от 100 до 5000 строк. DataTable также создается локально (иногда вручную построенный по коду) и не извлекает данные из некоторого удаленного источника данных.
  • Данные всегда будут отображаться как простая таблица (без диаграмм и т. Д.). Позже мне может понадобиться добавить группу
  • Я не могу переключиться на использование HTML, XAML и т. Д., Чтобы отобразить отчет. В ReportViewer есть функции, которые в конечном итоге я буду использовать, что HTML, XAML и т. Д. Не имеют.

ОБНОВЛЕНИЕ 2010/01/15

Начиная с ответом Джона ниже я смог добиться того, что мне было нужно. Как он упоминает, часть difficut изучает XML-схему RDL и знает, какие элементы RDL писать для достижения желаемого типа отчета.Динамически визуализации DataTable в Winform с помощью SSRS ReportViewer управления

ответ

1

Я сделал именно это за 4 месяца. Мой код находится в VB.NET и довольно длинный. Я начал с кода, указанного в GotReportViewer, и был построен поверх него. В двух словах, это то, что вам нужно будет делать:

  • Рендер и RDLC файла в памяти - с помощью DataTable (или набор данных, для многотабличных отчетов) в качестве входных данных

Для этого , Я создал класс под названием ReportEngine. Это в основном просто куча функций, которые создают файлы RDLC. Это суть всей операции, и код довольно длинный. Вот некоторые из основных функций, которые я использую. Лучше всего было бы просто по электронной почте вам мои классы - как они очень долго:

'Data Building variables 
    Private _reportDataset As DataSet    'Data displayed in report 
    Private _AllFields As List(Of String)   'All column field names 
    Private _AllCaptions As List(Of String)  'All column names to display in report (needed for french translation) 
    Private _reportRDL As MemoryStream   'Report definition file 
    Private _reportControl As ReportControl  'Control that displays the report 

    Public Sub LoadReport(ByVal reportDataset As DataSet) 
    Try 
     _reportDataset = reportDataset 

     'check if the datatable contains data 
     _hasNoData = False 
     If _reportDataset.Tables(0).Rows.Count = 0 Then 
     _hasNoData = True 
     End If 

     'Get table column fieldnames, captions and widths 
     _AllFields = GetTableFields(0) 
     _AllCaptions = GetTableCaptions(0) 

     'reset RDL file if already existing 
     If Not (_reportRDL Is Nothing) Then 
     _reportRDL.Dispose() 
     End If 

     GenerateRdl()     'Create the RDLC file 
     ShowReport()     'Load it into the ReportViewer Control 
     RaiseEvent ReportLoaded(Me)  'Indicate via event that report is loaded and ready to be displayed 

    Catch ex As Exception 
     'Handle error 
    End Try 
    End Sub 



    'returns a list of fields from a datatable used for the report 
    Public Function GetTableFields(ByVal tableIndex As Integer) As List(Of String) 
    Dim dataTable As DataTable = _reportDataset.Tables(tableIndex) 
    Dim availableFields As New List(Of String) 
    Dim i As Integer 
    For i = 0 To dataTable.Columns.Count - 1 
     availableFields.Add(dataTable.Columns(i).ColumnName) 
    Next i 
    Return availableFields 
    End Function 

    'returns a list of captions from a datatable 
    Public Function GetTableCaptions(ByVal tableIndex As Integer) As List(Of String) 
    Dim dataTable As DataTable = _reportDataset.Tables(tableIndex) 
    Dim captions As New List(Of String) 
    Dim i As Integer 
    For i = 0 To dataTable.Columns.Count - 1 
     captions.Add(dataTable.Columns(i).Caption) 
    Next i 
    Return captions 
    End Function 
  • Загрузите файл RDLC в ReportViewer из памяти
  • Добавьте источник данных к элементу управления ReportViewer, с тем же именем указанных в файле RDLC. Если имена не совпадают, вы получите ошибки.

[стартовый код здесь. - блок кода перепутались и не может исправить]

Public Sub DisplayReport(ByVal ms As MemoryStream, ByVal ds As DataSet) 

Dim RowCount As Integer = 0

ReportViewer1.Reset() 
ReportViewer1.LocalReport.DataSources.Clear() 
ReportViewer1.LocalReport.LoadReportDefinition(ms) 

For I As Integer = 0 To Me.ReportEngine.ReportDataSet.Tables.Count - 1 
    'Bind dataTables to the report viewer control - matches the datasources contained in the RDLC files 
    ReportViewer1.LocalReport.DataSources.Add(New ReportDataSource("MyData" + I.ToString, ds.Tables(I))) 

    'Calc total rows returned 
    RowCount += ds.Tables(I).Rows.Count 
Next 

SetupReport() 
ReportViewer1.RefreshReport() 

End Sub 

В любом случае, если у вас есть вопросы , Я мог бы продолжать эти дни. Для этого нужно много сделать.

0
public static DataTable GetDataTabletFromCSVFile(string filePath, bool isHeadings) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      using (TextFieldParser TextFieldParser = new TextFieldParser(filePath)) 
      { 
       if (isHeadings) 
       { 
        MethodResult = GetDataTableFromTextFieldParser(TextFieldParser); 

       } 
       else 
       { 
        MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser); 

       } 

      } 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

    public static DataTable GetDataTableFromCsvString(string csvBody, bool isHeadings) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      MemoryStream MemoryStream = new MemoryStream(); 


      StreamWriter StreamWriter = new StreamWriter(MemoryStream); 

      StreamWriter.Write(csvBody); 

      StreamWriter.Flush(); 


      MemoryStream.Position = 0; 


      using (TextFieldParser TextFieldParser = new TextFieldParser(MemoryStream)) 
      { 
       if (isHeadings) 
       { 
        MethodResult = GetDataTableFromTextFieldParser(TextFieldParser); 

       } 
       else 
       { 
        MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser); 

       } 

      } 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

    public static DataTable GetDataTableFromRemoteCsv(string url, bool isHeadings) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); 
      HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 

      StreamReader StreamReader = new StreamReader(httpWebResponse.GetResponseStream()); 

      using (TextFieldParser TextFieldParser = new TextFieldParser(StreamReader)) 
      { 
       if (isHeadings) 
       { 
        MethodResult = GetDataTableFromTextFieldParser(TextFieldParser); 

       } 
       else 
       { 
        MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser); 

       } 

      } 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 


    private static DataTable GetDataTableFromTextFieldParser(TextFieldParser textFieldParser) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      textFieldParser.SetDelimiters(new string[] { "," }); 

      textFieldParser.HasFieldsEnclosedInQuotes = true; 


      string[] ColumnFields = textFieldParser.ReadFields(); 

      DataTable dt = new DataTable(); 

      foreach (string ColumnField in ColumnFields) 
      { 
       DataColumn DataColumn = new DataColumn(ColumnField); 

       DataColumn.AllowDBNull = true; 

       dt.Columns.Add(DataColumn); 

      } 


      while (!textFieldParser.EndOfData) 
      { 
       string[] Fields = textFieldParser.ReadFields(); 


       for (int i = 0; i < Fields.Length; i++) 
       { 
        if (Fields[i] == "") 
        { 
         Fields[i] = null; 

        } 

       } 

       dt.Rows.Add(Fields); 

      } 

      MethodResult = dt; 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    } 

    private static DataTable GetDataTableFromTextFieldParserNoHeadings(TextFieldParser textFieldParser) 
    { 
     DataTable MethodResult = null; 
     try 
     { 
      textFieldParser.SetDelimiters(new string[] { "," }); 

      textFieldParser.HasFieldsEnclosedInQuotes = true; 

      bool FirstPass = true; 

      DataTable dt = new DataTable(); 

      while (!textFieldParser.EndOfData) 
      { 
       string[] Fields = textFieldParser.ReadFields(); 

       if(FirstPass) 
       { 
        for (int i = 0; i < Fields.Length; i++) 
        { 
         DataColumn DataColumn = new DataColumn("Column " + i); 

         DataColumn.AllowDBNull = true; 

         dt.Columns.Add(DataColumn); 

        } 

        FirstPass = false; 

       } 

       for (int i = 0; i < Fields.Length; i++) 
       { 
        if (Fields[i] == "") 
        { 
         Fields[i] = null; 

        } 

       } 

       dt.Rows.Add(Fields); 

      } 

      MethodResult = dt; 

     } 
     catch (Exception ex) 
     { 
      ex.HandleException(); 
     } 
     return MethodResult; 
    }