How to use FastReport Open Source in ASP.NET Core Web API application
ASP.Net
Core allows you to create Web API applications as well as the usual
ASP.Net. Such Restful Web API applications are extremely popular right
now. Therefore, it would be nice to learn how to use FastReport for
distribution via the API reports.
In this
article, we will create a demo WebAPI application that allows you to download
or view reports in two formats: html and png.
So, let’s
create the ASP.Net Core application. Then choose API. When the project is
generated, install FastReport.OpenSource packages from the nugget.org
repository:
In order to
use FastReport and static web pages we need to add several lines of code to
startup.cs in Configure method:
public void
Configure(IApplicationBuilder app, IHostingEnvironment env)
{
…
app.UseFastReport();
app.UseDefaultFiles();
app.UseStaticFiles();
…
}
We will need a small data model. That is why let’s add
Models folder to the project root and create Reports class in this folder:
Use this code:
public class Reports
{
// Report ID
public int Id { get; set; }
// Report
File Name
public string ReportName { get; set; }
}
Now let’s move on to the controller. We have
ValuesController controller. Add to the using section the following
libraries:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Hosting;
using FROSWebAPI.Models;
using System.IO;
using System.Data;
using FastReport.Utils;
using FastReport;
using FastReport.Export.Html;
using FastReport.Export.Image;
Let’s add one more class to the controller. It will
define the structure of the report query. There can be three parameters in the
query: format, inline flag (to be displayed in browser) and value of report
parameter. Here it is needed to say that in one of the reports we added
parameter instead of report header. By default it has the value that is
replaced by what we give.
public class ReportQuery
{
public string Format { get; set; }
public bool Inline { get; set; }
public string Parameter { get; set; }
}
ValuesController class already contains CRUD methods
(create, read, update, delete). We are only interested in data requests, web methods
and attribute [HttpGet]. Get method with no parameters will return us to
the list of reports. Second one, with parameters, will return a report in
one form or another: they are.
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IHostingEnvironment _hostingEnvironment; // We use the web interface hosting
environment to get out root path of it
public ValuesController(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
//Build a list of reports
Reports[] reportItems = new Reports[]
{
new Reports { Id = 1, ReportName = "Master-Detail.frx" },
new Reports { Id = 2, ReportName = "Simple Matrix.frx" }
};
// GET
api/values
[HttpGet]
public
ActionResult<IEnumerable<Reports>> Get()
{
return reportItems;
}
// GET
api/values/5
[HttpGet("{id}")]
public IActionResult Get(int id, [FromQuery] ReportQuery query)
{
string mime = "application/" + query.Format; //MIME-header with default value
// Find a report
Reports reportItem = reportItems.FirstOrDefault((p) => p.Id == id); //Extract the value of the
collection by identifier
if (reportItem != null)
{
string webRootPath =
_hostingEnvironment.WebRootPath; //Define the path to the wwwroot folder
string reportPath = (webRootPath + "/App_Data/" + reportItem.ReportName); //Define the path to the report
string dataPath = (webRootPath + "/App_Data/nwind.xml");//Define the path to the data base
using (MemoryStream stream = new MemoryStream()) //Create the stream for the report
{
try
{
using (DataSet dataSet = new DataSet())
{
//Fill the
source with data
dataSet.ReadXml(dataPath);
//Enable FastReport web mode
Config.WebMode = true;
using (Report report = new Report())
{
report.Load(reportPath); //Load the report
report.RegisterData(dataSet, "NorthWind"); //Register data in the report
if (query.Parameter != null)
{
report.SetParameterValue("Parameter", query.Parameter); // Defines the value of the report
parameter, if the parameter value is set in the URL
}
report.Prepare();//Prepare the report
//if the
selected format is png
if (query.Format == "png")
{
ImageExport
img = new ImageExport();
img.ImageFormat = ImageExportFormat.Png;
img.SeparateFiles = false;
img.ResolutionX
= 96;
img.ResolutionY = 96;
report.Export(img, stream);
mime = "image/" + query.Format; //redefine mime for png
}
//if the report format is html
else if
(query.Format == "html")
{
//report export to HTML
HTMLExport
html = new HTMLExport();
html.SinglePage
= true; //report on the one page
html.Navigator = false; //navigation panel on top
html.EmbedPictures = true; //build in images to the document
report.Export(html, stream);
mime = "text/" + query.Format; //redefine mime for html
}
}
}
//Get the name of resulting
report file with needed extension
var file = String.Concat(Path.GetFileNameWithoutExtension(reportPath),
".", query.Format);
//if the inline parameter is
true, open in browser
if (query.Inline)
return File(stream.ToArray(), mime);
else
//otherwise download report file
return File(stream.ToArray(), mime, file); // attachment
}
//Edit exceptions
catch
{
return new
NoContentResult();
}
finally
{
stream.Dispose();
}
}
}
else
return NotFound();
}
}
There is no
wwwroot folder in our project yet. Let’s create it and add inside one more
folder – App_Data. Inside add report templates and data sources for them:
Also, add
file Index.html to the wwwroot catalogue:
<!DOCTYPE html>
<html>
<head>
<title>FastReport Open Source Web Api</title>
<meta charset="utf-8" />
</head>
<body>
<h1>FastReport Open Source Web Api</h1>
<hr />
<a href="/api/values/">List Of All Reports</a><br />
<a href="/api/values/1?format=png">Get First Report in PNG</a><br />
<a href="/api/values/1?format=html">Get First Report in HTML</a><br />
<a href="/api/values/1?format=png&inline=true">Get First Report in PNG inline</a><br />
<a href="/api/values/2?format=html&inline=true">Get Second Report in HTML inline</a><br />
<a href="/api/values/1?format=png&inline=true¶meter=REPORT">Get First Report in PNG inline
with Parameter=REPORT</a><br />
<a href="/api/values/1?format=html&inline=true¶meter=REPORT">Get First Report in HTML inline
with Parameter=REPORT</a><br />
</body>
</html>
On this
page we form links for receiving reports. Some of them contain parameters which
we were talking before while creating the controller.
In order for
an application to launch by default our index page, we need to correct
launchSettings.json file under Properties. Just remove the lines
"launchUrl": "api / values " in two places.
Run the
application. And we will see a list of links:
Let’s try
to get the report in HTML format. In addition to this HTML file will be
downloaded. And now create the report in PNG format with browser view:
Transfer
the parameter to the report. Click on the last link:
As you can see, the report header changed to “Report”.
Therefore, we can easily send report by request in WebApi application.
Can you please provide the sample files, Master-Detail.frx, Simple Matrix.frx and nwind.xml.
ReplyDelete