How to Convert HTML to PDF in ASP.NET Core MVC

How to Convert HTML to PDF in ASP.NET Core MVC

In this article, I will discuss How to Convert HTML to PDF in an ASP.NET Core MVC Application with Examples using Rotativa.AspNetCore Library. Please read our previous article discussing How to Generate Password Protected PDF in ASP.NET Core MVC Application with Examples. Let’s continue with the application we worked on in previous articles.

HTML to PDF Conversion in ASP.NET Core MVC

Many web applications need to generate reports, invoices, receipts, or other documents. HTML is a flexible and familiar way to design and layout these documents. Once designed in HTML, they can be converted to PDF for easy distribution, printing, and consistent viewing across various platforms.

Developers can leverage HTML and CSS skills for designing documents, which are then easily converted to PDF, rather than learning a new language or tool specifically for PDF generation.

HTML templates can be dynamically generated and customized with data from databases or user inputs, making it a scalable solution for generating personalized documents for each user.

Converting HTML to PDF in an ASP.NET Core MVC application can be achieved through various methods. One common approach is to use a third-party library. Libraries like Rotativa, WkHtmlToPdf, DinkToPdf, SelectPdf, or iTextSharp can be integrated into your ASP.NET Core MVC application to perform the conversion.

Rotativa.AspNetCore Library:

Rotativa.AspNetCore is a library for the ASP.NET Core framework that allows developers to convert HTML pages into PDF documents easily. The library is based on the wkhtmltopdf tool, which converts HTML content rendered by the WebKit engine to PDF format. Key features and aspects of Rotativa.AspNetCore includes:

  • HTML to PDF Conversion: It enables the conversion of HTML views or pages to PDF documents, which is particularly useful for generating reports, invoices, and other documents that are typically rendered in a web application.
  • Easy Integration: Rotativa.AspNetCore is designed to integrate seamlessly with ASP.NET Core applications, making it relatively straightforward to generate PDFs from Razor views and HTML content.
  • Customization Options: It provides various options to customize the PDF generation process, such as setting page margins, orientation, custom headers and footers, and more.
  • Ease of Use: Rotativa.AspNetCore simplifies the PDF generation process to a few lines of code, making it accessible even to developers who are not deeply familiar with PDF generation techniques.
  • Support for JavaScript and CSS: Since it’s based on a web rendering engine, it supports advanced features of modern HTML, CSS, Bootstrap, and JavaScript, allowing for rich, styled content in PDFs.
How do you convert views to PDF in ASP.NET Core MVC?

Generating a PDF in ASP.NET Core MVC from views involves several steps. Here’s a general approach to accomplish this:

Install Rotativa.AspNetCore Library:

Several libraries are available for generating PDFs in ASP.NET Core, such as iTextSharp, DinkToPdf, and Rotativa.AspNetCore. Each has its own set of features and ways of working. Here, we are going to use Rotativa.AspNetCore library. You can install this library via the NuGet package manager. For instance, if you choose Rotativa.AspNetCore, you can install it by running the following command in the Package Manager Console:

Install Rotativa.AspNetCore Library

Download wkhtmltopdf:

You need to download wkhtmltopdf, the underlying tool Rotativa uses. You can download it from the official wkhtmltopdf website. So, please visit to the following website:

https://wkhtmltopdf.org/downloads.html

This will open the following page. Choose the correct version for your operating system.

Download wkhtmltopdf

Once you download the exe, then install it on your machine. After installing wkhtmltopdf, note the installation path. This is typically something like C:\Program Files\wkhtmltopdf\ on Windows. In my machine, it is in the below location:

Download wkhtmltopdf

Configure Rotativa Path

Your ASP.NET MVC application needs to know where to find wkhtmltopdf.exe. If you’re using a library like Rotativa, which is common for PDF generation in MVC applications, you often have to set the path to wkhtmltopdf.exe in your application’s code. For example, if using Rotativa, you might need to configure the path in the Program.cs class like this:

RotativaConfiguration.Setup(app.Environment.WebRootPath, @”C:\\Program Files\\wkhtmltopdf\\bin”);

Replace C:\\Program Files\\wkhtmltopdf\\bin with the actual path where wkhtmltopdf.exe is located.

Create an Action Method to Generate a PDF:

The PDF generation process will depend on the library you choose, for example, with Rotativa.AspNetCore, you can easily convert a view to a PDF.

First, ensure your action method returns a view that you want to convert to PDF. Then, instead of returning a View() from your action method, use Rotativa.AspNetCore will return a ViewAsPdf() result to convert the view to a PDF.

So, add the following Action Method within the FileUpload Controller. This action method will generate a PDF from a View and then return that PDF to the Client. In the following action method, “GeneratePDFFromView” is the name of the Razor view, and the invoice is the model object that contains data for the view.

