Как получить отчет от FastReport WebApi с помощью ajax

23.08.2017

В статье «Как использовать FastReport.Net в ASP.NET Web API» мы уже рассмотрели, как создать веб сервис для генерации отчетов. Тогда мы получали отчеты по ссылке, теперь рассмотрим, как получать отчет и отображать с помощью ajax скрипта.

Напомню, наш сервис может возвращать отчет в одном из форматов экспорта: PDF, HTML, png. Мы же будем получать отчет в HTML формате и выводить его на веб странице с помощью ajax скрипта.

Рассмотрим процесс создания WebApi приложения с «нуля». Создаем приложение ASP.Net. WebApi. Выбираем шаблон Empty и отмечаем опции: MVC и WebApi.

 

В ссылки проекта добавляем библиотеку FastReport.dll.

Переходим к созданию модели данных. Сейчас папка Model пуста. Кликнем по ней правой кнопкой и выберем Add(Добавить), Class (Класс).

Назовем его Reports.cs. Добавим два поля: Id и ReportName:

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; }
 }
}

В папку App_Data нужно положить шаблоны отчетов и файл базы данных. В нашем случае это два отчета: "Simple List.frx" и "Barcode.frx";

Теперь, в папку Controllers добавим контроллер ReportsController. В нем будет вся логика приложения. Делаем это с помощью контекстного меню для папки Controllers. Выбираем Add -> Controller:

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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
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 if (query.Format == "png")
 {
//Экспорт отчета в PNG
 using (ImageExport img = new ImageExport())
 {
 img.ImageFormat = ImageExportFormat.Png;
 img.SeparateFiles = false;
 img.ResolutionX = 96;
 img.ResolutionY = 96;
 report.Export(img, stream);
 query.Format = "png";
 }
 }
 else
 {
 WebReport webReport = new WebReport();//Создаем объект отчета
 webReport.Report.Load(reportPath); //Загружаем отчет 
 webReport.Report.RegisterData(dataSet, "NorthWind"); //Регистрируем источник данных в отчете
 if (query.Parameter != null)
 {
 webReport.Report.SetParameterValue("Parameter", query.Parameter); //Задаем значение параметра отчета
 }
 // inline registration of FastReport javascript
 webReport.InlineRegistration = true;//Позволяет регистрировать скрипты и стили в теле html-страницы вместо размещения их в заголовке
 webReport.Width = Unit.Percentage(100);
 webReport.Height = Unit.Percentage(100);
 // get control
 HtmlString reportHtml = webReport.GetHtml(); //загружаем отчет в HTML
 byte[] streamArray = Encoding.UTF8.GetBytes(reportHtml.ToString());
 stream.Write(streamArray, 0, streamArray.Length);//Записываем отчет в поток 
 } 
}
 }
//создаем результирующую переменную
 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);
 }
 }
}

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

 В файл Web.config нужно добавить два хендлера:

1
2
3
4
5
6
<handlers>

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
 <add name="FastReportHandler" path="FastReport.Export.axd" verb="*" type="FastReport.Web.Handlers.WebExport" />

</handlers>

Теперь добавим веб страницу. Делаем правый клик по проекту и выбираем Add->HTML Page.

 Традиционно называем стартовую страницу Index. Добавляем на страницу следующий код:

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
<!DOCTYPE html>
<html>
<head>
 <title></title>
 <meta charset="utf-8" />
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
</head>
<body>
 <script type="text/javascript" language="javascript">
 function call() {
 var msg = $('#formx').serialize();
 $.ajax({ 
 type: 'GET',// Метод передачи
 url: 'http://localhost:58005/api/reports/1', // Получаем файл от Rest сервиса 
 cache: false,// Кеширование
 timeout: 30000,// Верямя ожидания ответа
 data: msg,
 success: function (data) {// Функция сработает при успешном получении данных 
 $('#results').html(data);// Отображаем данные в форме
 },
 beforeSend: function (data) {// Функция срабатывает в период ожидания данных
 $('#results').html('<p>Ожидание данных...</p>');
 },
 dataType: "html", // Тип данных 
 error: function (data) {// Функция сработает в случае ошибки
 $('#results').html('<p>Не удалось загрузить отчет</p>');
 }
 });
 }
 </script>
<form method="GET" id="formx" action="javascript:void(null);" onsubmit="call()">
 <input value="Загрузить" type="submit">
 </form>
 <div id="results" typeof="submit"></div><!--Тут будет выведен результат-->
</body>
</html>

Как понятно из кода, мы просто загружаем HTML файл отчета, запросив его по ссылке у сервиса.

Открываем файл 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. Его можно удалить.

Откройте файл Global.asax. Удалите строку: 

1
RouteConfig.RegisterRoutes(RouteTable.Routes); 

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

Запускаем приложение и нажимаем кнопку «Загрузить»:

 

Получаем наш отчет.

Из рассмотренного примера понятно, что работать с веб сервисом для отчетов при помощи Ajax очень просто.

20 ноября 2024

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

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

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

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

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

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