Как загрузить отчет в Online Designer и скачать отредактированный отчет

Один из первых вопросов, который встает перед пользователями Online Designer – как организовать загрузку отчетов с локального компьютера? Сегодня мы рассмотрим загрузку из локального компьютера в Online Designer и скачивание измененного отчета на примере ASP.Net MVC приложения.

Создаем проект ASP.Net MVC. Нам понадобятся следующие библиотеки:

Откроем контроллер HomeController.cs. Добавьте недостающие библиотеки в секцию uses:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Runtime.Caching;
using System.Text;
using System.IO;
using FastReport;
using FastReport.Web;
using FastReport.Utils;
using System.Web.UI.WebControls;
using FastReport.Export.Html;
using FastReport.Data;
using System.Net.Http.Headers;
using FastReport.Export.Image;
using System.Net.Http;

В методе Index мы будем отображать OnlineDesigner. Но, сначала создаем объект веб отчета и кэш для хранения файла отчета. Кэш я использую для того, чтобы избежать сохранения файла на сервере:

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
private WebReport webReport = new WebReport(); //Объект веб отчета
 
 MemoryCache cache = MemoryCache.Default; //Кэш
 
 public ActionResult Index(HttpPostedFileBase upload)
 {
 webReport.Width = Unit.Percentage(100);
 webReport.Height = Unit.Percentage(100); 
 string report_path = GetReportPath(); //Путь к папке с отчетами
 System.Data.DataSet dataSet = new System.Data.DataSet();
 dataSet.ReadXml(report_path + "nwind.xml"); //Читаем базу данных
 webReport.Report.RegisterData(dataSet, "NorthWind"); //Регистрируем данные в отчете
//Если вы не используете кэш, то загружаем отчет с сервера
 if (System.IO.File.Exists(report_path + "report.frx"))
 {
 webReport.Report.Load(report_path + "report.frx");
 }
//Если вы используете кэш, то загружаем из него отчет
 if (cache.Contains("1"))
 {
 webReport.Report.Load(cache["1"] as Stream);
 }
 
 // задаем настройки Online-Designer
 webReport.DesignReport = true;
 webReport.DesignScriptCode = false;
 webReport.Debug = true;
 webReport.DesignerPath = "~/WebReportDesigner/index.html";
 webReport.DesignerSaveCallBack = "~/Home/SaveDesignedReport";
 webReport.ID = "DesignReport";
 ViewBag.WebReport = webReport; //передаем отчет во View
 
 return View();
 }

Метод получения пути к отчетам:

1
2
3
4
 private string GetReportPath()
 {
 return this.Server.MapPath("~/App_Data/"); 
 }

Далее добавим метод загрузки файла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[HttpPost] //Атрибут указывает, что метод обрабатывает Post запрос
 public ActionResult Upload(HttpPostedFileBase upload)
 {
 
 
 if (upload != null)
 {
 // получаем имя файла
 string fileName = System.IO.Path.GetFileName(upload.FileName);
 // сохраняем файл в кэш
 cache.Add("1", upload.InputStream, DateTimeOffset.Now.AddMinutes(1));
 //Если сохраняете в файл на сервере
 upload.SaveAs(Server.MapPath("~/App_Data/report.frx"));
 }
 return RedirectToAction("Index");
 }

Обратите внимание на параметр DateTimeOffset.Now.AddMinutes(1) в вызове функции добавления кэша. Он задает время жизни кэша.

Теперь нам нужен метод сохранения отчета в Online Designer:

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
[HttpPost]
 // call-back for save the designed report 
 public ActionResult SaveDesignedReport(string reportID, string reportUUID)
 {
 ViewBag.Message = String.Format("Confirmed {0} {1}", reportID, reportUUID);
 
 if (reportID == "DesignReport")
 {
//Записываем отчет в кэш
 cache.Set("1", Request.InputStream, DateTimeOffset.Now.AddMinutes(10));
 
 // Если отчет будет сохраняться на сервер
 /*************************************/
 
 Stream reportForSave = Request.InputStream;
 
 string pathToSave = Server.MapPath("~/App_Data/DesignedReports/test.frx");
 
 
 using (FileStream file = new FileStream(pathToSave, FileMode.Create))
 {
 reportForSave.CopyTo(file);
 } 
 /* */
 }
 return View();
 
 }

Для этого метода мы создаем отдельное представление SaveDesignedReport.cshtml с таким кодом:

1
<h2>@ViewBag.Message</h2>

 Осталось реализовать метод скачивания файла отчета:

1
2
3
4
5
6
7
8
 public FileResult GetFile()
 {
 Stream str = cache["1"] as Stream;
//формируем файл для скачивания из кэша
 return File(str, "application/octet-stream","test.frx");
//Если использовали сохранение файла на сервере 
return File(Server.MapPath("~/App_Data/DesignedReports/test.frx"), "application/octet-stream", "test.frx"); 
 }

Теперь рассмотрим представление для страницы Index (Home->Index.cshtml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@{
 ViewBag.Title = "Home Page";
}
<h3>Select file</h3>
@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
 <input type="file" name="upload" />
 <input type="submit" value="Upload" />
}
<div style="float:right"> 
 @using (Html.BeginForm("GetFile", "Home", FormMethod.Get))
 {
 <input id="dwn" type="submit" value="Download designed report" />
 }
</div>
@ViewBag.WebReport.GetHtml()

Вверху выводим заголовок страницы. Далее используем хэлпер BeginForm чтобы создать форму с кнопкой выбора файла. В параметрах указано имя метода-обработчика – «Upload», имя контроллера – «Home», метод обработки – FormMethod.Post, способ кодирования данных - enctype = "multipart/form-data".

Далее вставляем поле загрузки файла и кнопку.

В правой части страницы разместим еще одну кнопку, по которой будет скачиваться отредактированный отчет. Для нее тоже создаем форму с помощью хэлпера BeginForm.

В последней строке кода мы отображаем отчет, полученный из контроллера.

В файле _Layout.cshtml нужно подключить скрипты:    

1
2
3
4
<head>
@WebReportGlobals.Scripts()
@WebReportGlobals.Styles() 
</head>

Теперь нужно внести изменения в два веб конфига. Называются файлы одинаково, но размещены в разных папках. Первый – расположен в папке Views. Добавляем в него:

1
2
3
4
5
<namespaces>

 <add namespace="FastReport" />
 <add namespace="FastReport.Web" />
 </namespaces>

Второй файл расположен в корне проекта. В него добавляем обработчик:

1
2
3
4
5
6
<system.webServer> 
 <handlers>

 <add name="FastReportHandler" path="FastReport.Export.axd" verb="*" type="FastReport.Web.Handlers.WebExport"/>
 </handlers>
 </system.webServer>

Запускаем наше приложение.

Перед нами OnlineDesigner с пустым отчетом. Загрузим отчет с локального компьютера с помощью кнопки «Выберите файл». Из диалогового окна выбираем файл и нажимаем кнопку Upload:

Загрузился шаблон отчета. Изменим цвет фона в бэнде данных. На вкладке «Отчет» нажимаем кнопку «Сохранить»:

При этом отработает метод SaveDesignedReport и мы увидем зеленое оповещение справа:

Теперь жмем кнопку «Download designed report»:

Браузер скачает наш отчет. Откроем его в Report Designer:

И получаем наш отчет, отредактированный с помощью Online Designer.