Creating PDF In ASP.NET Core MVC Using Rotativa.AspNetCore

In this article, we are going to learn how to use Rotativa.AspNetCore tool to create PDFs from Views in ASP.NET Core. If you have worked with ASP.NET MVC, the Rotativa tool is already available there, which we can use for generating pdfs.

Source code

ASP.NET Core
Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY

This tool was created by Italian Giorgio Bozio. He had a requirement for generating pdf in ASP.NET MVC and a recurring task was to set up a way to create PDF docs, for business flow or reporting.

In the past, I used a lot of Crystal Reports. It had a very nice editor that users who weren't programmers could use with ease. Sometimes, though, it was problematic when installing on new servers and it was expensive, especially for projects where the requirements did not involve producing new layouts frequently.

Then, I found the wkhtmltopdf command line tool, tried it, and looked at opinions on the web. The first experiences were great. It was fast and the PDF docs came out pretty nice. And, most importantly,  it was free.

History of Rotativa referred from - http://letsfollowtheyellowbrickroad.blogspot.in/

What is wkhtmltopdf (wkhtmltopdf.exe)?

wkhtmltopdf is a C library.

wkhtmltopdf and wkhtmltoimage are open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt Web Kit rendering engine.

Definition referred to- https://wkhtmltopdf.org/

Tool to use with ASP.NET MVC

If you want a tool for creating pdf in ASP.NET MVC then you can download it from NuGet.

Command: -  Install-Package Rotativa -Version 1.7.4-rc

Do not use 1.7.3, it has issues.

Find it on GitHub:- https://github.com/webgio/Rotativa

Prerequisite

  1. Visual Studio 2017 with ASP.NET CORE 2.0
  2. AspNetCore 1.0.6 version

Creating ASP.NET Core MVC Application

Now let’s start with creating a simple application in ASP.NET MVC Core.

Open New Visual Studio 2017 IDE.

After opening IDE, next, we are going to create ASP.NET MVC Core project. For doing that, just click File - New - Project.

After choosing a project, a new dialog will pop up with the name "New Project". In that, we are going to choose Visual C# Project Templatesà.NET Coreà ASP.NET Core Web Application. Then, we are going to name the project as "DemoRotativa".

ASP.NET Core

After configuring the project, next, we are going to see project structure.

ASP.NET Core
After creating the project next, we are going to install Rotativa.AspNetCore to the project.

Installing Rotativa.AspNetCore to project

We are going to install Rotativa.AspNetCore 1.0.6 version which needs dependency of AspNetCore MVC 2.o. We already have created ASP.NET CORE 2.0 project; we do not need to worry.

We can install it via package manager console or via Manage package solution Windows.

ASP.NET Core

Let’s install it using package manager console.

ASP.NET Core

After installing Rotativa.AspNetCore next, we need to do configuration.

Configuration Rotativa.AspNetCore setting in a startup.cs class

We add this setting in a startup.cs class inside Configure method to set a relative path to the wkhtmltopdf.exe file to access.

RotativaConfiguration.Setup(env);

ASP.NET Core

Next, we need to add a new Folder in WWW with name “Rotativa” and inside this folder, we are going to add

wkhtmltopdf.exe, wkhtmltoimage.exe files.

You can download this files from GitHub if you download sample solution which I have provided

https://github.com/webgio/Rotativa.AspNetCore

Note

Download the solution and you will get this exe files.

ASP.NET Core

Next, after adding exe files, we are going to add Controller.

Adding DemoController

For adding controller just right click on controller folder then choose "Add," inside that, choose to Add New item. A new dialog will popup  with  Add New item, inside that choose "MVC Controller Class" and Name your controller as "DemoController" and click on Add button to create a Demo controller.

ASP.NET Core

After adding controller, next, we are going to Add Action to this Controller.

Adding [HttpGet] DemoViewAsPDF Action Method

We are going to add action method with name DemoViewAsPDF and this action method will return ViewAsPdf result.

Complete Code Snippet of DemoViewAsPDF

  1. using Microsoft.AspNetCore.Mvc;  
  2. using Rotativa.AspNetCore;  
  3.   
  4.   
  5. namespace DemoRotativa.Controllers  
  6. {  
  7.     public class DemoController : Controller  
  8.     {  
  9.         public IActionResult DemoViewAsPDF()  
  10.         {  
  11.             return new ViewAsPdf("DemoViewAsPDF");  
  12.         }  
  13.     }  
  14. }  

