While working with Fast Reports online report designer, we usually have to upload our report templates into it, and then, after editing, download them. Today we will look at how this can be done in the context of an ASP .NET Core application.
Create an ASP .NET Core application. Add the FastReport .NET libraries to it using NuGet. Use the local package source - the Nuget folder from the FastReport .NET installation directory. Install two packages FastReport.Core and FastReport.Web.
Add the App_Date folder to the wwwroot folder. Put the data source for the demo reports in it - nwind.xml.
We also add a folder with an online designer in wwwroot, which you downloaded from the official website www.fast-report.com .
To use the Fast Reports libraries in your project, you must add one line to the Startup.cs file:
1 2 3 4 5 6 7 8 9 |
public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env) { … app.UseFastReport(); … } } |
Let's proceed to editing the HomeController controller.
We need to create 4 methods: display the report designer with the loaded report, upload the file to the server, generate a file for downloading, save the modified report to the server.
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 |
public class HomeController : Controller { public static string ReportName; public ActionResult Index(string filepath) { Task.WaitAll(); WebReport webReport = new WebReport(); // Web report object webReport.Width = "1000"; webReport.Height = "1000"; string report_path = GetReportPath(); // Path to the folder with reports System.Data.DataSet dataSet = new System.Data.DataSet(); dataSet.ReadXml(report_path + "nwind.xml"); // Read the database webReport.Report.RegisterData(dataSet, "NorthWind"); // Register data in the report if (System.IO.File.Exists(report_path + "report.frx")) { webReport.Report.Load(report_path + "report.frx"); } // If you use a cache, then load a report from it. if (filepath != null) { webReport.Report.Load(filepath); } // Set the settings Online-Designer webReport.Mode = WebReportMode.Designer; webReport.DesignScriptCode = false; webReport.Debug = true; webReport.DesignerPath = @"WebReportDesigner/index.html"; webReport.DesignerSaveCallBack = "Home/SaveDesignedReport"; ViewBag.WebReport = webReport; // pass the report to View ViewData["reportName"] = ReportName = Path.GetFileName(filepath); return View(); } private string GetReportPath() { return "wwwroot/App_Data/"; } [HttpPost] public async Task<IActionResult> UploadFile(List<IFormFile> file) { if (file == null || file[0].Length == 0) return Content("file not selected"); // Form the path to the file var path = Path.Combine( Directory.GetCurrentDirectory(), GetReportPath(), file[0].FileName); // Save the file on the server using (var stream = new FileStream(path, FileMode.Create)) { await file[0].CopyToAsync(stream); } // Move on to display the report designer with the loaded report template. return RedirectToAction("Index", "Home", new { filepath = path }); } [HttpPost] public IActionResult Download(string filename) { // Form the path to the file on the server var path = Path.Combine(Directory.GetCurrentDirectory(), GetReportPath(), filename); if (System.IO.File.Exists(path)) { // Form the result of POST request var bytes = System.IO.File.ReadAllBytes(path); Response.Body.Write(bytes, 0, bytes.Length); } return new OkResult(); } [HttpPost] public IActionResult SaveDesignedReport(string reportID, string reportUUID) { var path = Path.Combine(Directory.GetCurrentDirectory(), GetReportPath()); ViewBag.Message = String.Format("Confirmed {0} {1}", reportID, reportUUID); // Set the message for representation Stream reportForSave = Request.Body; // Write the result of the Post-request to the stream. string pathToSave = System.IO.Path.Combine(path, ReportName); // Form the path to save the file using (FileStream file = new FileStream(pathToSave, FileMode.Create)) // Stream creation { reportForSave.CopyTo(file); // Save query result to file return View(); } } } |
When displaying a web page, at first you will see a report designer with a blank template. And after uploading the report file to the server, the designer will appear with the template loaded.
Notice that we use ViewData to pass the report name to the view.
Now change the view for the Index method:
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 |
@{ ViewData["Title"] = "Home Page"; } <form asp-controller="Home" asp-action="UploadFile" method="post" enctype="multipart/form-data"> <input id="file" type="file" name="file" accept=".frx" /> <button type="submit">Загрузить файл</button> <input type="Button" value="Скачать отчет" onclick="GetFile()" /> </form> @await ViewBag.WebReport.Render() <script language="javascript" type="text/javascript"> function GetFile() { $.ajax({ url: '/Home/Download', type: 'POST', data: { filename: '@ViewData["reportName"]' }, xhrFields: { responseType: 'blob' }, success: function (data) { var tag = document.createElement('a'); var url = window.URL.createObjectURL(data); tag.href = url; tag.download = '@ViewData["reportName"]'; document.body.append(tag); tag.click(); tag.remove(); window.URL.revokeObjectURL(url); } }); }; </script> |
Here we used two ways to send requests to the server - through the form and through the ajax request. In the first case, we load the file, and since we still need to update the report designer, we can neglect to refresh the entire page. In the second case, when downloading the report file, we do not want to refresh the page and it is better to use the ajax request. We cannot organize file downloading with only ajax request, therefore when processing the result of the request we create a tag with a link to the file being downloaded.
For the SaveDesignedReport method in the controller, you need to create a view with the code:
@ViewBag.Message
That's all. Run the application. First we see a report designer with an empty template.
Click the button "Select file" and select the report template to download.
Press the button "Upload file":
And we get a report designer with a loaded template. We can perform any manipulations with the template and save it. And then, click the "Download Report" button.
And the browser loads the report file.
Thus, we realized our plans - a full-fledged report editor with the ability to load, save and download a report.