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


Open Source is very popular in our time. The global giants of the software market played considerable role in its popularization. After all, these companies are developing high-end commercial software, and their open source projects are based on proven solutions and best practices. And development is lead by professional programmers. All this increases the credibility of such open source projects. No, I do not want to say that projects created by a community of like-minded people are worse. Often they turn into cult, for example, the well-known Linux. However, such projects often attract inexperienced developers eager to gain new experience, which affects the quality of the product.

Anyway, more and more commercially successful software companies are trying to benefit the public, creating open source projects. FastReports has not become an exception. One of its most successful projects, the FastReport .NET report generator, is now open source. To tell the truth, this is not a fully-fledged FastReport .NET. In its Open Source version, the report export was pretty much cut, leaving only the export in html, the images and the native format of the reports prepared for viewing. However, otherwise it is still the same FastReport .NET.

But not everyone knows FastReport .NET. Someone is just starting their acquaintance with FastReport with OpenSource. Let's take a quick look at the main components and capabilities of this report generator.

Features:
  • Create reports using a convenient separate application - report designer FastReport Designer Community Edition (https://github.com/FastReports/FastReport/releases);
  • Display reports for apps based on: .Net WinForms, ASP .Net MVC, ASP .Net Core MVC, WPF, AvaloniaUI;
  • The ability to connect to any database, use any of its tables or create queries;
  • The ability to add dialog forms to your report to request parameters before running the report.
  • The built-in report script allows you to use data from the dialog form, to perform complex calculations, and to transform objects of a report by events. You can use .Net libraries in the script as well;
  • Export report to format: html, image (jpeg, png, tiff, bmp, gif, Windows meta file);
  • Open source gives you the opportunity to make changes to obtain the desired functionality.
The structure of FastReport Open Source includes two libraries:
FastReport.OnlineDesigner and FastReport.OnlineDesigner.Web
The first one contains the main functionality of the report generator, inherited from FastReport.Net. The second one is an adaptation of the report generator to the .Net Core framework. In particular, the WebReport object allows displaying a form with navigation elements on a web page which can display a report page by page.
If you plan to use a report generator in a web project, then you need to add both libraries to your project. However, if the web is not provided, then only FastReport.OpenSource is sufficient.

Where to download

You can download the source code of the FastReport.OpenSource project in the github repository:
But if you do not plan to change the source code, you just need to connect the libraries in the project using the NuGet package manager. We will talk about this later.

How to install FastReport Open Source

There are three ways to install the FastReport.OpenSource libraries into your project:
  1. From the NuGet package manager;
  2. From the git repository;
  3. Build the project in a local folder.
Let’s consider installation methods in more detail:
  • The first - from the NuGet package manager. The “freshest” FastReport.OpenSource package assemblies have already been placed in the nuget.org repository. Find and install the FastReport.OpenSource and FastReport.OpenSource.Web packages.
  • The second way - from the Git repository. To do this, you must have Git and the latest version of .Net Core SDK installed. Next, copy the repository using the Git Bash console. To do this, enter the command:
  • cd FastReport
    Tools/pack.bat

    The first command clones a project from the repository. The second one – moves us to cloned repository folder. And the third one – runs the building script. As a result we’ll get the folder fr_nuget located in the FastReport directory. We can see built NuGet packages in the folder. You should set a local NuGet packages source to add libraries into the project. Open the NuGet packages manager in your ASP .Net Core project. There is the settings button in the top right corner.
    Set the path to the fr_nuget folder for the Local package source. Click Update and OK.

    Select the source package Local package source in the drop-down list in the upper right corner. And also select the Browse tab in the upper left corner. If you do not need libraries to work with MySql and Postgres, then install the two packages FastReport.OpenSource and FastReport.OpenSource.Web. If you want to build packages under Linux, then the procedure is the same as above, and the commands are as follows:
    git clone https://github.com/FastReports/FastReport.git
    cd FastReport
    chmod 777 Tools/pack.sh && ./Tools/pack.sh
  • The third method - Build the project in a local folder. It consists in downloading the project from github as an archive. Extract the archive to the desired folder. And run the file pack.bat from the Tools folder. The result will be the same as in the method above.

How to use in WinForms

Although the FastReport Open Source is “sharpened” for the web, you can still use it in regular WinForms applications. However, the report will have to be displayed in graphical format using exporting the report to an image.
Let’s consider the way to do this. First of all, you need to add libraries to the project. For this we use the NuGet package manager. If packages are built locally, then we specify the local package repository; otherwise, select the nuget.org repository. Install the FastReport.OpenSource package.
In the code of your application, you need to add library namespaces:
using FastReport;
using FastReport.Export.Image;
Add a method for loading and exporting a report in image format:
        private void button1_Click(object sender, EventArgs e)
        {
            Report report = new Report();  // Create a report object
            report.Load(@"J:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports\Master-Detail.frx"); // Load report template
            DataSet data = new DataSet(); //Create a data source
            data.ReadXml(@"J:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports\nwind.xml"); // Load the database into the data source.
            report.RegisterData(data,"NorthWind"); // Register the data source in the report
            ImageExport exp = new ImageExport(); // Create report export in image format
            exp.ImageFormat = ImageExportFormat.Png; // Set the image format png            report.Prepare(); //Report prepare
            exp.Export(report, Directory.GetCurrentDirectory() + "/test.png"); // Export report to file
            var file = exp.GeneratedFiles[0]; // Save image to file
            pictureBox1.Image = new Bitmap(file); // Set the image
        }
From the comments it should be clear what we have done. It is necessary to clarify only the moment with the export of multi-page reports. The export has the HasMultipleFiles property, which is responsible for exporting report pages to different files. That is why GeneratedFiles is an array of files. In our example, we displayed the first generated file. In fact, 3 files were generated. You can implement elements of navigation through the pages of the report. In the meantime, let's take a look at the output of the button click handler:


How to use in WPF

Forms in WPF are implemented using XAML. Therefore, we have only one option available for displaying the report - as an image. As in the previous example, we simply export the report to a picture.
All you need is to connect the FastReport library. OpenSource and add an Image object to the form. To navigate through the report pages, you can add a toolbar and several buttons at once, for example: Forward, Back, First, Last.
In the previous example, we looked at how to load a report template, build it, and export it to an image. And also, we displayed the first page of the report.
How to make navigation through the pages?
If you look at the main form code in XAML format, then you will see the components that we added to the visual form:
<ToolBar Height="25" VerticalAlignment="Top" Grid.ColumnSpan="5" Margin="0,0,10,0">
            <Button x:Name="Open" Click="Open_Click">
                <Image Source="Resources/001.ico"></Image>
            </Button>
            <Button x:Name="First" Click="First_Click">
                <Image Source="Resources/frst.png"></Image>
            </Button>
            <Button x:Name="Previous" Click="Previous_Click">
                <Image Source="Resources/prr.png"></Image>
            </Button>
            <Button x:Name="Next" Click="Next_Click">
                <Image Source="Resources/nxt.png"></Image>
            </Button>
            <Button x:Name="Last" Width="43" Click="Last_Click">
                <Image Source="Resources/lst.png"></Image>
            </Button>
<ScrollViewer>
            <Image x:Name="im">
            </Image>
        </ScrollViewer>
This example is for informational purposes, therefore, most object attributes are not shown to simplify the perception of the code.
As you noticed, buttons have a click event handlers. Let's look at the handler for the button named Open:
public List<BitmapImage> pages = new List<BitmapImage>(); // List to store report pages in png format
private void Open_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog myDialog = new OpenFileDialog(); // Create a dialog
            myDialog.Filter = "Подготовленные отчёты(*.FPX)|*.fpx;"; // Set file filtering by extension in the dialog box.
            myDialog.Multiselect = false; // Forbidding multiple file selections            if (myDialog.ShowDialog() == true) // Display the dialog
            {
               Report report = new Report(); // Create an instance of the report object
              report.LoadPrepared(myDialog.FileName); // Load report in fpx format

                FastReport.Export.Image.ImageExport ex = new FastReport.Export.Image.ImageExport(); // Export instance
                ex.HasMultipleFiles = true; // Create separate files for each export page
ex.ImageFormat = ImageExportFormat.Png; // Set the export format
            ex.Resolution = 96; // Set the image resolution
            ex.Export(report, Directory.GetCurrentDirectory() + "/test.png"); // Export the image report to the test.png file

            foreach (string file in ex.GeneratedFiles) // For each file from the export
            {
// Save image cache to page list
  BitmapImage image = new BitmapImage();
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.UriSource = new Uri(file);
                image.EndInit();
                pages.Add(image);                   
            }
             im.Source = pages[0]; // Set the Image object image
            }       
}

