Как отобразить много отчетов на одной странице в Blazor

Как отобразить несколько отчетов на одной странице в Blazor

Нередко у наших пользователей появляется необходимость отобразить два отчета с разными данными на одной странице. Представим ситуацию, где вам нужно сравнить отчёты за первый и последний месяц. Для решения вашей задачи у нас есть поддержка Blazor WebReport.

Пример использования двух отчетов на одной странице в Blazor

Давайте рассмотрим подробнее как это реализовать в вашем Blazor-приложении. За основу возьмем демо-приложение из статьи “Отчеты и PDF документы в приложении Blazor” и уберем оттуда всё лишнее.

Для начала давайте попробуем просто отобразить два отчета на одной странице. Заходим в файл “Pages\Index.razor.cs”.

После этого добавляем второй отчет. Не забываем сначала его объявить и зарегистрировать для него данные, а затем написать следующий кусочек кода:

Report Report2 { get; set; }
 
 Report2 = Report.FromFile(reportPath);
 Report2.RegisterData(DataSet, "NorthWind");

Отлично, теперь давайте отобразим наш отчет. Переходим к файлу “Pages\Index.razor.cs” и вписываем необходимый код:

 UserWebReport2 = new WebReport
 {
 Report = Report2,
 Toolbar = toolbar2
 };

Теперь наш файл будет выглядеть примерно так:

 public partial class Index
 {
 readonly string directory;
 const string DEFAULT_REPORT = "Filter Employees.frx";
 public Report Report1 { get; set; }
 public Report Report2 { get; set; }
 public WebReport UserWebReport { get; set; }
 
 public WebReport UserWebReport2 { get; set; }
 
 DataSet DataSet { get; }
 
 
 protected override void OnParametersSet()
 {
 base.OnParametersSet();
 
 string path = 
 Path.Combine(
 directory,
 string.IsNullOrEmpty(ReportName) ? DEFAULT_REPORT : ReportName);
 
 Report1 = Report.FromFile(path);
 Report2 = Report.FromFile(path);
 
 // Registers the application dataset
 Report1.RegisterData(DataSet, "NorthWind");
 Report2.RegisterData(DataSet, "NorthWind");
 
 
 ToolbarSettings toolbarSettings1 = new ToolbarSettings()
 {
 Color = Color.Red,
 IconColor = IconColors.White,
 Position = Positions.Left,
 };
 
 ToolbarSettings toolbarSettings2 = new ToolbarSettings()
 {
 Color = Color.Black,
 IconColor = IconColors.White,
 Position = Positions.Right,
 };
 
 UserWebReport = new WebReport
 {
 Report = Report1,
 Toolbar = toolbarSettings1,
 };
 UserWebReport2 = new WebReport
 {
 Report = Report2,
 Toolbar = toolbarSettings2,
 };
 }
 
 public Index()
 {
 directory = Path.Combine(
 Directory.GetCurrentDirectory(),
 Path.Combine("..", "..", "Reports"));
 
 DataSet = new DataSet();
 DataSet.ReadXml(Path.Combine(directory, "nwind.xml"));
 }
 }

Замечательно, теперь заходим в файл “Pages/Index.razor” и вписываем в него второй компонент: 

<WebReportContainer WebReport="@UserWebReport2"/>

Посмотреть на результат можно запустив наше Blazor-приложение и открыв любой отчет. Для наглядности мы выбрали отчёт с графиками и диаграммами.  

Отображение двух отчетов в Blazor

А что если:
- мы хотим увидеть разные данные в этих отчетах;
- мы хотим увидеть разные отчеты на каждом листе;
- мы хотим увидеть, отчет в котором содержаться работники и их зарплаты помесячно;
- мы хотим увидеть отчеты с данными за Сентябрь, а во втором за Октябрь;
- мы хотим быстро открывать другой отчет не закрывая первый.

И на все эти ситуации будет один ответ. Это можно реализовать!

Воспользуемся FastReport .NET, в котором мы откроем дизайнер отчетов и изменим наш стандартный Simple List.frx. Подключаем новый источник данных, в нашем случае это будет XML:

Подключение нового источника данных

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

Редактирование отчета

Теперь требуется создать условие, по которому будем фильтровать данные. Нажмем два раза по колонке “Данные” слева. Затем во вкладке “Фильтр” напишем условие как на скриншоте ниже. 

Фильтрация данных в отчете

На этом моменте можно сохранять отчет и открывать наше демо-приложение. Давайте напишем небольшой кусочек кода в файле “Pages/Index.razor”:

 public EventCallback Filter1()
 {
 UserWebReport.Report.Load(Path.Combine(directory,firstReport));
 UserWebReport.Report.SetParameterValue("Month", Select1);
 return default;
 }
 public EventCallback Filter2()
 {
 UserWebReport2.Report.Load(Path.Combine(directory,secondReport));
 UserWebReport2.Report.SetParameterValue("Month", Select2);
 return default;
 }
 public EventCallback ChangeReport1(){
 
 UserWebReport.Report.Load(Path.Combine(directory,firstReport));
 return default;
 }
 
 public EventCallback ChangeReport2(){
 
 UserWebReport2.Report.Load(Path.Combine( directory, secondReport));
 return default;
 }

