When a client came to us needing polished, data-rich Excel exports from their ASP.NET Core web application, I knew FastReport was the right tool for the job. FastReport is a mature reporting library with a dedicated Excel export plugin that integrates cleanly into the .NET ecosystem. After wiring it up across several projects, I want to share exactly how I approach the setup, the gotchas I've run into, and the patterns that make the integration reliable in production.
Why FastReport for Excel Export in ASP.NET Core?
There are plenty of libraries that can spit out an .xlsx file, but FastReport gives you something most of them don't: a full report designer workflow combined with a programmable export pipeline. Your team can design report templates visually, and then your application exports them to Excel on demand — formatted, paginated, and branded exactly the way the client expects.
For business applications where Finance or Operations teams live inside Excel, this distinction matters enormously. We're not just dumping raw data; we're delivering a structured, formatted workbook that mirrors the report layout.
Prerequisites Before You Start
Before touching any code, make sure your environment is ready. Here's what you'll need:
- .NET 6, 7, or 8 — FastReport's ASP.NET Core packages support all current LTS and STS releases.
- A FastReport license — the community edition covers basic use, but the Excel export plugin typically requires a commercial license. Confirm your license tier before scoping the project.
- NuGet access — either nuget.org or FastReport's private feed depending on your license.
- An existing ASP.NET Core project — MVC or minimal API both work.
Installing the FastReport Excel Export Plugin
Start by adding the core FastReport package and the Excel export plugin. Open your terminal in the project root and run:
dotnet add package FastReport.OpenSource
dotnet add package FastReport.OpenSource.Export.Xlsx
If you're on the commercial edition, the package names change slightly — check the FastReport documentation for your specific license tier. The principle is the same: one core package, one export-specific package.
After installing, verify the packages appear correctly in your .csproj:
<PackageReference Include="FastReport.OpenSource" Version="2024.*" />
<PackageReference Include="FastReport.OpenSource.Export.Xlsx" Version="2024.*" />
Pin your versions in production. I've been caught by minor-version changes breaking export behavior mid-sprint.
Registering FastReport in the Service Pipeline
Inside Program.cs, register FastReport with the ASP.NET Core dependency injection container. For web viewer support you add the full middleware, but for export-only workflows — which is the more common business scenario — a lightweight registration is sufficient:
builder.Services.AddFastReport();
If you're also exposing a web-based report viewer, chain in app.UseFastReport() after app.UseRouting(). For pure server-side export, you can skip the middleware entirely and work directly with the FastReport API in your controllers or services.
Building the Export Service
I always encapsulate report generation in a dedicated service class. This keeps controllers thin and makes the logic testable. Here's the pattern I use:
public class ReportExportService
{
private readonly IWebHostEnvironment _env;
public ReportExportService(IWebHostEnvironment env)
{
_env = env;
}
public byte[] ExportToExcel(object dataSource, string reportFileName)
{
var reportPath = Path.Combine(_env.ContentRootPath, "Reports", reportFileName);
using var report = new Report();
report.Load(reportPath);
report.RegisterData(dataSource, "DataSource");
report.Prepare();
using var ms = new MemoryStream();
var export = new XlsxExport();
export.Export(report, ms);
return ms.ToArray();
}
}
A few things to note here. First, report.Prepare() is non-negotiable — it runs the report engine and renders all the bands before export. Skip it and you get a blank workbook. Second, I store .frx report template files in a /Reports folder at the content root. This makes deployment straightforward and keeps templates out of the compiled binary.
Wiring It to a Controller Endpoint
With the service in place, the controller becomes simple:
[HttpGet("export/excel")]
public IActionResult ExportSalesReport([FromQuery] int month, [FromQuery] int year)
{
var data = _salesRepository.GetMonthlySales(month, year);
var bytes = _reportExportService.ExportToExcel(data, "SalesReport.frx");
return File(bytes,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
$"SalesReport_{year}_{month:D2}.xlsx");
}
The MIME type application/vnd.openxmlformats-officedocument.spreadsheetml.sheet is the correct type for .xlsx files. Using the wrong MIME type causes browsers to mishandle the download — I've seen this trip up junior developers regularly.
Configuring the XlsxExport Options
The XlsxExport object exposes several properties worth knowing:
- PageBreaks — controls whether report page breaks translate into Excel sheet breaks.
- Wysiwyg — when true, FastReport tries to match the visual layout of the report as closely as possible in the workbook.
- OpenAfterExport — set this to false in server contexts; it's a desktop artifact.
- DataOnly — exports raw data cells without formatting, useful for downstream data processing.
For client-facing exports I always enable Wysiwyg. For data pipeline exports I switch to DataOnly. Having both modes available from the same report template is a significant operational advantage.
Handling Common Production Issues
A few problems come up repeatedly across projects:
- File locking on report templates — if you're running multiple worker processes, ensure report files are read-only and never written to at runtime. Load them fresh each request rather than caching the
Reportobject itself. - Memory spikes on large datasets — FastReport buffers the prepared report in memory. For very large exports, consider streaming directly to the response rather than buffering in a
MemoryStream. - Missing fonts on Linux containers — FastReport's rendering engine depends on font metrics. In Docker deployments add
libfontconfig1and common font packages to your base image. - License exceptions at startup — these almost always mean the license file path is wrong or the environment variable isn't set. Check
FastReport.Utils.Config.LicenseFilein your startup code.
Putting It All Together
Once this pipeline is in place, adding a new Excel export to the application is a matter of designing a new .frx template and registering the appropriate data source. The infrastructure handles the rest. That's the real productivity win — the first integration takes a focused afternoon, but every subsequent report is a fraction of that effort.
At Helion 360, we often integrate this kind of reporting capability as part of broader business application builds. When clients need operational dashboards, compliance reports, or financial summaries that their teams can actually use in their existing Excel workflows, this FastReport pattern delivers without the fragility of custom EPPLUS or ClosedXML implementations that have to replicate a designer's layout in code.
If you're building a similar system and hitting a wall, feel free to reach out. This is exactly the kind of problem we enjoy solving.


