Muaddib878
Muaddib878

Reputation: 356

Rendering .rdlc reports with ASP .NET Core

Is it possible to render .rdlc reports with ASP.NET Core? Currently this only seems to be possible if I target the .NET Framework as opposed to .NET Core.

I don't need a report viewer I just need to render the results of an .rdlc report as a byte array.

Upvotes: 17

Views: 41862

Answers (5)

Its BK
Its BK

Reputation: 56

In case anyone is still looking for a similar solution, I would recommend using "ReportViewerCore.NETCore".

Here is the nuGet reference - https://www.nuget.org/packages/ReportViewerCore.NETCore/

Here is the github link to the repo - https://github.com/lkosson/reportviewercore/

Basic usage

Stream reportDefinition; // your RDLC from file or resource
IEnumerable dataSource; // your datasource for the report

LocalReport report = new LocalReport();
report.LoadReportDefinition(reportDefinition);
report.DataSources.Add(new ReportDataSource("source", dataSource));
report.SetParameters(new[] { new ReportParameter("Parameter1", "Parameter value") });
byte[] pdf = report.Render("PDF");

Upvotes: 4

Tharindu Jayasinghe
Tharindu Jayasinghe

Reputation: 3203

If you want to create pdf/excel/word using rdlc report I recommend you can use AspNetCore.Reporting library. This is open source and comes as a nuget package. you can integrate this in your .NET Core API or .NET Core Azure function. You can generate a byte array convert it to base 64 string and retrieve that to your client side. More on the link in the comment.

Upvotes: 10

Knelis
Knelis

Reputation: 7159

Rendering RDLC reports relies on WinForms and WebForms and is currently only supported on .NET Framework. Hopefully Microsoft will make a (slimmed down) version available (just rendering the reports for starters) on .NET Core or .NET 5, but no word as of yet.

As an alternative, you could go for a solution where you run report rendering as a separate ASP.NET 2 app targeting .NET Framework, while the rest of your app could target .NET Core 3 or later. That way, you can call the reporting endpoints with the appropriate data, and it returns a rendered report.

This is what I've done, creating a sort of microservices architecture where multiple .Net Core 3.1 apps can post both the XML RDLC report definition and data to an endpoint running on net48, which uses the LocalReport class to render the report to the desired format, returning it as a byte array.

Angular app |  ---->  |  APIs (.Net Core 3.1)  |  ---->  |  API (.Net Framework 4.8)

Upvotes: 0

Aneesh Gopalakrishnan
Aneesh Gopalakrishnan

Reputation: 702

You very well can render rdlc into a byte array. Please see a related question I asked a while back. RDLC Local report viewer for ASP.NET Core and Angular(>2.0).

Eventually a creative discussion on that thread resulted in an angular package(https://www.npmjs.com/package/ng2-pdfjs-viewer - Disclosure; I am the author) with consumable rdlc byte array functionality on client side. Of course, instead of this package, you may choose another javascript library to display the byte array.

A simple usage on angular would be like this. Please note, most of the code can be reused even if you are using plain js or another framework.

The below code demonstrates

1. Spitting byte array using RDLC report viewer control on aspnet core action method(on server side) and sending it over wire using http. (Code is in C#)
2. Processing response's byte array into a blob object (Js)
3. Feeding blob object into ng2-pdfjs-viewer.
4. ng2-pdfjs-viewer internally uses Mozilla's PDFJS to accomplish the feat of displaying the PDF on browser.
(FYI.. I took code from samples provided on ng2-pdfjs-viewer package. Replace step 3 and 4 if you are using another library or plain javascript)

<!-- your.component.html -->
<button (click)="showPdf();">Show</button>
<div style="width: 800px; height: 400px">
  <ng2-pdfjs-viewer #pdfViewer></ng2-pdfjs-viewer>
</div>

export class MyComponent implements OnInit {
  @ViewChild('pdfViewer') pdfViewer
  ...

  private downloadFile(url: string): any {
    return this.http.get(url, { responseType: ResponseContentType.Blob }).map(
      (res) => {
        return new Blob([res.blob()], { type: "application/pdf" });
      });
  }

  public showPdf() {
    let url = "http://localhost/api/GetMyPdf";
    this.downloadFile(url).subscribe(
    (res) => {
        this.pdfViewer.pdfSrc = res; // <---- pdfSrc can be Blob or Uint8Array
        this.pdfViewer.refresh(); // Ask pdf viewer to load/reresh pdf
      }
    );
  }

[HttpGet]
[Route("MyReport")]
public IActionResult GetReport()
{
   var reportViewer = new ReportViewer {ProcessingMode = ProcessingMode.Local};
   reportViewer.LocalReport.ReportPath = "Reports/MyReport.rdlc";

   reportViewer.LocalReport.DataSources.Add(new ReportDataSource("NameOfDataSource1", reportObjectList1));
   reportViewer.LocalReport.DataSources.Add(new ReportDataSource("NameOfDataSource2", reportObjectList1));

   Warning[] warnings;
   string[] streamids;
   string mimeType;
   string encoding;
   string extension;

   var bytes = reportViewer.LocalReport.Render("application/pdf", null, out mimeType, out encoding, out extension, out streamids, out warnings);

   return File(bytes, "application/pdf")
}

Upvotes: 2

Default Writer
Default Writer

Reputation: 2566

You can not render .rdlc reports in .NET Core, using .rdlc as a byte array.

Upvotes: 0

Related Questions