After adding Action Method, next, we are going to add “DemoViewAsPDF” View.

Adding DemoViewAsPDF View

ASP.NET Core

On this View, we have added simple Billing Invoice.

Code snippet of DemoViewAsPDF View

  1. @{  
  2.     Layout = null;  
  3. }  
  4.   
  5. <html>  
  6. <head>  
  7.     <meta charset="utf-8">  
  8.     <title>Demo</title>  
  9.     <link rel="stylesheet" href="style.css">  
  10.     <link rel="license" href="https://www.opensource.org/licenses/mit-license/">  
  11.     <script src="script.js"></script>  
  12.     <link href="~/css/demo.css" rel="stylesheet" />  
  13.       
  14. </head>  
  15. <body>  
  16.     <header>  
  17.         <h1>Invoice</h1>  
  18.         <address contenteditable>  
  19.             <p>Jonathan Neal</p>  
  20.             <p>101 E. Chapman Ave<br>Orange, CA 92866</p>  
  21.             <p>(800) 555-1234</p>  
  22.         </address>  
  23.         <span><img src="D:\DemoRotativa\DemoRotativa\DemoRotativa\wwwroot\images\Invoice.jpg" /><input type="file" accept="image/*"></span>  
  24.     </header>  
  25.     <article>  
  26.         <h1>Recipient</h1>  
  27.         <address contenteditable>  
  28.             <p>Demo Company<br>c/o Saineshwar</p>  
  29.         </address>  
  30.         <table class="meta">  
  31.             <tr>  
  32.                 <th><span contenteditable>Invoice #</span></th>  
  33.                 <td><span contenteditable>000001</span></td>  
  34.             </tr>  
  35.             <tr>  
  36.                 <th><span contenteditable>Date</span></th>  
  37.                 <td><span contenteditable>January 1, 2018</span></td>  
  38.             </tr>  
  39.             <tr>  
  40.                 <th><span contenteditable>Amount Due</span></th>  
  41.                 <td><span id="prefix" contenteditable>र </span><span>600.00</span></td>  
  42.             </tr>  
  43.         </table>  
  44.         <table class="inventory">  
  45.             <thead>  
  46.                 <tr>  
  47.                     <th><span contenteditable>Item</span></th>  
  48.                     <th><span contenteditable>Description</span></th>  
  49.                     <th><span contenteditable>Rate</span></th>  
  50.                     <th><span contenteditable>Quantity</span></th>  
  51.                     <th><span contenteditable>Price</span></th>  
  52.                 </tr>  
  53.             </thead>  
  54.             <tbody>  
  55.                 <tr>  
  56.                     <td><a class="cut">-</a><span contenteditable>Front End Consultation</span></td>  
  57.                     <td><span contenteditable>Experience Review</span></td>  
  58.                     <td><span data-prefix>र </span><span contenteditable>150.00</span></td>  
  59.                     <td><span contenteditable>4</span></td>  
  60.                     <td><span data-prefix>र </span><span>600.00</span></td>  
  61.                 </tr>  
  62.             </tbody>  
  63.         </table>  
  64.   
  65.         <table class="balance">  
  66.             <tr>  
  67.                 <th><span contenteditable>Total</span></th>  
  68.                 <td><span data-prefix>र </span><span>600.00</span></td>  
  69.             </tr>  
  70.             <tr>  
  71.                 <th><span contenteditable>Amount Paid</span></th>  
  72.                 <td><span data-prefix>र </span><span contenteditable>0.00</span></td>  
  73.             </tr>  
  74.             <tr>  
  75.                 <th><span contenteditable>Balance Due</span></th>  
  76.                 <td><span data-prefix>र </span><span>600.00</span></td>  
  77.             </tr>  
  78.         </table>  
  79.     </article>  
  80.   
  81.     <aside>  
  82.         <h1><span contenteditable>Additional Notes</span></h1>  
  83.         <div contenteditable>  
  84.             <p>A finance charge of 1.5% will be made on unpaid balances after 30 days.</p>  
  85.         </div>  
  86.     </aside>  
  87. </body>  
  88. </html>  

Now we have completed with all settings so let’s save this application and access your First Pdf.

URL to access:- http://localhost:#####/demo/DemoViewAsPDF

