Skip to content

Reporting Integrating Telerik Reporting

Edward edited this page Apr 13, 2023 · 4 revisions

Integrating Telerik Reporting with Serenity

Telerik Reporting is a feature-rich reporting tool that allows you to quickly design and build great looking reports with ability to export as Excel/PDF/Image etc.

It is paid-for, and you can look at pricing here.

1. Download and add NuGet packages

Download the NuGet packages from your Telerik dashboard.

Telerik.Reporting.17.0.23.118.nupkg
Telerik.Reporting.OpenXmlRendering.17.0.23.118.nupkg
Telerik.Reporting.Services.AspNetCore.17.0.23.118.nupkg
Telerik.Reporting.WebServiceDataSource.17.0.23.118.nupkg

Create the following directory path in the root directory of your project (where YourAwesomeProject.sln is):

pro-packages/telerik.reporting/

Then place your *.nupkg files in this folder.

Remember to add this line to your .gitignore file to make sure your packages are stored in your source control:

!/pro-packages/**

Update your NuGet.conf file to the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
		<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
		<!-- Add this line below -->
		<add key="Telerik" value="pro-packages" /> 
    </packageSources>
</configuration>

2. Add JavaScript libraries

In your Scripts directory, add a directory called telerik, and another directory with the version number (currently 17.0.23.118).

Inside this directory, add these files:

Add the contents of telerikReportViewer to this file: /Scripts/telerik/17.0.23.118/telerikReportViewer.kendo.min.js

Add the contents of telerikReportViewer.kendo.min.js to this file: /Scripts/telerik/17.0.23.118/telerikReportViewer.min.js

Please note the links to these files above might change if Telerik's versioning changes.

3. Add a Report page to your project

Inside Modules/Reporting/ReportViewer

Create a file called ReportIndex.cshtml, and add the following contents:

@{
    ViewData["Title"] = "Reports";
}
@section Head {
    <link href="https://kendo.cdn.telerik.com/2022.3.913/styles/kendo.common.min.css" rel="stylesheet" id="common-css" />
    <link href="https://kendo.cdn.telerik.com/2022.3.913/styles/kendo.default.min.css" rel="stylesheet" id="skin-css" />
    <style>
        #ReportViewer {
            clear: both;
            height: 400px;
        }
    </style>   
}
<div id="ReportViewer">
    Loading report viewer...
</div>
<script type="module" src="@Html.ResolveWithHash("~/esm/Modules/Reporting/ReportViewer/ReportPage.js")"></script>
<script src="~/Scripts/telerik/17.0.23.118/telerikReportViewer.kendo.min.js"></script>
<script src="~/Scripts/telerik/17.0.23.118/telerikReportViewer.min.js"></script>

Create a file called ReportPage.ts, and add the following contents:

import { initFullHeightGridPage } from '@serenity-is/corelib/q';

declare var telerikReportViewer;

$(() => {
    initFullHeightGridPage($('#ReportViewer'));

    (<any>$("#ReportViewer"))
        .telerik_ReportViewer({
            serviceUrl: "api/reports/",
            reportSource:
            {
                report: "Report Catalog.trdp",
                parameters: {}
            },
            viewMode: telerikReportViewer.ViewModes.INTERACTIVE,
            scaleMode: telerikReportViewer.ScaleModes.SPECIFIC,

            scale: 1.0,
            enableAccessibility: false,
            parameters:
            {
                editors:
                {
                    multiSelect: telerikReportViewer.ParameterEditorTypes.COMBO_BOX,
                    singleSelect: telerikReportViewer.ParameterEditorTypes.COMBO_BOX,
                }
            }
        });
})

Create a file called ReportPage.cs, and add the following contents:

using Serenity.Web;
using Microsoft.AspNetCore.Mvc;

namespace YourAwesomeProject.Reporting
{
    [Route("Report/[action]")]
    public class ReportController : Controller
    {
        [PageAuthorize(TelerikReports.PermissionKeys.ReportViewer)]
        [Route("~/Reports")]
        public ActionResult Reports()
        {
            return View(MVC.Views.Reporting.ReportViewer.ReportIndex);
        }
    }
}

Create a file called ReportApiController.cs, and add the following code:

namespace YourAwesomeProject.Reporting
{
    using System.IO;
    using Microsoft.AspNetCore.Mvc;
    using Telerik.Reporting.Services;
    using Telerik.Reporting.Services.AspNetCore;
    using Microsoft.AspNetCore.Hosting;

    [Route("api/reports")]
    public class ReportApiController : ReportsControllerBase
    {
        protected IWebHostEnvironment HostEnvironment { get; }

        public ReportApiController(IReportServiceConfiguration reportServiceConfiguration, IWebHostEnvironment env)
        : base(reportServiceConfiguration)
        {
            HostEnvironment = env;

            reportServiceConfiguration.ReportSourceResolver = new TypeReportSourceResolver()
                        .AddFallbackResolver(new UriReportSourceResolver(
                            Path.Combine(HostEnvironment.ContentRootPath, @"App_Data", "Reports")));
        }

        // If you want to add a UserId or TenantId parameter to all your reports to protect sensitive data, uncomment the following two methods:

        //public override IActionResult CreateInstance(string clientID, [FromBody] ClientReportSource reportSource)
        //{
        //    reportSource.ParameterValues.Remove("TenantID");
        //    reportSource.ParameterValues.TryAdd("TenantID", Serenity.Authorization.UserId);

        //    return base.CreateInstance(clientID, reportSource);
        //}

        //public override IActionResult GetParameters(string clientID, [FromBody] ClientReportSource reportSource)
        //{
        //    reportSource.ParameterValues.Remove("TenantID");
        //    reportSource.ParameterValues.TryAdd("TenantID", Serenity.Authorization.UserId);
        //    return base.GetParameters(clientID, reportSource);
        //}
    }
}

Create a path Modules/Reporting/Services/, and inside it create a file named ReportingServiceCollectionExtensions.cs, with the following contents:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using Telerik.Reporting.Cache.File;
using Telerik.Reporting.Services;

namespace YourAwesomeProject.Extensions.DependencyInjection
{

    public static class ReportingServiceCollectionExtensions
    {
        public static void AddTelerikReportViewer(this IServiceCollection services, IConfiguration configuration)
        {
            if (services == null)
                throw new ArgumentNullException(nameof(services));

            services.AddSingleton<IReportServiceConfiguration>(sp =>
                new ReportServiceConfiguration
                {
                    ReportingEngineConfiguration = configuration,
                    HostAppId = "YourAwesomeProject",
                    Storage = new FileStorage()
                });
        }
    }
    
}

4. Add code to your app's initialisation

Inside your Startup.cs file add the following:

References to Telerik namespaces.

using YourAwesomeProject.Extensions.DependencyInjection;

Code to the end of your ConfigureServices method.

// Existing code
services.AddSingleton<IDataMigrations, DataMigrations>();
// ...

// Add this line
services.AddTelerikReportViewer(Configuration);

5. Add a report connection string

Take note of your ConnectionString name in your report's data source. The example reports use the name Telerik.Reporting.Examples.CSharp.Properties.Settings.TelerikConnectionString.

Add a database connection to your appsettings.config file

  "Data": {
    "Default": {
      "ConnectionString": "Server=(localdb)\\MsSqlLocalDB;Database=Serene_Default_v1;Integrated Security=true",
      "ProviderName": "System.Data.SqlClient"
    }
  },
  "ConnectionStrings": {
    "Telerik.Reporting.Examples.CSharp.Properties.Settings.TelerikConnectionString": {
      "ConnectionString": "Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=SSPI",
      "ProviderName": "System.Data.SqlClient"
    }
  },
  "Logging": "..."

NB. If you are running this in Azure or Docker you can override the connection string by setting an environment variable called ConnectionStrings__TelerikReports__ConnectionString

Note that the connection string name Telerik.Reporting.Examples.CSharp.Properties.Settings.TelerikConnectionString comes from the demos and is used by the demo reports. During installation you can choose to add a demo database where it sets up an AdventureWorks database for you.

6. Test it out

Inside the ReportApiController.cs we set the reportsPath variable to App_Data/Reports.

Place your report (.trdp) files in this folder, and be sure to reference the correct initial page in the ReportIndex.cshtml file (check the comments in it).

Run your app and add /Reports to the path and you should be able to run and download some fancy reports!

Clone this wiki locally