public IActionResult GeneratePDFFromView()
{
    // Sample invoice data
    // Here, we have hardcoded the data,
    // In Real-time you will get the data from the database
    var invoice = new Invoice
    {
        InvoiceNumber = "INV-DOTNET-1001",
        Date = DateTime.Now,
        CustomerName = "Pranaya Rout",
        Items = new List<InvoiceItem>
                {
                    new InvoiceItem { ItemName = "Item 1", Quantity = 2, UnitPrice = 15.0m },
                    new InvoiceItem { ItemName = "Item 2", Quantity = 3, UnitPrice = 10.0m },
                    new InvoiceItem { ItemName = "Item 3", Quantity = 1, UnitPrice = 35.0m }
                },
        PaymentMode = "COD"
    };

    //Set the Total Amount
    invoice.TotalAmount = invoice.Items.Sum(x => x.TotalPrice);

    return new ViewAsPdf("GeneratePDFFromView", invoice)
    {
        FileName = "MyInvoice.pdf"
    };
}
Creating the View:

Next, add a view with the name GeneratePDFFromView.cshtml and copy and paste the following code. We are not using any Loyout because we don’t need the website header and footer in the PDF.

@{
    Layout = null;
    int SR_NO = 1;
}

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Invoice</title>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    @*  Invoice Container: Create a main container for your invoice. *@
    <div class="container">
        <!-- Invoice content goes here: Include your company details or any header information -->
        <div class="row">
            <div style="text-align:center" class="col">
                <h2 style="font-size:30px" class="text-danger">Invoice</h2>
            </div>
            <div class="col text-right">
                <p style="font-size:18px"><b>Invoice #</b>@Model.InvoiceNumber</p>
                <p style="font-size:18px"><b>Date:</b> @Model.Date</p>
            </div>
        </div>
        
        @* Billing Information: Add sections for billing to and from, and other details.*@
        <div class="row mb-4">
            <div style="font-size:18px" class="col-sm-6">
                <div>
                    <strong>Bill From</strong>
                </div>
                <div>Address Line 1</div>
                <div>City, Zip</div>
                <div>Email: info@dotnettutorials.net</div>
                <div>Phone: +1234567890</div>
            </div>
            <br />
            <div style="font-size:18px" class="col-sm-6">
                <div>
                    <strong>Billed To:</strong>
                </div>
                <div>@Model.CustomerName</div>
                <div>City, Zip</div>
                <div>Email: CustomerName@edotnettutorials.net</div>
                <div>Phone: +987654321</div>
            </div>
        </div>

        @* Invoice Items: Create a table for line items. *@
        <div class="table-responsive">
            <table class="table table-striped">
                <thead style="font-size:20px">
                    <tr>
                        <th scope="col">SR NO:</th>
                        <th scope="col">Item</th>
                        <th scope="col">Quantity</th>
                        <th scope="col">Unit Price</th>
                        <th scope="col">Total</th>
                    </tr>
                </thead>
                <tbody style="font-size:18px">
                    @foreach (var item in Model.Items)
                    {
                        <tr>
                            <td>@SR_NO</td>
                            <td>@item.ItemName</td>
                            <td>@item.Quantity</td>
                            <td>@item.UnitPrice</td>
                            <td>@item.TotalPrice</td>
                        </tr>
                        SR_NO++;
                    }
                    <tr>
                        <td colspan="4" style="text-align: right;"><strong>Total</strong></td>
                        <td><strong>@Model.TotalAmount</strong></td>
                    </tr>
                </tbody>
            </table>
        </div>

        @* Footer: Optionally, add a footer for additional notes or terms. *@
        <div class="row">
            <div class="col">
                <p class="text-center" style="font-size:20px">Thank you for your shopping</p>
            </div>
        </div>
    </div>
</body>
</html>
Link to the PDF Generation Action

In your view, create a link to the controller action that generates the PDF. So, modify the DownloadPDF.cshtml view as follows to provide a link to the GeneratePDFFromView action method.

@{
    ViewData["Title"] = "DownloadPDF";
}

<h1>Download PDF</h1>
<a href="@Url.Action("GenerateInvoicePDF", "FileUpload")">Download Invoice</a>
<br/>
<h1>Download Password Protected PDF</h1>
<a href="@Url.Action("GeneratePasswordProtectedInvoicePDF", "FileUpload")">Download Password Protected Invoice</a>
<br />
<h1>Generate PDF from View</h1>
<a href="@Url.Action("GeneratePDFFromView", "FileUpload")">Generate PDF From View</a>
Run and Test

Run your application and navigate to the URL FileUpload/DownloadPDF, which should open the following page. Clicking on the Generate PDF From View link, as shown in the image below, triggers the PDF generation and download.

HTML to PDF Conversion in ASP.NET Core MVC Application with Examples using Rotativa.AspNetCore Library

Once you click on the Generate PDF From View link, it will generate the PDF from View and then download the PDF as shown in the below image:

