Как использовать FastReport.Net в ASP .NET Web API

22.08.2017

Фреймворк Web API позволяет быстро и просто создавать HTTP-сервисы. В отличие от обычных ASP.Net MVC проектов, Web API не работает с представлениями. Используется контроллер специального вида, методы которого возвращают объекты модели.

Задача такого контроллера передавать данные, а не представления.

Давайте рассмотрим, как создать простой веб-сервис, предоставляющий отчеты FastReport.

1)      Прежде всего создадим два отчета, которые будем отображать.

Шаблон отчета Simple List выглядит так:

Обратите внимание, что заголовок отчета имеет параметр [Parameter]. Нужно добавить параметр отчета с таким именем. Данные для этого отчета можно взять из таблицы Employee демонстрационной базы данных nwind.xml, которую можно найти тут: C:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports.

Шаблон второго отчета не будет содержать данные. Вы можете взять готовый шаблон Barcodes.frx из папки C:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports.

Как уже говорилось выше, мы будем использовать два отчета и одну базу данных в нашем проекте. Добавим их в папку App_Data. Делаем правый клик по этой папке в обозревателе решения. Выбираем Add->Existing item. Таким образом добавляем три файла: Barcode.frx, Simple List.frx, nwind.xml. Либо можно просто перетянуть эти файлы мышью в папку App_Data.

 

2)      Создаем приложение ASP.NET:

Нажимаем Ок и переходим к выбору типа проекта:

Выбираем шаблон Empty.  Внизу отмечаем опции MVC и Web API. Если вы выберите шаблон Web API, то получите проект, заполненный демонстрационными данными.

3)      В Reference добавляем ссылку на библиотеку FastReport.dll.

4)      Теперь, необходимо добавить модель данных. Для этого, в обозревателе решения, выбираем папку Model и делаем правый клик. В контекстном меню выбираем Add->Class:

Называем класс Reports.cs. Тип класса по умолчанию – Class. Нажимаем Add.

В созданный класс добавляем две переменные с методами get и set:

1
2
3
4
5
6
7
8
9
10
namespace FastReportWebApiDemo.Models
{
 public class Reports
 {
 // Report ID
 public int Id { get; set; }
 // Report File Name
 public string ReportName { get; set; }
 }
}

 5) Теперь добавим в проект контроллер. Делаем правый клик по папке Controllers. Из контекстного меню выбираем Add->Controller.

Выбираем шаблон контроллера – Web API2 Controller – Empty:

Назовем его ReportsController:

Переходим к кодированию логики в контроллере. Задача – обеспечить загрузку в браузере или отображение отчета в одном из форматов экспорта: PDF, HTML, png.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using FastReport;
using FastReport.Export.Image;
using FastReport.Export.Html;
using FastReport.Export.Pdf;
using FastReport.Utils;
using FastReportWebApiDemo.Models;
using System.Web.Hosting;
using System.Data;
using System.IO;
using System.Net.Http.Headers;
 
namespace FastReportWebApiDemo.Controllers
{
//Класс параметров в запросе
 public class ReportQuery
 {
 // Format of resulting report: png, pdf, html
 public string Format { get; set; }
 // Value of "Parameter" variable in report
 public string Parameter { get; set; }
 // Enable Inline preview in browser (generates "inline" or "attachment")
 public bool Inline { get; set; }
 }
 
 public class ReportsController : ApiController
 { // Список отчетов
 Reports[] reportItems = new Reports[]
 {
 new Reports { Id = 1, ReportName = "Simple List.frx" },
 new Reports { Id = 2, ReportName = "Barcode.frx" }
 };
 
 // Получить список отчетов
 public IEnumerable<Reports> GetAllReports()
 {
 return reportItems;
 }
 
