The Future of Report Generation with Blazor WebAssembly

2023-03-14

The Future of Report Generation with Blazor WebAssembly

Microsoft has long introduced a framework for creating an interactive web interface with C#, HTML and CSS. It comes in two versions: Server-side (Blazor Server) and Client-side (Blazor WebAssembly). WebAssembly is particular because it is executed right in the user’s browser and accesses the remote server only for the libraries required for code execution.

FastReport .NET already supports Blazor technology as part of the FastReport.Web package (more). However, until now, we have only supported Server-side rendering (Blazor Server). It took us a long time to get FastReport .NET working right in the user’s browser because we needed Skia support for stable work. Starting with version 2023.2, we are pleased to announce Blazor WebAssembly support as part of the FastReport.Blazor.Wasm package. This package is available as part of a FastReport .NET Enterprise subscription and higher (including Ultimate). 

Attention! Blazor WebAssembly support is currently in beta. Some reports and functionality may not work. Read the documentation and restrictions carefully before using.

Creating a demo application

Let’s create a test demo application to see the work of FastReport in WebAssembly.

First, install WebAssembly Build Tools to build your project with WebAssembly. If it is not installed, then run the following commands on the command line, depending on the TargetFramework of your application:

For .NET 6:

dotnet workload install wasm-tools-net6

For .NET 7:

dotnet workload install wasm-tools

Now let’s create a simple Blazor WebAssembly demo project from a template. You can do this using Microsoft Visual Studio 2022 or the dotnet CLI. For simplicity, let’s use the command:

dotnet new blazorwasm -n BlazorWasmDemo

Let’s edit the csproj of our project and add the latest FastReport.Blazor.Wasm package:

<ItemGroup>
 <PackageReference Include="FastReport.Blazor.Wasm" Version="2023.2.0" />
</ItemGroup>

Now, if you want to prepare your report in the browser (.frx), you must disable Trimming, as it interferes with the report script compilation. You can do this in the following way:

<PropertyGroup>
 <PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>

Now we add the native SkiaSharp libraries as part of our application. Depending on the TargetFramework we need to add:

For .NET 6:

<ItemGroup>
 <NativeFileReference Include="$(HarfBuzzSharpStaticLibraryPath)\2.0.23\*.a" />
 <NativeFileReference Include="$(SkiaSharpStaticLibraryPath)\2.0.23\*.a" />
</ItemGroup>

For .NET 7:

<ItemGroup>
 <NativeFileReference Include="$(HarfBuzzSharpStaticLibraryPath)\3.1.12\*.a" />
 <NativeFileReference Include="$(SkiaSharpStaticLibraryPath)\3.1.12\st\*.a" />
</ItemGroup>

In the _Imports.razor file, similarly to the Blazor Server components, add the necessary namespace to view the FastReport components:

@using FastReport.Web
@using FastReport.Web.Blazor.Components

Register FastReport services in our DI container (file Program.cs):

builder.Services.AddScoped(_ => new HttpClient{ BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddFastReport();

Note that for FastReport to work in WebAssembly, you must have a configured HttpClient in a DI container that can access root to load the necessary dlls builds. If you need to override HttpClient for your use, you can just set a separate HttpClient only for FastReport needs:

builder.Services.AddFastReport(options => options.HttpClient = 
new HttpClient{ BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)});

We have almost completed our long journey of preparing FastReport in WebAssembly, but there are just a few finishing touches. In the standard wwwroot\index.html file, we need to add the loading of js scripts for the proper work of FastReport:

<script src="./_content/FastReport.Web/scripts.js"></script>

Font registration

FastReport must interact with the user’s fonts since FastReport works with reports and the font is an integral part of any report with text. This is what happens when the report generator runs on Windows or Linux. However, the information about installed fonts on the user’s computer becomes unavailable when FastReport runs in a browser. Thus, our application must register the fonts that we will use in our reports. In our application, we will use a font that we will embed in our library as an embedded resource (EmbeddedResource) in advance. For this, specify in our project (.csproj):

<ItemGroup>
 <EmbeddedResource Include="Fonts\**">
 <Link>Fonts\%(RecursiveDir)%(Filename)%(Extension)</Link>
 </EmbeddedResource>
</ItemGroup>

Let’s put all the fonts we need in the Fonts folder and register them in our Program.cs. Let’s create this method and call it immediately:

static void AddFonts()
{
 var resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
 foreach (var resource in resources)
 {
 using var font = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
 FastReport.Utils.Config.PrivateFontCollection.AddFontFromStream(font);
 }
}
 
AddFonts();

Data registration

That’s quite difficult. Few database connectors can work directly from the user’s browser. Therefore, we leave this to the discretion of our users. For example, you can request data from some third-party resource via HTTP and then register this data in a report before preparing it. In our application, for demonstration, we use the data from the xml file, which we put in wwwroot together with the report.

Attention! Do not use this method for the final project publication because hackers can easily steal your data.

Using WebReportContainer component

Finally, let’s change the file Index.razor to use our WebReportContainer component. It will require the following code:

@page "/"
@using FastReport
@using System.Data;
@inject HttpClient HttpClient
 
@if (isReady)
{
 <WebReportContainer WebReport="myWebReport" />
}
 
@code{
 WebReport myWebReport;
 private bool isReady = false;
 
 protected async override Task OnParametersSetAsync()
 {
 // We receive a report
 var reportBytes = await HttpClient.GetByteArrayAsync("Simple List.frx");
 var reportStream = new MemoryStream(reportBytes);
 var report = Report.FromStream(reportStream);
 
 // Get xml database and register it
 var dataBytes = await HttpClient.GetByteArrayAsync("nwind.xml");
 var dataSet = new DataSet();
 dataSet.ReadXml(new MemoryStream(dataBytes));
 report.RegisterData(dataSet, "NorthWind");
 
 // Create a WebReport and assign a report to it
 myWebReport = new WebReport()
 {
 Report = report,
 EmbedPictures = true
 };
 isReady = true;
 }
}

Everything went well if we saw our report in the browser:

The finished report displayed in the browser

You have access to the reporting engine, you can build reports and view ready-made. Online designer support will be added in future. For security reasons, database connections are disabled inside reports, you will need to connect data from your application yourself. We are working hard on improving our WebAssembly component. If you have any questions, write to our support at support@fast-report.com.

November 20, 2024

Localization and Language Switching in FastReport VCL

FastReport VCL supports 40 languages for interface localization and allows you to change the language on the fly through menus or code, without recompilation.
November 01, 2024

New Features of the FastReport VCL Editor

We are considering new features of the report editor: extension lines, highlighting of intersecting objects, updated report and data trees.
October 30, 2024

Using Styles When Creating Reports in FastReport VCL

The article discusses one of the new features of FastReport VCL — the use of styles and style sheets.
Fast Reports
  • 800-985-8986 (English, US)
  • +4930568373928 (German)
  • +55 19 98147-8148 (Portuguese)
  • info@fast-report.com
  • 66 Canal Center Plaza, Ste 505, Alexandria, VA 22314

© 1998-2024 Fast Reports Inc.