This code allows you to open a report file in FPX format, load it into a report object, export it to PNG format, and save the resulting files to a list for later navigation through the pages. Remember that by default HasMultipleFiles is true.
Why do we save the image cache? The fact is that in WPF files are not “released” after opening, which means that we will not be able to delete files created during export when we want to open another report. Caching images helps to get around this problem.
And now we implement handlers for other buttons - navigation buttons:

public int CurrentPage = 0; // Variable to store current page

// Open the first report page
private void First_Click(object sender, RoutedEventArgs e)
        {
            CurrentPage = 0;
im.Source = pages[CurrentPage];
        }

// View previous report page
        private void Previous_Click(object sender, RoutedEventArgs e)
        {
            CurrentPage--; // Reduce the page number by 1
im.Source = pages[CurrentPage];
        }

// Open next report page
        private void Next_Click(object sender, RoutedEventArgs e)
        {
            CurrentPage++; // Increase page number by 1
im.Source = pages[CurrentPage];
        }

// Open last page of report
        private void Last_Click(object sender, RoutedEventArgs e)
        {
            CurrentPage = pages.Count() - 1; // Last page number
im.Source = pages[CurrentPage];
        }

How to use in AvaloniaUI

Avalonia platform is the ideological successor of WPF, but in a cross-platform version. Since the user interface of the Avalonia program is based on XAML, we can output our reports in image format. That is, you must first export the report to an image and simply display it in the <image> tag. Let's take a quick look at the way to do this.
First of all, to create an application on Avalonia, you need to install a template in VisualStudio. This can be done in the menu Tools -> Extensions and Updates. In the form that opens, select the Online node in the tree on the left. And in the search bar at the top enter Avalonia. Select and install the Avalonia for visual Studio extension.
There are two ways to install this framework: via Visual Studio and from the GIT repository.
The first method is very simple. In Visual Studio, open the menu:
In the tree on the left, open the Online node, and in the search bar in the right corner enter Avalonia. And install the extension found.
Create an application by selecting the Avalonia Application template.
Unfortunately, there is no compatibility between the WPF and Avalonia controls, so the visual design of the form is not available to us - only the XAML code. But in the XAML code there are some differences with WPF. They are associated with the absence of many attributes of components that either were not implemented due to the lack of time or were abandoned. In the previous example, we looked at the implementation of loading the report, exporting it to an image and displaying it. Let's see how similar code for Avalonia will look like:

