Динамически отображать DataTable в Winform, используя элемент управления SSRS ReportViewer - PullRequest
0 голосов
/ 12 ноября 2009

ФОН

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

ВОПРОСЫ

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

КОНТЕКСТ

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

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

Исходя из ответа Джона ниже, я смог достичь того, что мне было нужно. Как он упоминает, самая сложная часть заключается в изучении XML-схемы RDL и знании того, какие элементы RDL нужно написать для достижения желаемого вида отчета.

Ответы [ 2 ]

1 голос
/ 13 ноября 2009

Я сделал именно это за 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 голосов
/ 22 января 2016
    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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...