Теперь давайте добавим на страницу с отчетом 4 выпадающих списка для фильтрации данных и переключения между отчетами:

 <div style="display:flex;flex-direction:column;">
 <div style="display:flex;flex-direction:row;">
 <div style="display:flex;flex-direction:column;">
 <select style= "margin-left:370px;" @onclick=ChangeReport1() @bind="@firstReport">
 <option>Simple List.frx</option>
 <option>Chart.frx</option>
 <option>Filter Employees.frx</option>
 </select>
 @if (@firstReport == "Filter Employees.frx")
 {
 <select style= "margin-left:400px;" @onclick=Filter1() @bind="@Select1">
 <option>September</option>
 <option>October</option>
 <option>November</option>
 </select>
 }
 </div>
 <div style="display:flex;flex-direction:column;">
 <select style= "margin-left:614px;" @onclick=ChangeReport2() @bind="@secondReport">
 <option>Simple List.frx</option>
 <option>Chart.frx</option>
 <option>Filter Employees.frx</option>
 </select>
 @if (@secondReport == "Filter Employees.frx")
 {
 <select style= "margin-left:681px;" @onclick=Filter2() @bind="@Select2">
 <option>September</option>
 <option>October</option>
 <option>November</option>
 </select>
}
 </div>
 </div> 

Файл Pages/Index.razor после всех изменений будет выглядеть примерно так: 

@page "/"
@using System.IO;
@using System.Data;
 
 <div style="display:flex;flex-direction:column;">
 <div style="display:flex;flex-direction:row;">
 <div style="display:flex;flex-direction:column;">
 <select style= "margin-left:370px;" @onclick=ChangeReport1() @bind="@firstReport">
 <option>Simple List.frx</option>
 <option>Chart.frx</option>
 <option>Filter Employees.frx</option>
 </select>
 @if (@firstReport == "Filter Employees.frx")
 {
 <select style= "margin-left:400px;" @onclick=Filter1() @bind="@Select1">
 <option>September</option>
 <option>October</option>
 <option>November</option>
 </select>
 }
 </div>
 <div style="display:flex;flex-direction:column;">
 <select style= "margin-left:614px;" @onclick=ChangeReport2() @bind="@secondReport">
 <option>Simple List.frx</option>
 <option>Chart.frx</option>
 <option>Filter Employees.frx</option>
 </select>
 @if (@secondReport == "Filter Employees.frx")
 {
 <select style= "margin-left:681px;" @onclick=Filter2() @bind="@Select2">
 <option>September</option>
 <option>October</option>
 <option>November</option>
 </select>
 }
 </div>
 </div> 
 <div style="display:flex;flex-direction:row;">
 <WebReportContainer WebReport="@UserWebReport"/>
 
 <WebReportContainer WebReport="@UserWebReport2"/>
 </div>
</div>

 

@code {
 
 private string dir = Path.Combine(
 Directory.GetCurrentDirectory(),
 Path.Combine("..","..", "Demos", "Reports"));
 
 [Parameter]
 public string ReportName { get; set; }
 
 [Parameter]
 public string Select1 { get; set; } = "September";
 
 [Parameter]
 public string Select2 { get; set; } = "October";
 
 [Parameter]
 public string firstReport { get; set; } = "Filter Employees.frx";
 
 [Parameter]
 public string secondReport { get; set; } = "Filter Employees.frx";
 
 public EventCallback Filter1()
 {
 UserWebReport.Report.Load(Path.Combine(directory,firstReport));
 UserWebReport.Report.SetParameterValue("Month", Select1);
 return default;
 }
 public EventCallback Filter2()
 {
 UserWebReport2.Report.Load(Path.Combine(directory,secondReport));
 UserWebReport2.Report.SetParameterValue("Month", Select2);
 return default;
 }
 public EventCallback ChangeReport1(){
 
 UserWebReport.Report.Load(Path.Combine(directory,firstReport));
 return default;
 }
 
 public EventCallback ChangeReport2(){
 
 UserWebReport2.Report.Load(Path.Combine( directory, secondReport));
 return default;
 }
 
}

Хочется немного разнообразить отчёт. Заходим в файл “Pages/Index.razor.cs” для того, чтобы раскрасить наши панели инструментов при одновременной работе с ними. Добавляем следующий код: 

 ToolbarSettings toolbarSettings1 = new ToolbarSettings()
 {
 Color = Color.Red,
 IconColor = IconColors.White,
 Position = Positions.Left,
 };
 
 ToolbarSettings toolbarSettings2 = new ToolbarSettings()
 {
 Color = Color.Black,
 IconColor = IconColors.White,
 Position = Positions.Right,
 };

На этом моменте можно запустить демо-приложение и посмотреть на результат:

Отображение двух отчетов в демо-приложении Blazor

Выглядит неплохо, но можно ещё немного улучшить. Следующим шагом будет добавление фильтрации во второй отчет с помощью выпадающих списков сверху: 

Фильтрация отчетов с помощью выпадающих списков

Отлично, теперь изменим отчет во втором компоненте: 

Отображение двух разных отчётов

Таким образом можно не только отображать два отчета на одной странице, но также и проводить с ними различные манипуляции. Например, попробуйте фильтровать данные или вообще смотреть на разные отчёты одновременно как было показано выше. В наших WebReport для вашего удобства имеется возможность кастомизировать панель инструментов для каждого отчета под свои нужды.

Нельзя не отметить, что два отчета - это не предел и их может быть даже 10 на одной странице! И да, с каждым из них можно будет без проблем проводить всевозможные действия.

Демонстрацию работы проекта из этой статьи вы сможете найти по следующему пути: FastReport.Net Trial\Demos\Core\FastReport.Blazor.DoubleReports