<StackPanel Orientation="Horizontal" HorizontalAlignment="left" VerticalAlignment="Top" Background="#AA000000">
      <Button Name="Open" Margin="5" Background="Transparent">
        <Image Source="Resources/001.ico"></Image>
      </Button>
      <Button Name="First" Click="First_Click" Margin="5" Background="Transparent">
        <Image Source="Resources/frst.png"></Image>
      </Button>
      <Button Name="Prev" Click="Prev_Click" Margin="5" Background="Transparent">
        <Image Source="Resources/prr.png"></Image>
      </Button>
      <Button Name="Next" Click="Next_Click" Margin="5" Background="Transparent">
        <Image Source="Resources/nxt.png"></Image>
      </Button>
      <Button Name="Last" Click="Last_Click" Margin="5" Background="Transparent">
        <Image Source="Resources/lst.png"></Image>
      </Button>
     </StackPanel>
    <ScrollViewer>
        <Image Name="img" RenderTransformOrigin="0.5,0.5" Stretch="None" />
     </ScrollViewer>

In general, everything looks the same, but as noted above, many properties and controls are not available. Therefore, we replaced the ToolBar with a StackPanel. The main difference is in C# code. We cannot access the page objects directly; you must first find them by name:
public Button OpenBtn = this.FindControl <Button> ("Open");
Thus, if you need to refer to the property of the control, you will first have to get it at your disposal.
Implementation of the report button click handler will look like the WPF example:
public List<Avalonia.Media.Imaging.Bitmap> pages = new List<Avalonia.Media.Imaging.Bitmap>(); // Export file list

        private async void OpenFile(object sender, RoutedEventArgs e)
        {
// Open file
            OpenFileDialog myDialog = new OpenFileDialog();
            myDialog.Filters.Add(new FileDialogFilter() { Name = "Prepared reports(*.FPX)", Extensions = new List<string> { "fpx" } }); // Add filter by file extension
            myDialog.AllowMultiple = false;

            var result = await myDialog.ShowAsync(this); // Display the dialog
            Report report = new Report(); // Create report object
            report.LoadPrepared(result[0]); // Load the prepared report into the Report object.
            FastReport.Export.Image.ImageExport ex = new FastReport.Export.Image.ImageExport(); // Create export report
            ex.HasMultipleFiles = true; // Split the report page by page into several files when exporting
ex.ImageFormat = ImageExportFormat.Png; // Set export format
            ex.Resolution = 96; // Set image resolution
            ex.Export(report, Directory.GetCurrentDirectory() + "/test.png"); // Export to test.png file
            foreach (string file in ex.GeneratedFiles)
            {
                pages.Add(new Avalonia.Media.Imaging.Bitmap(file)); // Add each export file to the list
            }
            img.Source = pages[0]; // Display the first page of the report.
}