 // Получить отчет по ID из запроса
 public HttpResponseMessage GetReportById(int id, [FromUri] ReportQuery query)
 {
 // Найти отчет
 Reports reportItem = reportItems.FirstOrDefault((p) => p.Id == id);
 if (reportItem != null)
 {
 string reportPath = HostingEnvironment.MapPath("~/App_Data/" + reportItem.ReportName);
 string dataPath = HostingEnvironment.MapPath("~/App_Data/nwind-employees.xml");
 MemoryStream stream = new MemoryStream();
 try
 {
 using (DataSet dataSet = new DataSet())
 {
//Заполняем источник данными
 dataSet.ReadXml(dataPath);
//Включаем веб режим FastReport
 Config.WebMode = true;
 using (Report report = new Report())
 {
 report.Load(reportPath); //Загружаем отчет
 report.RegisterData(dataSet, "NorthWind"); //Регистрируем данные в отчете
 if (query.Parameter != null)
 {
 report.SetParameterValue("Parameter", query.Parameter); //Устанавливаем значение параметра в отчете. Само значение мы берем из URL
 }
 
 // Две фазы подготовки для исключения отображения каких-либо диалогов
 report.PreparePhase1();
 report.PreparePhase2();
 
 if (query.Format == "pdf")
 {
//Экспорт отчета в PDF
 PDFExport pdf = new PDFExport();
//Используем поток для хранения отчета, чтобы не плодить файлы
 report.Export(pdf, stream);
 }
 else if (query.Format == "html")
 {
//Экспорт отчета в HTML
 HTMLExport html = new HTMLExport();
 html.SinglePage = true;
 html.Navigator = false;
 html.EmbedPictures = true;
 report.Export(html, stream);
 }
 else
 {
//Экспорт в формат изображения
 ImageExport img = new ImageExport();
 img.ImageFormat = ImageExportFormat.Png;
 img.SeparateFiles = false;
 img.ResolutionX = 96;
 img.ResolutionY = 96;
 report.Export(img, stream);
 query.Format = "png";
 }
 }
 }
//создаем результирующую переменную
 HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK)
 {
 Content = new ByteArrayContent(stream.ToArray())
 };
 
 stream.Dispose();
 
 result.Content.Headers.ContentDisposition =
 new System.Net.Http.Headers.ContentDispositionHeaderValue(query.Inline ? "inline" : "attachment")
 {
//Задаем расширение файла в зависимости от типа экспорта
 FileName = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format)
 };
//Определяем тип контента для браузера 
result.Content.Headers.ContentType =
 new MediaTypeHeaderValue("application/" + query.Format);
 return result;
 }
//Обрабатываем исключения
 catch
 {
 return new HttpResponseMessage(HttpStatusCode.InternalServerError);
 }
 }
 else
 return new HttpResponseMessage(HttpStatusCode.NotFound);
 }
 }
}
 

Как видите, мы добавили еще один класс в контроллер. В классе ReportQuery определяются параметры HTTP запроса. Это – format, parameter и inline. Первый определяет формат экспорта отчета, второй – значение параметра в отчете, третий – будет ли отчет открыт непосредственно в браузере.

В классе ReportsController мы создали массив отчетов и два метода. В массиве определены названия и идентификаторы отчетов. Первый метод GetAllReports() возвращает список доступных отчетов. В нашем случае два отчета. Второй метод GetReportById(int id, [FromUri] ReportQuery query) возвращает отчет по идентификатору. Из атрибута query мы можем получить параметры format, inline и parameter. Они определяют: формат экспорта отчета, будет ли отчет открыт непосредственно в браузере, значение параметра передаваемого в отчет.

6)      Добавляем веб страницу в отчет. С помощью нее мы будем передавать запросы серверу с нужными параметрами. Для этого делаем правый клик по имени проекта. Выбираем Add->HTML Page:

 

Назовем страницу index:

 

Добавляем на страницу такой код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
 <title>FastReport.Net Web Api Demo</title>
 <meta charset="utf-8" />