HTML to PDF Conversion in ASP.NET Core MVC Application with Examples

How do you generate A Password-protected PDF in ASP.NET Core MVC using Rotativa?

Generating a Password Protected PDF in ASP.NET Core MVC from views using Rotativa requires a combination of steps, including setting up Rotativa, generating a PDF from a view, and then applying password protection. By default, Rotativa itself doesn’t directly support adding password protection to a PDF. However, we can achieve this by first generating the PDF with Rotativa and then adding password protection using another library like iTextSharp or iText7.

Generate PDF from a View using Rotativa.

First, generate the PDF from a Razor View using Rotativa. So, modify the GeneratePDFFromView action method as follows:

public IActionResult GeneratePDFFromView()
{
    // Sample invoice data
    // Here, we have hardcoded the data,
    // In Real-time you will get the data from the database
    var invoice = new Invoice
    {
        InvoiceNumber = "INV-DOTNET-1001",
        Date = DateTime.Now,
        CustomerName = "Pranaya Rout",
        Items = new List<InvoiceItem>
                {
                    new InvoiceItem { ItemName = "Item 1", Quantity = 2, UnitPrice = 15.0m },
                    new InvoiceItem { ItemName = "Item 2", Quantity = 3, UnitPrice = 10.0m },
                    new InvoiceItem { ItemName = "Item 3", Quantity = 1, UnitPrice = 35.0m }
                },
        PaymentMode = "COD"
    };

    //Set the Total Amount
    invoice.TotalAmount = invoice.Items.Sum(x => x.TotalPrice);


    var report = new ViewAsPdf("GeneratePDFFromView", invoice)
    {
        FileName = "UnprotectedReport.pdf"
    };
    return report;
}
Add Password Protection to the PDF using iText

After generating the PDF with Rotativa, use iText to read this PDF and re-save it with password protection. So, add the following action method within the FileUpload controller.

public IActionResult GenerateProtectedPDF()
{
    // Generate PDF from View using Rotativa
    var rotativaResult = GeneratePDFFromView() as ViewAsPdf;

    //Conver View to byte Array
    var binaryPdf = rotativaResult.BuildFile(ControllerContext).Result;

    // Define memory stream to store the protected PDF
    MemoryStream protectedPdfStream = new MemoryStream();

    // Define writer properties with password protection
    WriterProperties props = new WriterProperties()
        .SetStandardEncryption(
            userPassword: System.Text.Encoding.UTF8.GetBytes("Abcd1234"),
            ownerPassword: System.Text.Encoding.UTF8.GetBytes("1234XYZ"),
            permissions: 0,
            encryptionAlgorithm: EncryptionConstants.ENCRYPTION_AES_128
        );

    // Initialize PDF writer
    PdfWriter writer = new PdfWriter(protectedPdfStream, props);

    // Read the generated PDF from Rotativa
    PdfReader reader = new PdfReader(new MemoryStream(binaryPdf));

    // Initialize PDF document
    using (PdfDocument pdfDoc = new PdfDocument(reader, writer))
    {
        pdfDoc.Close();
    }

    // Return the password-protected PDF
    return new FileStreamResult(new MemoryStream(protectedPdfStream.ToArray()), "application/pdf")
    {
        FileDownloadName = "ProtectedReport.pdf"
    };
}

Explanation

  • The GeneratePDFFromView method uses Rotativa to convert a view into a PDF.
  • The GenerateProtectedPDF method then takes this PDF, reads it with iText, and applies password protection.
  • The ViewAsPdf class is part of Rotativa and generates a PDF from a Razor view.
  • The PdfReader and PdfWriter classes from iText are used to handle the PDF reading and writing processes, respectively.
Call the Method from the front end.

Add a button or link in your front end that triggers the GenerateProtectedPDF action to allow users to download the password-protected PDF. So, modify the DownloadPDF.cshtml view as follows to provide a link to the GenerateProtectedPDF action method.

@{
    ViewData["Title"] = "DownloadPDF";
}

<h1>Download PDF</h1>
<a href="@Url.Action("GenerateInvoicePDF", "FileUpload")">Download Invoice</a>
<br/>
<h1>Download Password Protected PDF</h1>
<a href="@Url.Action("GeneratePasswordProtectedInvoicePDF", "FileUpload")">Download Password Protected Invoice</a>
<br />
<h1>Generate PDF from View</h1>
<a href="@Url.Action("GenerateProtectedPDF", "FileUpload")">Generate PDF From View</a>

Now, run the application and test it, and it should work as expected.

In the next article, I will discuss How to Send Emails with Attachments in ASP.NET Core MVC Application with examples. In this article, I try to explain HTML to PDF Conversion in ASP.NET Core MVC Application with Examples. I hope you enjoy this article on HTML to PDF Conversion in ASP.NET Core MVC.

Leave a Reply

Your email address will not be published. Required fields are marked *