In this blog, I will walk you through how to add the Report Designer component to a Blazor application. The Report Designer component for Blazor is a web-based WYSIWYG reporting tool for creating and editing reports. It has a wide range of report items to help you transform data into meaningful information.
Let’s get started!
Prerequisites
Before getting started, ensure your development environment includes the following:
Visual Studio 2022 with the ASP.NET and web development workload.
Create a Blazor Server Application
- Open Visual Studio 2022 and click Create a new project.
Create a new project
- Choose the Blazor application and click Next.
Create a Blazor application
If this template is unavailable, refer to this link to configure the system environment.
Provide a project name and then click Create.
Ensure that .NET 6.0 version is selected and click Create. Your Blazor application is created and loaded in Visual Studio.
Select .NET version
Install the NuGet Packages
To get the APIs related to the Blazor Report Designer, you need to install the package BoldReports.Net.Core. The BoldReports.Net.Core package contains APIs to process the designer file and data actions.
Follow these steps to install the NuGet packages:
In the Solution Explorer tab, right-click the project or solution and choose Manage NuGet Packages.
In the browser tab, search for the BoldReports.Net.Core package and install it in your Blazor server application.
Install Blazor reporting NuGet packages
Configure the Blazor Report Designer Web API
Next, you need to create a Web API controller to process the designer file and data actions:
Right-click the Data folder and select Add.
Select New item from the context menu.
In the Add New Item dialog, select the API controller – Empty
Name it BoldReportsAPIController.cs. and then click Add.
In the BoldReportsAPIController class, implement the IReportDesignerController interface from the namespace BoldReports.Web.ReportDesigner.
In the Program.cs file, add the following to use the Web API with Blazor. It maps incoming requests to the appropriate controllers based on defined routes.
app.MapControllers();
Paste the following code into the BoldReportsAPIController.cs class, which uses the IReportDesignerController interface, ReportDesignerHelper, and ReportHelper classes too. These classes are explained in the following.
using BoldReports.Web.ReportViewer;
using Microsoft.AspNetCore.Hosting;
using BoldReports.Web.ReportDesigner;
using Microsoft.Extensions.Caching.Memory;
namespace ServerBlazorApp.Data
{
[Route("api/{controller}/{action}/{id?}")]
public class BoldReportsAPIController : ControllerBase, IReportDesignerController
{
private Microsoft.Extensions.Caching.Memory.IMemoryCache _cache;
private IWebHostEnvironment _hostingEnvironment;
public BoldReportsAPIController(Microsoft.Extensions.Caching.Memory.IMemoryCache memoryCache, IWebHostEnvironment hostingEnvironment)
{
_cache = memoryCache;
_hostingEnvironment = hostingEnvironment;
}
/// <summary>
/// Get the path of specific file
/// </summary>
/// <param name="itemName">Name of the file to get the full path</param>
/// <param name="key">The unique key for Blazor report designer</param>
/// <returns>Returns the full path of file</returns>
[NonAction]
private string GetFilePath(string itemName, string key)
{
string dirPath = Path.Combine(this._hostingEnvironment.WebRootPath + "\\" + "Cache", key);
if (!System.IO.Directory.Exists(dirPath))
{
System.IO.Directory.CreateDirectory(dirPath);
}
return Path.Combine(dirPath, itemName);
}
/// <summary>
/// Action (HttpGet) method for getting resource of images in the report.
/// </summary>
/// <param name="key">The unique key for request identification.</param>
/// <param name="image">The name of requested image.</param>
/// <returns>Returns the image as HttpResponseMessage content.</returns>
public object GetImage(string key, string image)
{
return ReportDesignerHelper.GetImage(key, image, this);
}
/// <summary>
/// Send a GET request and returns the requested resource for a report.
/// </summary>
/// <param name="resource">Contains report resource information.</param>
/// <returns> Resource object for the given key</returns>
public object GetResource(ReportResource resource)
{
return ReportHelper.GetResource(resource, this, _cache);
}
/// <summary>
/// Report initialization method that is triggered when report begin processed.
/// </summary>
/// <param name="reportOptions">The ReportViewer options.</param>
[NonAction]
public void OnInitReportOptions(ReportViewerOptions reportOption)
{
//You can update report options here
}
/// <summary>
/// Report loaded method that is triggered when report and sub report begin to be loaded.
/// </summary>
/// <param name="reportOptions">The ReportViewer options.</param>
[NonAction]
public void OnReportLoaded(ReportViewerOptions reportOption)
{
//You can update report options here.
}
/// <summary>
/// Action (HttpPost) method for posting the request for designer actions.
/// </summary>
/// <param name="jsonData">A collection of keys and values to process the designer request.</param>
/// <returns>Json result for the current request.</returns>
[HttpPost]
public object PostDesignerAction([FromBody] Dictionary<string, object> jsonResult)
{
return ReportDesignerHelper.ProcessDesigner(jsonResult, this, null, this._cache);
}
/// <summary>Action (HttpPost) method for posting the request for designer actions.</summary>
/// <returns>Json result for the current request.</returns>
public object PostFormDesignerAction()
{
return ReportDesignerHelper.ProcessDesigner(null, this, null, this._cache);
}
public object PostFormReportAction()
{
return ReportHelper.ProcessReport(null, this, this._cache);
}
/// <summary>
/// Action (HttpPost) method for posting the request for report process.
/// </summary>
/// <param name="jsonResult">The JSON data posted for processing report.</param>
/// <returns>The object data.</returns>
[HttpPost]
public object PostReportAction([FromBody] Dictionary<string, object> jsonResult)
{
return ReportHelper.ProcessReport(jsonResult, this, this._cache);
}
/// <summary>
/// Sets the resource into storage location.
/// </summary>
/// <param name="key">The unique key for request identification.</param>
/// <param name="itemId">The unique key to get the required resource.</param>
/// <param name="itemData">Contains the resource data.</param>
/// <param name="errorMessage">Returns the error message, if the write action is failed.</param>
/// <returns>Returns true, if resource is successfully written into storage location.</returns>
[NonAction]
bool IReportDesignerController.SetData(string key, string itemId, ItemInfo itemData, out string errorMessage)
{
errorMessage = string.Empty;
if (itemData.Data != null)
{
System.IO.File.WriteAllBytes(this.GetFilePath(itemId, key), itemData.Data);
}
else if (itemData.PostedFile != null)
{
var fileName = itemId;
if (string.IsNullOrEmpty(itemId))
{
fileName = System.IO.Path.GetFileName(itemData.PostedFile.FileName);
}
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{
itemData.PostedFile.OpenReadStream().CopyTo(stream);
byte[] bytes = stream.ToArray();
var writePath = this.GetFilePath(fileName, key);
System.IO.File.WriteAllBytes(writePath, bytes);
stream.Close();
stream.Dispose();
}
}
return true;
}
/// <summary>
/// Gets the resource from storage location.
/// </summary>
/// <param name="key">The unique key for request identification.</param>
/// <param name="itemId">The unique key to get the required resource.</param>
/// <returns>Returns the resource data and error message.</returns>
[NonAction]
public ResourceInfo GetData(string key, string itemId)
{
var resource = new ResourceInfo();
try
{
var filePath = this.GetFilePath(itemId, key);
if (itemId.Equals(Path.GetFileName(filePath), StringComparison.InvariantCultureIgnoreCase) && System.IO.File.Exists(filePath))
{
resource.Data = System.IO.File.ReadAllBytes(filePath);
}
else
{
resource.ErrorMessage = "File not found from the specified path";
}
}
catch (Exception ex)
{
resource.ErrorMessage = ex.Message;
}
return resource;
}
/// <summary>
/// Action (HttpPost) method for posted or uploaded file actions.
/// </summary>
[HttpPost]
public void UploadReportAction()
{
ReportDesignerHelper.ProcessDesigner(null, this, this.Request.Form.Files[0], this._cache);
}
}
}
What Is the IReportDesignerController Interface?
The IReportDesignerController interface contains the required actions and helper methods declaration for processing the designer file and data actions.
Methods | Description |
GetResource | This action gets the images used in the report from the server at the time of preview in the Designer. |
OnlnitReportOptions | This invokes from a ReportHelper when the report is about to be processed at the time of preview. Before the report loads, you can customize CSV delimiters like in the following.reportOption.ReportModel.CsvOptions.FieldDelimiter = “,”; |
OnReportLoaded | This invokes from a ReportHelper when the report and subreport start loading for report rendering.You can use this method to customize the report settings if needed at the time of previewing it in the Designer. For example, you can change the UserID for the report like the following.reportOption.ReportModel.UserProfile.UserID = “NewUserID”; |
PostReportAction | This action processes the report request on the server side and returns the processed reporting result to the client side. |
PostFormDesignerAction | This action saves the report to the client. |
PostFormReportAction | This action saves the exported report to the client. |
UploadReportAction | This action receives the upload data from the Report Designer for adding images and opening reports client side. |
SetData | This invokes from a ReportDesignerHelper to write the resource file information to the server side that we are receiving with the UploadReportAction(). |
GetData | This invokes from a ReportDesignerHelper to read the resource file information that has been saved using SetData() for further report-building processes. |
Initialize the Blazor Report Designer
Next, you need to integrate Bold Reports JavaScript controls by creating an interop file to initialize the Report Designer with basic parameters:
- Create a Data/BoldReportDesignerOptions.cs class with the following code to hold the Report Designer properties.
namespace ServerBlazorApp.Data
{
public class BoldReportDesignerOptions
{
public string ServiceURL { get; set; }
}
}
Create a Scripts folder inside the wwwroot folder.
Create a boldreports-interop.js file inside the www-root/Scripts folder and add the following code snippet to invoke the Bold Reports Designer JavaScript control.
// Interop file to render the Blazor Report Designer component with properties.
window.BoldReports = {
RenderDesigner: function (elementID, reportDesignerOptions) {
$("#" + elementID).boldReportDesigner({
serviceUrl: reportDesignerOptions.serviceURL
});
}
}
Reference the Scripts and Theme Related to Blazor Report Designer
Next, reference the following online CDN links along with the boldreports-interop.js file in the head section of Pages/_Layout.cshtml to use our JavaScript reporting controls in the Blazor application.
<link href="https://cdn.boldreports.com/4.2.78/content/material/bold.reports.all.min.css" rel="stylesheet" />
<link href="https://cdn.boldreports.com/4.2.78/content/material/bold.reportdesigner.min.css" rel="stylesheet" />
<link href=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.min.css rel="stylesheet" />
<link href=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/show-hint.min.css rel="stylesheet" />
<script src="https://cdn.boldreports.com/external/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src=https://cdn.boldreports.com/external/jsrender.min.js type="text/javascript"></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/codemirror.min.js type="text/javascript"></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/show-hint.min.js type="text/javascript"></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/addon/hint/sql-hint.min.js type="text/javascript"></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.37.0/mode/sql/sql.min.js type="text/javascript"></script>
<script src=https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.44.0/mode/vb/vb.min.js type="text/javascript"></script>
<!--Used to render the gauge item. Add this script only if your report contains the gauge report item. -->
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/ej2-base.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/ej2-data.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/ej2-pdf-export.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/ej2-svg-base.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/data-visualization/ej2-lineargauge.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/data-visualization/ej2-circulargauge.min.js"></script>
<!--Used to render the map item. Add this script only if your report contains the map report item.-->
<script src="https://cdn.boldreports.com/4.2.78/scripts/data-visualization/ej2-maps.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/bold.reports.common.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/bold.reports.widgets.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/common/bold.report-designer-widgets.min.js"></script>
<!--Used to render the chart item. Add this script only if your report contains the chart report item.-->
<script src="https://cdn.boldreports.com/4.2.78/scripts/data-visualization/ej.chart.min.js"></script>
<!-- Report Designer component script-->
<script src="https://cdn.boldreports.com/4.2.78/scripts/bold.report-viewer.min.js"></script>
<script src="https://cdn.boldreports.com/4.2.78/scripts/bold.report-designer.min.js"></script>
<!-- Blazor interop file -->
<script src="~/scripts/boldreports-interop.js"></script>
Render Blazor Report Designer in a Razor Page
To render the Blazor Report Designer in a Razor page, you need to use the JavaScript Interop. To do so, open the Pages/Index.razor file and paste the following code.
@page "/"
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components
@inject IJSRuntime JSRuntime
@using ServerBlazorApp.Data;
<div id="designer" style="width: 100%;height: 650px"></div>
@code {
// ReportDesigner options
BoldReportDesignerOptions designerOptions = new BoldReportDesignerOptions();
// Used to render the Blazor Report Designer component in Blazor page.
public async void RenderReportDesigner()
{
designerOptions.ServiceURL = "/api/BoldReportsAPI";
await JSRuntime.InvokeVoidAsync("BoldReports.RenderDesigner", "designer", designerOptions);
}
// Initial rendering of Blazor Report Designer
protected override void OnAfterRender(bool firstRender)
{
RenderReportDesigner();
}
}
It has the following methods to render the Blazor Report Designer.
Methods | Description |
RenderReportDesigner | Renders the Report Designer component in a Blazor page. |
OnAfterRender | Initializes the Report Designer by calling the method RenderReportDesigner that we created. |
Run the Blazor Report Designer Application
Now, all is set up. To preview the Report Designer, build and run the application. You can create stunning professional reports from here!
Click Run or the F5 button to launch the application. When you run the application, the Report Designer will be rendered like in the following image.
Bold Reports Blazor report designer application
Now, you can build reports within your Blazor application integrated with the Report Designer.
Conclusion
I hope this blog provided sufficient guidance for integrating the Report Designer component into a Blazor application. To explore more about the Report Designer for Blazor and using report items in it, look through our documentation site. To experience the features live, please check out our demo samples and solutions.
If you have any questions, please post them in the comments section. You can also contact us through our contact page, or if you already have an account, you can log in to ask your support question.
Bold Reports now offers a 15-day free trial without any credit card information required. We welcome you to start a free trial and experience Bold Reports for yourself. Try it and let us know what you think!
Catch us on our official Twitter, Facebook, and LinkedIn pages for info about upcoming releases.