As for the navigation buttons for navigating between pages, their implementation has no difference from the WPF example:
public int CurrentPage = 0; // Variable to store current page

// Open the first report page
private void First_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            CurrentPage = 0;
            img.Source = pages[CurrentPage];
        }

// View previous report page
        private void Prev_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            CurrentPage--;
            img.Source = pages[CurrentPage];
        }

// Open next report page
        private void Next_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            CurrentPage++;
            img.Source = pages[CurrentPage];
        }

// Open last page of report
        private void Last_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
        {
            CurrentPage = pages.Count - 1;
            img.Source = pages[CurrentPage];
        }

How to use in .NET Core MVC

As part of the ASP.Net Core application, you can display web reports. That is, reports will be displayed on web pages. This works by exporting the report in html format. Consider the key points in using the FastReport.OpenSource.Web library in this web application:
1.       Add libraries. You can add the FastReport.OpenSource and FastReport.OpenSource.Web libraries using the NuGet package manager. These libraries are stored in the general nuget.org repository.
2.       Add using FastReport in Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseFastReport();
        }
3.       Add the code for creating and downloading the report to the controller
public IActionResult Index()
        {
            WebReport WebReport = new WebReport();
            WebReport.Report.Load(@"Reports/Master-Detail.frx"); // Load the report into the WebReport object
            System.Data.DataSet dataSet = new System.Data.DataSet(); // Create a data source
            dataSet.ReadXml(@"reports/nwind.xml"); // Open the xml database
            WebReport.Report.RegisterData(dataSet, "NorthWind"); // Registering the data source in the report
            WebReport.Mode = WebReportMode.Designer; // Set designer mode
            WebReport.DesignerLocale = "en"; // Choosing a localization designer
            WebReport.DesignerPath = @"WebReportDesigner/index.html"; // We set the URL of the online designer
            WebReport.DesignerSaveCallBack = @"Home/SaveDesignedReport"; // Set the view URL for the report save method
            ViewBag.WebReport = WebReport; // pass the report to View
            return View();
        }
