В первой части статьи мы создали приложение ASP.Net Core в котором реализовали методы: отображение отчета, отображение дизайнера отчета и сохранение измененного в дизайнере отчета на сервер. Но это лишь две функциональные возможности, которые мы заявили. Нам нужно реализовать метод экспорта нужного отчета в формат pdf или html с последующим скачиванием этого отчета. Чтобы пользователь знал какие отчеты возможны для скачивания, мы реализуем метод получения списка отчетов.
Добавим в модель (папка Model) данных структуру данных для списка отчетов:
1 2 3 4 5 6 7 |
public class Reports { // Report ID public int Id { get; set; } // Report File Name public string ReportName { get; set; } } |
Теперь мы можем создать список отчетов с идентификаторами в нашем контроллере:
Как уже говорилось выше, нам нужен список отчетов в клиентском приложении. Он пригодится и для отображения отчета, и для редактирования отчета в дизайнере, и для скачивания отчета в формате pdf или html.
1 2 3 4 5 6 |
//Получаем список отчетов в формате json [HttpGet] public IEnumerable<Reports> Get() { return reportItems; //Возвращает список отчетов. } |
Тут все просто – список отчетов в формате json. А теперь реализуем довольно сложный метод получения экспорта отчета:
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 |
//Получаем файл отчета в pdf/html //Атрибут имеет обязательный параметр id [HttpGet("{id}")] public IActionResult Get(int id, [FromQuery] ReportQuery query) { string mime = "application/" + query.Format; //MIME-заголовок со значением по умолчанию // Найти отчет Reports reportItem = reportItems.FirstOrDefault((p) => p.Id == id); //получаем значение коллекции по идентификатору if (reportItem != null) { string reportPath = (webRoot + "/App_Data/" + reportItem.ReportName); //определяем путь к отчету string dataPath = (webRoot + "/App_Data/nwind.xml");//определяем путь к базе данных using (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.Prepare();//подготавливаем отчет //если выбран формат pdf if (query.Format == "pdf") { //Экспорт отчета в PDF PDFExport pdf = new PDFExport(); //Используем поток для хранения отчета, чтобы не создавать лишние файлы report.Export(pdf, stream); } //если выбран формат отчета html else if (query.Format == "html") { //Экспорт отчета в HTML HTMLExport html = new HTMLExport(); html.SinglePage = true; //отчет на одной странице html.Navigator = false; //навигационная панель сверху html.EmbedPictures = true; //встраивает изображения в документ report.Export(html, stream); mime = "text/" + query.Format; //переопределяем mime для html } } } //получаем имя результирующего файла отчета с нужным расширением var file = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format); //скачиваем файл отчета return File(stream.ToArray(), mime, file); // attachment } //Обрабатываем исключения catch { return new NoContentResult(); } finally { stream.Dispose(); } } } else return NotFound(); } |
Этот метод получает два параметра на вход: id и query. Первый – это идентификатор отчета из нашего списка, а второй – набор параметров отчета, который мы укажем в url. Мы рассмотрим этот набор ниже, а пока продолжим с методом Get.
Метод SetParameterValue задает значение параметра, который мы передаем в url, если это не обходимо. Это просто демонстрация возможностей.
Как видите, из параметра format мы узнаем, что выбрал пользователь. В нашем случае это может быть pdf или html. В зависимости от формата осуществляется экспорт отчета. Каждый тип экспорта имеет свои настройки. В итоге экспорт сохраняется в поток, а из него преобразуется в файл для скачивания.
Теперь вернемся ко второму параметру метода Get – query. Он имеет тип ReportQuery. Создадим этот класс в модели данных:
1 2 3 4 5 6 7 8 |
//Структура запроса отчета public class ReportQuery { // Format of resulting report: pdf, html public string Format { get; set; } // Value of "Parameter" variable in report public string Parameter { get; set; } } |
Как вы поняли методы Get взяты из WebAPI. Этот проект является гибридом, он имеет и View часть и интерфейс WebAPI.
Таким образом, чтобы получить представление, отображающее отчет вы должны формировать url вида:
https://localhost:44346/api/reports/ShowReport?name=ReportName.frx
Для получения представления с дизайнером отчета ссылка будет отличаться лишь названием метода:
https://localhost:44346/api/reports/Designer?name=ReportName.frx
Но, чтобы получить имя отчета, вам необходим список доступных отчетов в клиентском приложении. Получить список отчетов в формате json можно с помощью url:
https://localhost:44346/api/reports/
Чтобы скачать отчет в выбранном формате вы сформируете url вида:
https://localhost:44346/api/reports/1?format=pdf
Где номер отчета соответствует id из списка отчетов на сервере, а формат может иметь значения: pdf или html. Кроме того, вы можете указать параметр отчета, если он есть в вашем шаблоне отчета. Тогда url будет выглядеть так:
https://localhost:44346/api/reports/1?format=pdf¶meter=REPORT
При этом сам параметр в отчете должен называться Parameter, а его значение берется из url. По аналогии вы можете придумать сколько вам угодно параметров в url.
На этом работу с серверной частью мы закончили. В следующей части статьи мы рассмотрим, как все это использовать в клиентском приложении на PHP.