Search code examples
c#asp.net-coreblazorwkhtmltopdfrotativa

How to use wkhtmltopdf Rotativa ViewAsPdf in Blazor Server


I would like to use Rotativa.AspNetCore.ViewAsPdf("~/Views/MyView/PDF.cshtml", model) in Blazor Server the same way I do in regular ASP.NET CORE MVC apps.

  1. I installed the "Rotativa.AspNetCore" nuget in my Blazor server project in .NET 8

  2. Added RotativaConfiguration.Setup(app.Environment.WebRootPath); app.UseRotativa(); in Program.cs

  3. Created a "Views" folder with a PDF.cshtml view

  4. Created a Controller I am calling via httpClient from my razor component to generate the PDF

[HttpPost("exportPDF")]
public ActionResult ExportPDF(PDFModel model)
{

    return new Rotativa.AspNetCore.ViewAsPdf("~/Views/MyView/PDF.cshtml", model)
    {
        FileName = "MyFile" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf",
        PageSize = Rotativa.AspNetCore.Options.Size.A4,
        PageOrientation = Rotativa.AspNetCore.Options.Orientation.Portrait,
        PageMargins = { Left = 15, Right = 15, Top = 15 },
        CustomSwitches = "--footer-center \"MyDocument + "\" --footer-right \"Page: [page]/[toPage]\" --footer-font-size \"6\""
    };
}

And I am getting an "Object reference not set to an instance of an object." exception from the "Rotativa.AspNetCore" source.

Has anyone got this working in Blazor?


Solution

  • I got it working by myself. It is totally possible to use rotativa.exe and Rotativa.AspNetCore nuget to generate PDFs in Blazor using the "ViewAsPdf" method. My initial setup was good and I added following two controller methods:

    public async Task<FileResult> ReturnPDF(int modelId)
    {
        PDFModel model = new PDFModel(); //or load from db
    
        byte[] pdfBytes = await GetPDFBytes(model);
    
        return File(pdfBytes, "application/pdf");
    }
    

    which calls following that creates the pdf using rotativa:

    public async Task<byte[]> GetPDFBytes(PDFModel model)
    {
    
       var pdf =  new Rotativa.AspNetCore.ViewAsPdf("~/Views/PDF.cshtml", model)
       {
           FileName = "Export_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf",
           PageSize = Rotativa.AspNetCore.Options.Size.A4,
           PageOrientation = Rotativa.AspNetCore.Options.Orientation.Portrait,
           PageMargins = { Left = 15, Right = 15, Top = 15 },
           CustomSwitches = "--footer-center \"ID_" + model.Id + "\" --footer-right \"Page: [page]/[toPage]\" --footer-font-size \"6\""
    };
    
       byte[] pdfBytes = await pdf.BuildFile(this.ControllerContext);
       return pdfBytes;
    

    }

    and calling it from .razor component via:

    <a href="@(_navManager.BaseUri + "mypage/ReturnPDF")" class="btn btn-danger" target="_blank">PDF_TEST_FileResult</a>
    

    I have also tried creating an API controller and send it a post request with whole PDF model, but the PDF never displayed in the browser, but got returned to the calling object in razor code.