4.       Add usage code to the view:
@await  ViewBag.WebReport.Render()
Also, you can display Online Designer using FastReport.OpenSource. This is a paid product that allows you to create and edit reports along with the desktop report generator.

How to use with Angular SPA

Creating your Angular SPA in Microsoft Visual Studio you can use all the advantages of the .Net Core MVC backend. Namely, use View to display in the SPA application.
To work with Angular, you need to install Node.js, a platform for executing JavaScript code on the server side. The easiest way is to download the installer from the developer’s website https://nodejs.org/en/. It also requires .Net Core SDK 2.0 or newer version. If you have Microsoft Visual Studio 2017 installed, then the SDK is already installed.
Now we create a folder for our future application in the desired place. Run the command prompt. Go to the created directory using the cd command. And we execute the command:

dotnet new angular -o SPAWebReport

You will need to install the typescript package in the folder with the application. To do this, in the command prompt navigate to the folder with the application and execute the command:
npm install -g typescript
Next, we need to install additional packages in the NuGet manager:
·         FastReport.OpenSource;
·         FastReport.OpenSource.Web;
·         Microsoft.Net.Compilers.
In the controller, add the method of loading the report and data for it:
using FastReport.Web;
[HttpGet("[action]")]
        public IActionResult ShowReport()
        {
            WebReport WebReport = new WebReport();
            WebReport.Width = "1000";
            WebReport.Height = "1000";
            WebReport.Report.Load("App_Data/Master-Detail.frx"); // Load the report into the WebReport object
            System.Data.DataSet dataSet = new System.Data.DataSet(); // Create a data source
            dataSet.ReadXml("App_Data/nwind.xml");  //Open xml database
            WebReport.Report.RegisterData(dataSet, "NorthWind"); // Registering the data source in the report
            ViewBag.WebReport = WebReport; //pass the report to View
            return View();
        }
For this method, you need to create a view of the same name, in which there will be only one line of code - report rendering:
@await ViewBag.WebReport.Render()
In the client part of the application, we define the page template in the template property of the component. The file is called App.component.ts:
import { Component } from '@angular/core';
import { SafeUrlPipe } from "./safeUrl.pipe";

@Component({
    selector: 'app-root',
    template: `<div>
                    <input type="button" (click)="Clicked()" value = "Show Report"/>
                   <div *ngIf="show">
                    <iframe  id="report" height="1000" width="1000" [src]="url | safeUrl"></iframe>
                    </div>
               </div>`
})
export class AppComponent {
    show: boolean = false;
    url: string;

    Clicked() {
        this.show = true;
        this.url = "api/SampleData/ShowReport";
    }
}
By default, the page template is in a separate file. We added an iframe so that the downloadable report runs in a separate environment. When loading the page, we will see only the button, the frame will be empty. But by clicking on the button, the source will be given - the view that we created above. In order for the link to be recognized as a link, and not as a simple text, we used the "normalizer" url. You can apply a function to a value using a pipe - a vertical slash.
We implement this "normalizer" in a separate class. And we already added the link to it to the class component.
safeURL.pipe.cs:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Pipe({ name: 'safeUrl' })
export class SafeUrlPipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) { }
    transform(url) {
        return this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
}
DomSanitizer allows you to make the link safe from malicious or erroneous inclusions.

We can write a lot more useful information about aspects of using FastReport Open Source, but the article turned out to be quite voluminous. Therefore, we will look at the way to use this report generator in more detail in further articles.


Comments

Popular posts

FastReport Designer Community Edition

How to use FastReport Open Source in ASP.NET Core Web API application