В статье «Как использовать 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 очень просто.