If you prefer to construct your reports using ASP.NET MVC engines like Razor you can benefit from jsreport.AspNetCore nuget package. This package provides middleware filter capable of transforming view output into any format jsreport supports. You can for example easily transform MVC view into pdf or excel. The idea is to use views as html generator and jsreport server as transformer to the desired output.
Note this package is dedicated to ASP.NET Core
applications. Please navigate to similar jsreport.MVC documentation when working with the ASP.NET application running full .NET framework.
The example sources are hosted in jsreport/jsreport-dotnet-example-webapp repository.
jsreport.AspNetCore
includes just helper classes to work with jsreport and it still requires to connect to instance running through jsreport.Local
or to the instance running remotely through jsreport.Client
.
This basic example uses jsreport.AspNetCore
, jsreport.Local
and jsreport.Binary
packages for setup.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddJsReport(new LocalReporting()
.UseBinary(JsReportBinary.GetBinary())
.AsUtility()
.Create());
}
The next step is to decorate the particular controller's action with MiddlewareFilter
and specify the jsreport recipe for transforming the view output.
[MiddlewareFilter(typeof(JsReportPipeline))]
public IActionResult Invoice()
{
HttpContext.JsReportFeature().Recipe(Recipe.ChromePdf);
return View();
}
This enables asp.net filter which captures the view rendering result and uses the specified chrome-pdf recipe to convert the output html into pdf.
This is just very basic scenario particularly useful in asp.net based applications. However jsreport includes tons of nice features worth it to explore. It allows to convert html to excel, evaluate javascript templating engines on top of the razor, run custom javascript functions and much more.
The asp.net core integration doesn't require using jsreport.Local and it works the same with the remote jsreport instance and jsreport.Client.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddJsReport(new ReportingService("http://jsreport:5488"));
}
This maybe be even better than using jsreport.Local
when running an orchestrated docker environment where jsreport is running in an extra container.
The example how you can run jsreport in one container, .net core app in another container and orchestrate them using docker-compose can be found here.
The response headers or other advanced response's attributes can be filled inside the OnAfterRender
hook.
var contentDisposition = "attachment; filename=\"myReport.pdf\"";
HttpContext.JsReportFeature().Recipe(Recipe.ChromePdf)
.OnAfterRender((r) => HttpContext.Response.Headers["Content-Disposition"] = contentDisposition);
OnAfterRender
hook can be used also to store output to file and at the same time return stream as the response.
[MiddlewareFilter(typeof(JsReportPipeline))]
public async Task<IActionResult> InvoiceWithHeader()
{
HttpContext.JsReportFeature().Recipe(Recipe.ChromePdf);
HttpContext.JsReportFeature().OnAfterRender((r) => {
using (var file = System.IO.File.Open("report.pdf", FileMode.Create))
{
r.Content.CopyTo(file);
}
r.Content.Seek(0, SeekOrigin.Begin);
});
return View(InvoiceModel.Example());
}
See the local troubleshooting section for details.
The pdf headers can be specified in extra partial view and rendered in runtime along with the main pdf content. The first you need to get the IJsReportMVCService
helper class from the asp.net container.
public IJsReportMVCService JsReportMVCService { get; }
public HomeController(IJsReportMVCService jsReportMVCService)
{
JsReportMVCService = jsReportMVCService;
}
Afterwards you can use it to render a partial view based on its name, get the header content and provide it to the jsreport request.
[MiddlewareFilter(typeof(JsReportPipeline))]
public IActionResult InvoiceWithHeader()
{
var header = await JsReportMVCService.RenderViewToStringAsync(
HttpContext, RouteData, "Header", new { });
HttpContext.JsReportFeature()
.Recipe(Recipe.ChromePdf)
.Configure((r) => r.Template.Chrome = new Chrome{ HeaderTemplate = header });
return View("Invoice", InvoiceModel.Example());
}
You don't have to use Razor and MVC views to render the report html content. The rendering can be invoked just from raw html as well.
var report = await JsReportMVCService.RenderAsync(new RenderRequest()
{
Template = new Template
{
Content = "<h1>Hello world</h1>",
Engine = Engine.None,
Recipe = Recipe.ChromePdf
}
});