C# in.
Reports out.

An open-source RDL engine for .NET 8 & 10. PDF, Excel, HTML, CSV and more — from SQL, JSON, or pure C#. Apache 2.0 licensed.

$ dotnet add package Majorsilence.Reporting.RdlEngine.SkiaSharp
Program.cs in
var parser = new RDLParser(rdlXml);
using var report = await parser.Parse();
await report.RunGetData();
await report.RunRender(ofs,
  OutputPresentationType.PDF);
report.pdf out
Sales Summary — Q2 2026
Generated 2026-06-11 · page 1 of 4
RegionUnitsRevenue
North America12,408$1.24M
Europe9,112$0.97M
Asia-Pacific7,654$0.81M
Total29,174$3.02M
PDF XLSX HTML CSV XML TIFF MHT
7+
Output formats
10+
Data sources
10
Barcode / QR types
.NET 8 & 10
Cross-platform
Apache 2.0
Open source

Everything you need for .NET reporting

From simple PDF invoices to complex multi-page reports with barcodes, charts, and dynamic data — all from a single library.

📄

Multi-Format Export

Render any report to PDF, Excel (xlsx), HTML, CSV, RTF, and XML from a single data fetch. One call, every format.

PDF XLSX HTML CSV RTF
🗄️

Flexible Data Sources

Connect to SQLite, SQL Server, PostgreSQL, MySQL, Firebird, JSON files, XML, or inject data directly from C# objects.

Microsoft.Data.Sqlite · Json · SQL · PostgreSQL
📦

Barcode & QR Codes

10 built-in CRI barcode types via ZXing.Net: QR Code, Code 128, Code 39, Data Matrix, Aztec, PDF417, ITF-14, and more.

Custom Report Items (CRI)
🖥️

Visual Designer

Drag-and-drop report designer on Windows. Design RDL files visually, then render them server-side on any OS.

Windows Designer · Cross-Platform Render
🌐

Cross-Platform

Server-side rendering runs on Linux, macOS, and Windows. Works great in Docker containers and cloud deployments.

Linux · macOS · Windows · Docker

RDL Report Format

Based on the open RDL (Report Definition Language) standard. Reports are XML files — version-control friendly and portable.

Open Standard · XML · Portable

The modern alternative to legacy reporting

Crystal Reports requires .NET Framework and a commercial license. SSRS requires SQL Server and a dedicated Windows server. Majorsilence Reporting is a NuGet package that runs anywhere .NET runs.

Majorsilence
This library
Crystal Reports SSRS FastReport /
DevExpress
License Apache 2.0 core, MIT/BSD-tri-licensed add-ons — free Commercial, per-seat Requires SQL Server license Commercial, per-seat
.NET 8 / 10 Full support .NET Framework only Render only (partial) Supported
Linux / Docker Cross-platform Windows only Windows Server only Varies by product
Deployment NuGet package Runtime redistributable Dedicated report server NuGet package
Report format Open RDL (XML) Binary .rpt (proprietary) Open RDL (XML) Proprietary
Output formats PDF, XLSX, HTML, CSV, RTF, XML, TIFF, MHT PDF, Excel, Word, HTML PDF, Excel, Word, HTML, CSV PDF, Excel, Word, HTML
Inject C# objects SetData() Limited Limited Varies
Built-in report portal Build your own Crystal Reports Server (extra cost) Included Some products include one
Open source GitHub
🔄

Migrating from Crystal Reports or SSRS?

SSRS reports use the same open RDL format — many will render with Majorsilence Reporting without modification. Crystal Reports .rpt files need conversion, but straightforward tabular reports migrate cleanly.

Read the migration guide →

Add to your project

Available on NuGet. Add the engine, then optionally the CRI package for barcode support.

$ dotnet add package Majorsilence.Reporting.RdlEngine.SkiaSharp
$ dotnet add package Majorsilence.Reporting.RdlCri.SkiaSharp
$ dotnet add package Majorsilence.Reporting.RdlCreator.SkiaSharp

Up and running in minutes

Call RdlEngineConfigInit() once at startup, load an RDL file, and render to any format.

Render a SQLite-backed report to PDF C#
using Majorsilence.Reporting.Rdl;

// Call once per application instance
RdlEngineConfig.RdlEngineConfigInit();

var baseDir = AppContext.BaseDirectory;
var dbPath  = Path.Combine(baseDir, "mydata.db");
var outPath = Path.Combine(baseDir, "report.pdf");

var rdlXml = (await File.ReadAllTextAsync("Report.rdl"))
    .Replace("mydata.db", dbPath);

var parser = new RDLParser(rdlXml) { Folder = baseDir };
using var report = await parser.Parse();

await report.RunGetData();
var ofs = new OneFileStreamGen(outPath, true);
await report.RunRender(ofs, OutputPresentationType.PDF);
Export to PDF, Excel, CSV, and HTML in one pass C#
// RunGetData once, then RunRender for each format.
await report.RunGetData();

foreach (var (filename, format) in new[] {
    ("report.pdf",  OutputPresentationType.PDF),
    ("report.xlsx", OutputPresentationType.Excel2007),
    ("report.csv",  OutputPresentationType.CSV),
    ("report.html", OutputPresentationType.HTML),
}) {
    var ofs = new OneFileStreamGen(filename, true);
    await report.RunRender(ofs, format);
}
Read data from a local JSON file RDL + C#
/* In the RDL DataSource */
<ConnectionProperties>
  <DataProvider>Json</DataProvider>
  <ConnectString>file=employees.json</ConnectString>
</ConnectionProperties>

var rdlXml = (await File.ReadAllTextAsync("Employees.rdl"))
    .Replace("employees.json", Path.Combine(baseDir, "employees.json"));

var parser = new RDLParser(rdlXml) { Folder = baseDir };
using var report = await parser.Parse();
await report.RunGetData();
await report.RunRender(new OneFileStreamGen("out.pdf", true), OutputPresentationType.PDF);
Add a QR Code or barcode to a report (CRI) RDL + C#
/* QrCode · BarCode128 · BarCode39 · DataMatrix · AztecCode · Pdf417 · ITF-14 */
<CustomReportItem Name="ProductQR">
  <Type>QrCode</Type>
  <CustomProperties>
    <CustomProperty>
      <Name>Code</Name>
      <Value>=Fields!ProductName.Value</Value>
    </CustomProperty>
  </CustomProperties>
</CustomReportItem>

var parameters = new Dictionary<string, string>
    { ["BarcodeType"] = "DataMatrix" };
await report.RunGetData(parameters);
Inject data from C# objects instead of a live query C#
record SaleRecord(string Product, string Region, decimal Amount, int Quantity);

var salesData = new List<SaleRecord>
{
    new("Widget A", "North", 1250.00m, 50),
    new("Widget B", "South", 840.50m,  33),
};

await report.DataSets["Data"].SetData(salesData);
await report.RunGetData();
await report.RunRender(ofs, OutputPresentationType.PDF);