</head>
<body>
 <h1>FastReport.Net Web Api Demo</h1>
 <hr />
 <a href="/api/reports/">List Of All Reports</a><br />
 <a href="/api/reports/1">Get First Report</a><br />
 <a href="/api/reports/2">Get Second Report</a><br />
 <a href="/api/reports/1?format=pdf">Get First Report in PDF</a><br />
 <a href="/api/reports/2?format=html">Get Second Report in HTML</a><br />
 <a href="/api/reports/1?format=pdf&inline=true">Get First Report in PDF inline</a><br />
 <a href="/api/reports/2?format=html&inline=true">Get Second Report in HTML inline</a><br />
 <a href="/api/reports/1?format=pdf&inline=true&parameter=REPORT">Get First Report in PDF inline with Parameter=REPORT</a><br />
 <a href="/api/reports/1?format=html&inline=true&parameter=REPORT">Get First Report in HTML inline with Parameter=REPORT</a><br />
</body>
</html>

Как можно понять из названий, мы можем:

  1. Получить список отчетов;
  2. Получить первый отчет. Исходя из нашего кода в контроллере, если мы явно не передаем параметр format, то отчет будет показан в формате png;
  3. Получить второй отчет;
  4. Получить первый отчет в формате PDF;
  5. Получить второй отчет в формате HTML;
  6. Получить первый отчет в формате PDF и отобразить в браузере;
  7. Получить второй отчет в формате HTML и отобразить в браузере;
  8. Получить первый отчет в формате PDF и отобразить в браузере, а также передать в отчет параметр REPORT;
  9. Получить второй отчет в формате HTML и отобразить в браузере, а также передать в отчет параметр REPORT.

 7)      Открываем файл WebApiConfig.cs из папки App_Start. Добавляем еще один MapHttpRoute для страницы Index:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void Register(HttpConfiguration config)
 {
 // Web API configuration and services
 // Web API routes
 config.MapHttpAttributeRoutes();
 config.Routes.MapHttpRoute(
 name: "Index",
 routeTemplate: "{id}.html",
 defaults: new { id = "index" }
 );
 
 config.Routes.MapHttpRoute(
 name: "DefaultApi",
 routeTemplate: "api/{controller}/{id}",
 defaults: new { id = RouteParameter.Optional }
 );
 }

В этой же папке расположен файл RouteConfig.cs. Его можно удалить.

8)  Последний шаг. Откройте файл Global.asax. Удалите строку: 

1
RouteConfig.RegisterRoutes(RouteTable.Routes); 

Теперь роутинг будет осуществляться только через WebApiConfig.

9)  Запускаем приложение. В браузере видим список команд:

 

  • Первая ссылка открывает список отчетов в виде XML документа:
  • Вторая и третья ссылки приведут к скачиванию первого и второго отчета в формате png;
  • Четвертая ссылка приводит к скачиванию первого отчета в формате PDF;
  • Пятая ссылка приводит к скачиванию второго отчета в формате HTML;
  • Шестая ссылка открывает первый отчет в формате PDF непосредственно в браузере:

  • Седьмая ссылка открывает второй отчет в формате HTML непосредственно в браузере:
  • Восьмая ссылка открывает первый отчет в формате PDF в браузере и передает параметр REPORT:

  • Девятая ссылка открывает первый отчет в формате HTML в браузере и передает параметр REPORT;

На этом все. Работать с FastReport в WebAPI ничуть не сложнее, чем в обычном ASP.Net MVC проекте.

20 ноября 2024

Локализация и смена языков в FastReport VCL

FastReport VCL поддерживает 40 языков для локализации интерфейса и позволяет изменять язык на лету через меню или код, без перекомпиляции.
1 ноября 2024

Новые возможности редактора отчетов FastReport VCL

Рассматриваем новые возможности редактора отчетов: выносные линии, подсветка пересекающихся объектов, обновлённые деревья отчетов и данных.
30 октября 2024

Использование стилей при создании отчетов в FastReport VCL

В статье подробно рассматривается одна из новых возможностей FastReport VCL – применение стилей и страниц стилей.