В этой статье я хочу рассмотреть возможность работы с отчетом с помощью элементов управления веб формы в проекте ASP .Net MVC.
Итак, задача - создать веб приложение, которое будет позволять:
1) загружать веб отчет;
2) экспортировать отчет в один из трех форматов;
3) отображать/скрывать панель инструментов веб отчета;
4) настраивать стиль кнопок на панели инструментов;
5) запускать отчет в Online дизайнере.
Приступим. Для начала проведем некоторые подготовительные работы, чтобы запустить веб отчет в MVC приложении. Добавляем ссылки на библиотеки: FastReport и FastReport.Web.
В папке Views->Shared нужно отредактировать файл _Layout.cshtml. Добавляем скрипты и стили в заголовок:
Опять же в папке Views есть файл Web.config. Добавляем в него пространства имен:
1 2 3 4 |
<namespaces> <add namespace="FastReport" /> <add namespace="FastReport.Web" /> </namespaces> |
В корне проекта есть еще один Web.config. В него добавляем обработчик, сразу после секции modules:
1 2 3 4 5 6 |
<modules> … </modules> <handlers> <add name="FastReportHandler" path="FastReport.Export.axd" verb="*" type="FastReport.Web.Handlers.WebExport"/> </handlers> |
В HomeController добавляем логику работы с отчетом.
В методе Index будем загружать отчет и передавать его во вью.
1 2 3 4 5 6 7 8 |
public ActionResult Index() { SetReport(); webReport.Width = Unit.Percentage(100); webReport.Height = Unit.Percentage(100); ViewBag.WebReport = webReport; return View(); } |
Я вынес загрузку отчета в отдельный метод, который мы рассмотрим ниже. Устанавливаем ширину и высоту веб отчета в 100%. С помощью ViewBag передаем отчет в представление. И возвращаем представление Index.
Чтобы использовать объект отчета в разных методах я создал глобальную переменную – экземпляр объекта WebReport.
1 |
public WebReport webReport = new WebReport();
|
1) Теперь рассмотрим загрузку отчета:
1 2 3 4 5 6 7 8 |
private void SetReport() { string report_path = GetReportPath(); System.Data.DataSet dataSet = new System.Data.DataSet(); dataSet.ReadXml(report_path + "nwind.xml"); webReport.Report.RegisterData(dataSet, "NorthWind"); webReport.Report.Load(report_path + "Master-Detail.frx"); } |
Задаем путь к папке с отчетами. Для удобства я создал отдельный метод с присвоением переменной пути к отчетам. Далее, создаем экземпляр объекта DataSet. Загружаем в него базу данных XML. Затем, регистрируем источник данных в объекте отчета. И, наконец, загружаем шаблон отчета в объект WebReport.
Метод установки пути к папке с отчетами:
1 2 3 4 |
private string GetReportPath() { return this.Server.MapPath("~/App_Data/"); } |
2) Давайте, не переходя ко вью добавим еще метод выбора экспорта отчета:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public void ReportExport(string type) { SetReport(); switch (type) { case "pdf": webReport.ExportPdf(); break; case "csv": webReport.ExportCsv(); break; default: webReport.ExportWord2007(); break; } |
Тут мы загрузили отчет. В зависимости от значения параметра type производим один из трех видов экспорта.
Теперь откроем представление Index.
Добавим на форму выпадающий список с тремя вариантами экспорта:
1 2 3 4 5 6 7 8 9 10 11 |
@using (Html.BeginForm("ReportExport", "Home")) { @Html.DropDownList("Type", new List<SelectListItem>() { new SelectListItem(){ Text= "PDF", Value = "pdf"}, new SelectListItem(){ Text= "CSV", Value = "csv"}, new SelectListItem(){ Text= "Word", Value = "doc"}, }, "Select export type") <input id="pdf" type="submit" value="Export" /> } @ViewBag.WebReport.GetHtml() |
Здесь мы использовали html хэлпер, с помощью которого создали форму, указывающую на контроллер “Home” и экшен (метод) “ReportExport”. Помните, мы уже создали такой метод в контроллере. Внутри формы мы создаем элемент DropDownList и наполняем его значениями. Конечно, можно было создать модель данных. Но, так как список состоит всего из трех элементов, я заполнил его прямо в представлении. После выпадающего списка расположена кнопка типа submit, по которой будет обновляться веб страница.
Как вы помните, метод ReportExport принимает параметр type – значение из выпадающего списка. В зависимости от выбранного значения будет произведен экспорт отчета в соответствующий формат.
3) Теперь реализуем сокрытие панели инструментов отчета. Во вью это будет выглядеть так:
1 2 3 4 |
@using (Html.BeginForm("Index", "Home")) { @Html.CheckBox("Toolbar", true, new { @onchange = "this.form.submit()" }) Toolbar } |
Как и в предыдущем примере, мы создаем форму. Однако, в этот раз указываем экшен Index – там, где у нас отображается отчет. Внутри формы мы создали элемент CheckBox. Его значение будем передавать в метод Index. На этот раз я решил не добавлять очередную кнопку для обновления страницы, а воспользовался событием @onchange, где указал функцию отправки формы "this.form.submit()". Теперь, при изменении значения checkbox страница будет обновляться.
По аналогии с экспортом отчета, мы должны передать в метод параметр. В данном случае это “Toolbar”. Будет передан строковый эквивалент булевой функции. Перейдем к нашему контролу, а именно к экшену Index:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public ActionResult Index(string toolbar) { SetReport(); webReport.Width = Unit.Percentage(100); webReport.Height = Unit.Percentage(100); if (toolbar == "true") webReport.ShowToolbar = true; else webReport.ShowToolbar = false; ViewBag.WebReport = webReport; return View(); } |
В методе добавился один параметр и условие. В зависимости от значения параметра toolbar мы принимаем решение включать или отключать панель инструментов.
4) Переходим к созданию элементов управления, с помощью которых мы сможем выбирать стиль иконок. В предыдущий пример с формой мы добавим еще четыре элемента RadioButton:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@using (Html.BeginForm("Index", "Home")) { <table> <tr> <td> @Html.CheckBox("Toolbar", true, new { @onchange = "this.form.submit()" }) Toolbar </td> <tr> <tr> <td>Black Buttons:</td><td> @Html.RadioButton("Radio", "Black Buttons", true, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> <tr> <td>Green Buttons:</td><td> @Html.RadioButton("Radio", "Green Buttons", false, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> <tr> <td>Blue Buttons:</td><td>@Html.RadioButton("Radio", "Blue Buttons", false, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> <tr> <td>Red Buttons:</td><td>@Html.RadioButton("Radio", "Red Buttons", false, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> </table> @ViewBag.WebReport.GetHtml() |
Для улучшения внешнего вида, я поместил элементы в таблицу. Рассмотрим один из элементов RadioButton:
Html.RadioButton("Radio", "Black Buttons", true, new { style = "width: 13px;", @onchange = "this.form.submit()" })
Здесь имя контрола – “Radio”. Именно так будет называться еще один параметр в экшене Index. Затем, следует значение – “Black Buttons”. То есть, на панели инструментов будут отображаться черные кнопки. Следующее значение – будет ли отмечена радио кнопка по умолчанию. Последний параметр представляет собой объект HtmlAttributes. Здесь можно указать любой из доступных атрибутов для тэга <input type="radio" />. Я воспользовался этим и указал ширину контрола и событие onchange по аналогии с предыдущим элементом checkbox.
Итак, всего четыре радио кнопки – четыре стиля иконок в панели инструментов. Вернемся к нашему экшену 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 |
public ActionResult Index(string toolbar, string radio) { SetReport(); webReport.Width = Unit.Percentage(100); webReport.Height = Unit.Percentage(100); if (toolbar == "true") webReport.ShowToolbar = true; else webReport.ShowToolbar = false; switch (radio) { case "Red Buttons": webReport.ToolbarIconsStyle = ToolbarIconsStyle.Red; break; case "Green Buttons": webReport.ToolbarIconsStyle = ToolbarIconsStyle.Green; break; case "Blue Buttons": webReport.ToolbarIconsStyle = ToolbarIconsStyle.Blue; break; default: webReport.ToolbarIconsStyle = ToolbarIconsStyle.Black; break; } ViewBag.WebReport = webReport; return View(); } |
Добавился еще один параметр – radio. В конструкции Switch я назначаю нужный стиль, в зависимости от значения radio.
Давайте вынесем обработку параметров toolbar и radio в отдельные методы, для порядка.
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 |
public void ShowToolbar(string toolbar) { if (toolbar == "true") webReport.ShowToolbar = true; else webReport.ShowToolbar = false; } public void ToolbarStyle(string radio) { switch (radio) { case "Red Buttons": webReport.ToolbarIconsStyle = ToolbarIconsStyle.Red; break; case "Green Buttons": webReport.ToolbarIconsStyle = ToolbarIconsStyle.Green; break; case "Blue Buttons": webReport.ToolbarIconsStyle = ToolbarIconsStyle.Blue; break; default: webReport.ToolbarIconsStyle = ToolbarIconsStyle.Black; break; } } |
Index тоже изменился:
1 2 3 4 5 6 7 8 9 10 |
public ActionResult Index(string toolbar, string radio) { SetReport(); webReport.Width = Unit.Percentage(100); webReport.Height = Unit.Percentage(100); ShowToolbar(toolbar); ToolbarStyle(radio); ViewBag.WebReport = webReport; return View(); } |
5) Осталось реализовать последнюю задуманную функцию – запуск отчета в Online дизайнере. Скажу сразу, чтобы его отобразить, необходимо получить сборку OnlineDesigner с сайта разработчика и включить ее в проект. Просто разархивируйте и добавьте всю папку WebReportDesigner в корень проекта.
Добавим в форму из предыдущего примера кнопку и скрытое поле:
По нажатию на кнопку будет отправлена форма. Обратите внимание, что атрибут value определяется через ViewBag. Мы передаем значение кнопки из контрола. Чуть позже вы поймете зачем я так сделал. Для кнопки назначено событие oncklick. В нем я присваиваю значение элементу hidden. Обратите внимание, что благодаря ViewBag я получаю значение свойства веб отчета. Таким образом, если на странице показан Дизайнер отчетов, то значение поля hidden будет ture, иначе false.
Для поля hidden задаем атрибут id=”hid”. Благодаря идентификатору мы находим нужный элемент на форме. Теперь весь код для представления выглядит так:
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 |
@{ ViewBag.Title = "Home Page"; } <div style="float:left"> @using (Html.BeginForm("ReportExport", "Home")) { @Html.DropDownList("Type", new List<SelectListItem>() { new SelectListItem(){ Text= "PDF", Value = "pdf"}, new SelectListItem(){ Text= "CSV", Value = "csv"}, new SelectListItem(){ Text= "Word", Value = "doc"}, }, "Select export type") <input id="pdf" type="submit" value="Export" /> } <div align="left"> @using (Html.BeginForm("Index", "Home")) { <table> <tr> <td> @Html.CheckBox("Toolbar", true, new { @onchange = "this.form.submit()" }) Toolbar </td> <td> <input id="dsg" type="submit" value="@ViewBag.Result" onclick="document.getElementById('hid').value='@ViewBag.WebReport.DesignReport.ToString()'"/> <input id="hid" type="hidden" name="dsg"> </td> <tr> <tr> <td>Black Buttons:</td><td> @Html.RadioButton("Radio", "Black Buttons", true, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> <tr> <td>Green Buttons:</td><td> @Html.RadioButton("Radio", "Green Buttons", false, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> <tr> <td>Blue Buttons:</td><td>@Html.RadioButton("Radio", "Blue Buttons", false, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> <tr> <td>Red Buttons:</td><td>@Html.RadioButton("Radio", "Red Buttons", false, new { style = "width: 13px;", @onchange = "this.form.submit()" })</td> </tr> </table> } </div> </div> @ViewBag.WebReport.GetHtml() |
Перейдем к контроллеру.
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 |
public ActionResult Index(string toolbar, string radio, string dsg) { SetReport(); webReport.Width = Unit.Percentage(100); webReport.Height = Unit.Percentage(100); ShowToolbar(toolbar); ToolbarStyle(radio); ViewBag.Result = ShowDesigner(dsg); ViewBag.WebReport = webReport; return View(); } public string ShowDesigner(string dsg) { if (dsg == "False") { webReport.DesignReport = true; return "Show Report"; } else if (dsg == "True") { webReport.DesignReport = false; return "Show Designer"; } return "Show Designer"; } |
Как видите добавился еще один параметр в методе Index. Его имя соответствует имени элемента hidden во вью. Также добавилась строка: «ViewBag.Result = ShowDesigner(dsg);».
В ней я передаю имя кнопки в представление. Новый метод ShowDesigner включает или отключает дизайнер отчета и возвращает имя кнопки.
Запустим приложение:
Выпадающий список с тремя видами экспорта:
Отключаем тулбар:
А теперь включим онлайн дизайнер отчетов:
Отобразим отчет и включим тулбар. Выберем какой-нибудь стиль для кнопок на тулбаре:
Таким образом, мы создали внешние элементы управления с помощью которых управляем свойствами объекта WebReport в приложении ASP .Net MVC.