Snapshot of Pdf

ASP.NET Core

Setting Margin to Pdf

For displaying a demo of Margin we are going to add another Action Method with name “DemoPageMarginsPDF” and along with this we are also going to add View with the same name “DemoPageMarginsPDF”.

Code snippet for setting Margin to Pdf

  1. public IActionResult DemoPageMarginsPDF()  
  2. {  
  3.     var report = new ViewAsPdf("DemoPageMarginsPDF")  
  4.     {  
  5.         PageMargins = { Left = 20, Bottom = 20, Right = 20, Top = 20 },  
  6.     };  
  7.     return report;  
  8. }  

Output

ASP.NET Core

Setting Orientation to Pdf

  1. Landscape
  2. Portrait

Code snippet for setting Orientation to Pdf 

  1. public IActionResult DemoOrientationPDF(string Orientation)  
  2.  {  
  3.      if (Orientation == "Portrait")  
  4.      {  
  5.          var demoViewPortrait = new ViewAsPdf("DemoViewAsPDF")  
  6.          {  
  7.              FileName = "Invoice.pdf",  
  8.              PageOrientation = Rotativa.AspNetCore.Options.Orientation.Portrait,  
  9.          };  
  10.          return demoViewPortrait;  
  11.      }  
  12.      else  
  13.      {  
  14.          var demoViewLandscape = new ViewAsPdf("DemoViewAsPDF")  
  15.          {  
  16.              FileName = "Invoice.pdf",  
  17.              PageOrientation = Rotativa.AspNetCore.Options.Orientation.Landscape,  
  18.          };  
  19.          return demoViewLandscape;  
  20.      }  
  21.  }  

Output - Orientation Portrait

Url to access :- http://localhost:60042/demo/DemoOrientationPDF?Orientation=Portrait

ASP.NET Core

Output - Orientation Landscape

Url to access :- http://localhost:60042/demo/DemoOrientationPDF?Orientation=Landscape 

ASP.NET Core

Notes :- https://wkhtmltopdf.org/usage/wkhtmltopdf.txt

Setting Page number to Pdf

The customization of the pdf files can be done using Custom Switches.

Options

ArgumentsDescription
--page-offset <offset>Set the starting page number (default 0)
--footer-center <text>Centered footer text
   [page]Replaced by the number of the pages currently being printed
--footer-font-size <size>Set footer font size (default 12)   

For adding a Page number at the footer of the page we are going to use Custom Switches. 

Code snippet for setting Page Number to Pdf

  1. public IActionResult DemoPageNumberPDF()  
  2. {  
  3.     return new ViewAsPdf("DemoPageNumberPDF")  
  4.     {  
  5.         CustomSwitches = "--page-offset 0 --footer-center [page] --footer-font-size 12"  
  6.     };  
  7. }  

Output

ASP.NET Core

Setting Page Size to Pdf

We can set various page sizes of pdf, such as “A0”, “A1”, “A2”, “A3”, “A4”, “A5”. etc.

For the demo, we are going to set “A6” Size.

Code snippet for setting Page Size to Pdf

  1. public IActionResult DemoPageSizePDF()  
  2. {  
  3.     return new Rotativa.AspNetCore.ViewAsPdf("DemoPageSizePDF")  
  4.     {  
  5.         PageSize = Rotativa.AspNetCore.Options.Size.A6,  
  6.     };  
  7. }  

ASP.NET Core

Output

ASP.NET Core

Setting Page Number in different format to PDF

For adding a Page number at the footer of the page, we are going to use Custom Switches.

In this part, we display current date with current page number and last page number in the footer.

e.g.:

Current Date “18/02/2018” Page:  Current page / Last Page

Options

Arguments Description 
–footer-center This aligns the footer at the center foot of the page. 
Page:[page]/[toPage] The [page] to [toPage] marks the current page and the total number of pages in the file 
–footer-font-size Displays line above the footer 
–footer-spacing Sets the spacing between the footer-line and the text 
–footer-line Displays line above the footer 
–footer-font-name Sets the font family/style of text 

