How do I render and return a view as pdf

374 views Asked by At

So I'm trying to add a new endpoint to my controller which can return the html response of another endpoint at pdf. The reason for this is deprecate a 3rd party service which involves all kinds of other problems.

I've found a library called IronPDF which seems to do the job, but I'm now struggling to get the html of the original endpoint. It looks something like this:

public class HomeController : Controller
{
    public HomeController() : base() { }

    public IActionResult Index()
    {
        return View();
    }
    
    public IActionResult IndexPdf()
    {
        ViewResult view = Index() as ViewResult;
        HtmlToPdf renderer = new HtmlToPdf();

        // How do I get the html content of view as a string here?
        string html = ??

        PdfDocument pdf = renderer.RenderHtmlAsPdf(html);
        
        using (var stream = pdf.Stream)
        {
            return File(stream, "application/pdf", "Index.pdf");
        }
    }
}

How do I get the html of the ViewResult?

This is just an example, I'm hoping to adapt it to handle dynamic pages in future. Is there a better way of doing this?

2

There are 2 answers

0
Ruikai Feng On

You could try as below in your controller:

public async Task<IActionResult> IndexPdf()
    {
        using StringWriter sw = new StringWriter();
        IView view = _viewEngine.FindView(ControllerContext, "Index",true).View??default!;
        ViewContext viewContext = new ViewContext(ControllerContext, view, ViewData, TempData, sw, new HtmlHelperOptions());
        await view.RenderAsync(viewContext);
        var content = sw.GetStringBuilder().ToString();

        ChromePdfRenderer renderer = new ChromePdfRenderer();

        PdfDocument pdf = renderer.RenderHtmlAsPdf(content);
        return File(pdf.Stream, "application/pdf", "Index.pdf");
        

    }

inject ICompositeViewEngine into your controller:

private readonly ICompositeViewEngine _viewEngine;

        public HomeController(ILogger<HomeController> logger, ICompositeViewEngine viewEngine)
        {
            .......
            _viewEngine = viewEngine;
        }

Result:

enter image description here

Notice:

1,HtmlToPdf is obsolote,you could try with ChromePdfRenderer

2,You have to input full address for your css files,or the css won't work

enter image description here

the content string is OK,I checked with return Ok(content):

enter image description here

3,You could just try with

renderer.RenderUrlAsPdfAsync("targeturl");

directly,without getting the html of the ViewResult.

0
Chaknith Bin On

IronPdf just released extensions that help in rendering web application view and page content to PDF. Please use the IronPdf.Extensions.Mvc.Core package for ASP.NET MVC Core. This package only serve as an extension. The IronPdf package is still needed to render Razor Views to PDFs.

For Example: Models

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
}

In the HomeController file, use the RenderRazorViewToPdf method and pass IRazorViewRenderer, the path to our "Persons.cshtml," and the List that contains the required data.

public async Task<IActionResult> Persons()
{
    var persons = new List<Person>
    {
    new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
    new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
    new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
    };
    if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
    {
        ChromePdfRenderer renderer = new ChromePdfRenderer();

        // Render Razor view to PDF document
        PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);
        Response.Headers.Add("Content-Disposition", "inline");

        // Output PDF document
        return File(pdf.BinaryData, "application/pdf", "razorViewToPdf.pdf");
    }
    return View(persons);
}