-
Notifications
You must be signed in to change notification settings - Fork 204
Streaming PDF ASP NET Core
Peter Gill edited this page Jun 8, 2026
·
3 revisions
When generating reports in a web application you typically want to stream the output directly to the HTTP response rather than writing a temporary file to disk. Use MemoryStreamGen for this.
dotnet add package Majorsilence.Reporting.RdlEngine.SkiaSharp
dotnet add package Majorsilence.Reporting.RdlCri.SkiaSharpCall RdlEngineConfig.RdlEngineConfigInit() once when the application starts, not inside each request handler.
// Program.cs
using Majorsilence.Reporting.Rdl;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
// One time per app instance
RdlEngineConfig.RdlEngineConfigInit();
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();using Majorsilence.Reporting.Rdl;
using Microsoft.AspNetCore.Mvc;
[HttpGet("report.pdf")]
public async Task<IActionResult> GetReportPdf()
{
var rdlPath = Path.Combine(_env.ContentRootPath, "Reports", "MyReport.rdl");
var rdlp = new RDLParser(await System.IO.File.ReadAllTextAsync(rdlPath))
{
Folder = Path.GetDirectoryName(rdlPath)
};
using var report = await rdlp.Parse();
if (report.ErrorMaxSeverity > 4)
return StatusCode(500, string.Join("; ", report.ErrorItems.Cast<string>()));
await report.RunGetData(null);
using var ms = new MemoryStreamGen();
await report.RunRender(ms, OutputPresentationType.PDF);
// Copy to byte array before MemoryStreamGen is disposed
var pdf = ((System.IO.MemoryStream)ms.GetStream()).ToArray();
return File(pdf, "application/pdf", "report.pdf");
}Change the OutputPresentationType value and MIME type to produce different formats. See Output Formats for the full list.
// Excel
using var ms = new MemoryStreamGen();
await report.RunRender(ms, OutputPresentationType.Excel2007);
var bytes = ((System.IO.MemoryStream)ms.GetStream()).ToArray();
return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "report.xlsx");
// CSV
using var ms = new MemoryStreamGen();
await report.RunRender(ms, OutputPresentationType.CSV);
var bytes = ((System.IO.MemoryStream)ms.GetStream()).ToArray();
return File(bytes, "text/csv", "report.csv");
// HTML (embed in a page or return as a fragment)
using var ms = new MemoryStreamGen();
await report.RunRender(ms, OutputPresentationType.HTML);
var html = ms.GetText();
return Content(html, "text/html");// Set parameters on the viewer before RunGetData
var rdlp = new RDLParser(await System.IO.File.ReadAllTextAsync(rdlPath));
using var report = await rdlp.Parse();
// Parameters are passed as a dictionary to RunGetData
var parameters = new System.Collections.Generic.Dictionary<string, string>
{
{ "StartDate", "2024-01-01" },
{ "EndDate", "2024-12-31" }
};
await report.RunGetData(parameters);
using var ms = new MemoryStreamGen();
await report.RunRender(ms, OutputPresentationType.PDF);
var pdf = ((System.IO.MemoryStream)ms.GetStream()).ToArray();
return File(pdf, "application/pdf", "report.pdf");using var report = await rdlp.Parse();
var rpt = report;
await rpt.DataSets["DataSetNameInYourReport"].SetData(yourDataTable);
using var ms = new MemoryStreamGen();
await report.RunGetData(null);
await report.RunRender(ms, OutputPresentationType.PDF);
var pdf = ((System.IO.MemoryStream)ms.GetStream()).ToArray();
return File(pdf, "application/pdf", "report.pdf");| Format | Content-Type |
|---|---|
application/pdf |
|
| Excel (.xlsx) | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
| CSV | text/csv |
| HTML | text/html |
| XML | application/xml |
| RTF | application/rtf |
| MHTML | message/rfc822 |
| TIFF | image/tiff |
For a higher-level route-based approach that lists and serves reports from a folder, see ASP.NET Core MVC.