Forgot password?
  • Home
  • /
  • White Papers
  • /
  • How to use FastReport Online Designer in a web application on knockout.js

How to use FastReport Online Designer in a web application on knockout.js

Dmitriy Fedyashov

In this article, we will look at the way to quickly create a demo application on ASP.Net Core MVC with the client part in the form of a one-page application written in the knockout.js library.

How to install a knockout template and create an application

The .Net Core SDK may not contain a template for generating a knockout application. But it is easy to fix. Open the PowerShell command line in the folder where the application will be located.

Enter the command:

dotnet new — install Microsoft.AspNetCore.SpaTemplates::*

After that, you can create an application by template. Enter the command:

dotnet new knockout –o KnockOnlineDesigner

Go to the folder with the created application:

cd KnockOnlineDesigner

And execute the command to install the necessary JavaScript libraries:

npm install

Preparation

Now you can run the created project. It does not have a sln file yet. It will be added when you first save the project. Since we will be working with the open FastReport library, we install the NuGet packages FastReport.OpenSource, FastReport.OpenSource.Web.

Report templates should be placed in the wwwroot folder. Create an App_Data directory and add several report templates and a data file for them.

 

In addition, in wwwroot you need to add a folder with an online designer.

You can download the online designer from the developer’s site in the client section. Of course, if you have a purchased license for it. Before you can download an online designer, you need to build it. In the online designer, you select the components and controls that you need in the report designer. Please note that in the Configuration section, the API is selected for working with .Net Core.

After the end of construction of the designer libraries are going to be built and there is a link to download the zip file. Just unzip the contents of the archive in the directory wwwroot.

In the Startup.cs file, we include the FastReport libraries:

1
2
3
4
5
6
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{

App.UseFastReport();

}

 To display the report designer, you need to create a web report object and enable designer mode. Let's use the SampleDataController controller. Add two methods to it: displaying the designer and saving the modified report on the server.

 

Editing the SampleDataController 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
using System;
using Microsoft.AspNetCore.Mvc;
using FastReport.Web;
using Microsoft.AspNetCore.Hosting;
using System.IO;
 
namespace KnockOnlineDesigner.Controllers
{
 [Route("api/[controller]")]
 public class SampleDataController : Controller
 {
 private IHostingEnvironment _env;
 
 public SampleDataController(IHostingEnvironment env)
 {
 _env = env;
 }
 
 [HttpGet("[action]")]
 public IActionResult Design(string name)
 {
 var webRoot = _env.WebRootPath; //wwwroot path
 WebReport WebReport = new WebReport(); //create web report object
 WebReport.Width = "1000"; //set the web report width
 WebReport.Height = "1000"; //set the web report height
 WebReport.Report.Load(System.IO.Path.Combine(webRoot, (String.Format("App_Data/{0}.frx", name)))); //load report into the WebReport
 System.Data.DataSet dataSet = new System.Data.DataSet(); //create data source
 dataSet.ReadXml(System.IO.Path.Combine(webRoot, "App_Data/nwind.xml")); //open xml database
 WebReport.Report.RegisterData(dataSet, "NorthWind"); //edit data source WebReport.Mode = WebReportMode.Designer; //set the web report mode – designer WebReport.DesignerLocale = "en"; //set report designer localization WebReport.DesignerPath = @"WebReportDesigner/index.html"; //set online designer url WebReport.DesignerSaveCallBack = @"api/SampleData/SaveDesignedReport"; //set callback url WebReport.Debug = true; //enable debug mode.
 ViewBag.WebReport = WebReport; //pass report to view
 return View();
 }
 
 [HttpPost("[action]")]
 public IActionResult SaveDesignedReport(string reportID, string reportUUID)
 {
 var webRoot = _env.WebRootPath; //set the wwwroot path
 ViewBag.Message = String.Format("Confirmed {0} {1}", reportID, reportUUID); //set message for view
 Stream reportForSave = Request.Body; //write the post result into the stream
 string pathToSave = System.IO.Path.Combine(webRoot, @"App_Data/TestReport.frx"); //get the path to save reports
using (FileStream file = new FileStream(pathToSave, FileMode.Create)) //create file stream
 {
 reportForSave.CopyTo(file); //save the result into the file
 }
 return View();
 }
 }
}

 Please note that before the methods the attributes of the Get or Post attributes must be placed corresponding to the request type.

For the created methods we add two views:

  • Design.chtml:

@await ViewBag.WebReport.Render()

  • SaveDesignedReport.chtml:

@ViewBag.Message

 

The client application on knockout.js is located in the ClientApp folder.

In this folder there is a components directory in which pages and menus are located. Let us edit the homepage template - the file home-page.html:

1
2
3
4
5
6
<div id="app">
 <select data-bind="options: reports, value: selectedReport"></select>
 <button data-bind="click: clicked">Edit Report</button>
</div>
<div data-bind = "html: designer">
</div>

 This template displays a drop-down list of reports, a button and a div element in which the html code received from the backend — the report designer — will be inserted. Pressing the button will execute the clicked function. The javascript for this template is located in a separate home-page.ts file. Let's replace its contents with our code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import * as ko from 'knockout';
 
class HomePageViewModel {
 public designer = ko.observable('');
 public selectedReport = "Image";
 public reports = ko.observableArray(["Image", "Hierarchic List", "Matrix"]);
 
 clicked() {
 if (this.selectedReport != '') {
 fetch('api/SampleData/Design?name=' + this.selectedReport)
 .then(response => response.text())
 .then(data => {
 this.designer(data);
 });
 }
 }
}
 
export default { viewModel: HomePageViewModel, template: require('./home-page.html') };

 Here, we added a few variables:

  • designer - will store the html code received from the server at the request of the report designer;
  • selectedReport - stores the name of the report selected in the drop-down list;
  • reports - list of report names.

And also, there is a clicked function that performs a get request to the server and receives the online designer with the html report loaded into it.

That's it, you can run our demo application:

At first we see a blank page with a drop-down list of reports and the Edit Report button. Select a report from the list and click the button. In a moment we will see the online designer:

Now you can edit the report template and save it. On the Report tab, click the Save button.

 

The Saved message in the green box will inform you about the successful saving of the report. This tells us that the SaveDesignedReport method worked as intended and saved the report in the App_Data folder. Let's check it out. Stop the application and look at the App_Data folder:

 

As you can see, another report template was added with the same name that we specified in the SaveDesignedReport method.

Similar articles:

back