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&parameter=REPORT">Get First Report in PNG inline with Parameter=REPORT</a><br />
    <a href="/api/values/1?format=html&inline=true&parameter=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.

Comments

  1. Can you please provide the sample files, Master-Detail.frx, Simple Matrix.frx and nwind.xml.

    ReplyDelete

Post a Comment

Popular posts

FastReport Open Source - what is it and how to use it

FastReport Designer Community Edition