Code snippet 

  1. public IActionResult DemoPageNumberwithCurrentDate()  
  2. {  
  3.     var pdfResult = new ViewAsPdf("DemoPageNumberwithCurrentDate")  
  4.     {  
  5.         CustomSwitches =  
  6.             "--footer-center \"  Created Date: " +  
  7.           DateTime.Now.Date.ToString("dd/MM/yyyy") + "  Page: [page]/[toPage]\"" +  
  8.           " --footer-line --footer-font-size \"12\" --footer-spacing 1 --footer-font-name \"Segoe UI\""  
  9.     };  
  10.   
  11.     return pdfResult;  
  12. }  

ASP.NET Core

Converting Model-based View to Pdf

In this part, we are going to send the model to view and then we are going to convert view to pdf, for doing that first we need to add Model, we are going to add a simple model with name “Customer”.

Customer Model

  1. public class Customer  
  2. {  
  3.     public int CustomerID { get; set; }  
  4.     public string Name { get; set; }  
  5.     public string Address { get; set; }  
  6.     public string Country { get; set; }  
  7.     public string City { get; set; }  
  8.     public string Phoneno { get; set; }  
  9. }  

Adding New Action Method DemoModelPDF

In this action method, we are going create a list of customers and send this collection to DemoModelPDF View.

Code snippet

  1. public IActionResult DemoModelPDF()  
  2.  {  
  3.      List<Customer> customerList = new List<Customer>()  
  4.      {  
  5.          new Customer { CustomerID = 1, Address = "Taj Lands Ends 1", City = "Mumbai" , Country ="India", Name ="Sai", Phoneno ="9000000000"},  
  6.          new Customer { CustomerID = 2, Address = "Taj Lands Ends 2", City = "Mumbai" , Country ="India", Name ="Ram", Phoneno ="9000000000"},  
  7.          new Customer { CustomerID = 3, Address = "Taj Lands Ends 3", City = "Mumbai" , Country ="India", Name ="Sainesh", Phoneno ="9000000000"},  
  8.          new Customer { CustomerID = 4, Address = "Taj Lands Ends 4", City = "Mumbai" , Country ="India", Name ="Saineshwar", Phoneno ="9000000000"},  
  9.          new Customer { CustomerID = 5, Address = "Taj Lands Ends 5", City = "Mumbai" , Country ="India", Name ="Saibags", Phoneno ="9000000000"}  
  10.   
  11.      };  
  12.   
  13.      return new ViewAsPdf("DemoModelPDF", customerList);  
  14.  }  

DemoModelPDF View

On View, we just iterate Customer collection.

Code snippet of DemoModelPDF View

  1. @model List<DemoRotativa.Models.Customer>  
  2. @{  
  3.     Layout = null;  
  4. }  
  5.   
  6. <!DOCTYPE html>  
  7. <html lang="en">  
  8. <head>  
  9.     <title>Bootstrap Example</title>  
  10.     <meta charset="utf-8">  
  11.     <meta name="viewport" content="width=device-width, initial-scale=1">  
  12.     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
  13.     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>  
  14.     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
  15. </head>  
  16. <body>  
  17.     <div class="container">  
  18.         <h2>Customer</h2>  
  19.         <p>Customer Details</p>  
  20.         <table class="table table-bordered">  
  21.             <thead>  
  22.                 <tr>  
  23.                     <th>CustomerID</th>  
  24.                     <th>Name</th>  
  25.                     <th>Address</th>  
  26.                     <th>Country</th>  
  27.                     <th>City</th>  
  28.                     <th>Phoneno</th>  
  29.                 </tr>  
  30.             </thead>  
  31.             <tbody>  
  32.   
  33.                 @foreach (var item in Model)  
  34.                 {  
  35.                     <tr>  
  36.                         <td>@item.CustomerID</td>  
  37.                         <td>@item.Name</td>  
  38.                         <td>@item.Address</td>  
  39.                         <td>@item.Country</td>  
  40.                         <td>@item.City</td>  
  41.                         <td>@item.Phoneno</td>  
  42.                     </tr>  
  43.                 }  
  44.   
  45.             </tbody>  
  46.         </table>  
  47.     </div>  
  48. </body>  
  49. </html> 

Output

ASP.NET Core

Conclusion

In this article, we have learned how to use Rotativa.AspNetCore with ASP.NET Core in a step by step way. First we started with creating Project then controller after that we have added NuGet package of Rotativa.AspNetCore and further we have created PDF of View in various ways.

Note

Do not use ViewData and TempData to display data on View because it has some issues which will resolve soon; use Model which works perfectly.