How to use the FastReport Open Source WebReport with ReactJS
The popular
React library deservedly takes leading positions in web programming. Convenient
and flexible tool for creating web applications. Today we will create an
application on ReactJS in conjunction with ASP .Net Core. But this is not our
main goal. And the main goal is to display FastReport reports using the
FastReport.OpenSource library. This library is an open source report generator
for the .Net Core platform from the FastReport company.
Create a project
To create
an ASP project .Net Core + React we need Microsoft Visual Studio 2017, or .Net
Core 2.0 SDK and higher. Also install the Node.js package. This is a toolkit
for running javascript code on the server. Download the installation file from the
developer’s site.
To create
an ASP .Net Core project with a front-end to React, you can use a simple
command from the command line:
dotnet new
react -o FROSReact
Where
FROSReact is the project name. As a result, we get a ready-made demonstration
project, in which we simply make changes.
Backend
- Add
packages
To use the FastReport Open Source libraries in your project, you need to
add them using the NuGet package manager. Open the package manager and find the
library in the nuget.org repository: FastReport.OpenSource,
FastReport.OpenSource.Web.
- Startup
To use the added libraries, edit the
startup.cs file:
public void
Configure(IApplicationBuilder app, IHostingEnvironment env)
{
…
app.UseFastReport();
…
}
- Add reports and database to the
project
We will need report files and a database for them. To do this, add the
App_Data folder to the project root and drag the report template files and xml
database for them:
- Add a method to the controller
In our project there is already a
SampleDataController controller. Add to it your method: [HttpGet("[action]")]
public IActionResult DisplayReport(string name)
{
WebReport WebReport = new
WebReport();
WebReport.Width = "1000";
WebReport.Height = "1000";
WebReport.Report.Load(String.Format("App_Data/{0}.frx", name)); // Load the report into the WebReport object
System.Data.DataSet dataSet = new
System.Data.DataSet(); // Create a data source
dataSet.ReadXml(@"App_Data/nwind.xml"); // Open the xml database
WebReport.Report.RegisterData(dataSet, "NorthWind"); // Registering the data source in the report
ViewBag.WebReport = WebReport; // Pass the report
to View
return View();
}
• Add a view
In our project, there is no
traditional for the mvc application folder View. Create it in the project root.
And inside it is another SampleData folder, according to the name of the
controller. In this folder we add a cshtml format view named DisplayReport,
with the following content:
@await ViewBag.WebReport.Render()
The Render
method will return the report in html format.
On this stage work with the backend is finished.
Frontend
Create a new Report.js
component to display the report page in the ClientApp \ src \ components
directory.
In it we need to
implement:
• list of available
reports;
• request for a report
by name from the server;
• report display.
To display our new
page, you need to make changes to some scripts.
NavMenu.js:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Navbar } from 'react-bootstrap';
import './NavMenu.css';
export class NavMenu extends Component {
displayName
= NavMenu.name
render() {
return (
<Navbar inverse fixedTop fluid collapseOnSelect>
<Navbar.Header>
<Navbar.Brand>
<Link to={'/'}>ReactFROS</Link>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
</Navbar>
);
}
}
И App.js:
import React, { Component } from 'react';
import { Route } from 'react-router';
import { Layout } from './components/Layout';
import { Report } from './components/Report';
export default class App extends Component {
displayName = App.name
render() {
return (
<Layout>
<Route exact path='/' component={Report} />
</Layout>
);
}
}
Let's go back to the
Report.js file. First, create a component class inherited from PureComponent.
import React, { PureComponent, Fragment } from 'react';
export class Report extends
PureComponent {
constructor(props) {
super(props);
}
render() {}
}
In the class constructor, we call the super
class constructor (props) to make inheritance work.
To implement the list of reports, we need an
array of objects with report names. Add it to the class constructor, and more
specifically to the state:
this.state = {
options: [
{
value: 'Select report name …',
},
{
value: 'Matrix',
},
{
value: 'Master-Detail',
},
{
value: 'Text',
},
]
};
And now add the code to display the list:
render() {
const { options, value } = this.state;
return (
<div>
<Fragment>
<select onChange={this.handleChange} value={value}>
{options.map(item => (
<option key={item.value}
value={item.value}>
{item.value}
</option>
))}
</select>
</Fragment>
</div>
);
}
We use the Fragment component, which returns a
list of elements, and nothing is added to the DOM. The select tag itself is filled
with elements from an array using the map function. For the onChange event, you
need to implement the handleChange handler. Add it to the Report class:
handleChange = (event) => {
this.setState({ value:
event.target.value });
this.name = event.target.value;
};
Set the state for the value variable and set
the report name, which we will pass as a parameter when calling the report
generation method in the controller.
Now let's implement the report loading. Add a
variable to render that will contain the html representation of the
DisplayReport web method in the controller on the server.
render() {
const { options, value } = this.state;
let contents = this.name ? Report.getReport(this.name) : <div />;
return (
<div>
<div>
<Fragment>
<select onChange={this.handleChange} value={value}>
{options.map(item => (
<option key={item.value}
value={item.value}>
{item.value}
</option>
))}
</select>
</Fragment>
</div>
{contents}
</div>
);
}
Also, as you noticed, we added the output of
the contents variable in the html code.
Implement the getReport report retrieval
method. Add the following code to the Report class:
static createMarkup(name) {
return { __html: '<iframe
height="1000" width="1000"
src="api/SampleData/DisplayReport?name='+name+'" />' };
}
static getReport(name) {
return (
<div dangerouslySetInnerHTML={Report.createMarkup(name)}
/>
)
}
Here we had
to implement two methods. The first one converts the textual representation of
the tag frame into the html format, and the second one embeds the resulting
code into the DOM. The
dangerouslySetInnerHTML attribute replaces innerHTML.
That's all.
This finishes the completion of the frontend. Let's run the application:
When
loading the page, we will see only the drop-down list. Select from it the name
of the report:
After which
we will see the report:
Choose
another report:
Summarizing,
we can say that our goal has been achieved - an application to React, in which
FastReport reports are displayed.
Comments
Post a Comment