DotNetCurry Logo

Create and Print PDF in ASP.NET MVC

Posted by: Mahesh Sabnis , on 5/29/2017, in Category ASP.NET MVC
Views: 21952
Abstract: Use the Rotativa package with ASP.NET MVC to convert a HTML response directly into a PDF document and print the PDF document.

In order to print views displaying reports, tools like Crystal Reports can be used for reporting purposes and to create and print these reports in a printer friendly document. To do so, the report has to be converted into PDF by exporting it to a stream and then converting that stream into a PDF.

For developers using ASP.NET MVC 5, PDF can be directly generated using Rotativa package and sent for printing.

 

Printing PDF in ASP.NET MVC using Rotativa

Rotativa is a framework that provides free APIs for providing an extremely easy way to print PDF documents in ASP.NET MVC Applications. Rotativa is based on the wkhtmltopdf tool to create a PDF document from HTML that renders in the browser.

This framework can be downloaded from this link http://nuget.org/packages/Rotativa.

Rotativa uses the web kit engine which is used by chrome browser to render HTML. Most of the HTML Tags and styles are supported by this framework.

The Rotativa framework provides Rotativa namespace. This namespace contains following classes:

1. ActionAsPdf - accepts a view name as string parameter so that it can be converted into PDF.

2. PartialViewAsPdf - returns partial view as PDF.

3. UrlAsPdf - enables to return any URL as PDF.

4. ViewAsPdf - returns the result as PDF instead of HTML Response.

PDF Printing Demo

This application is developed using ASP.NET MVC 5 with Visual Studio 2015 or the Community Edition.

The Following steps provide additional information of the demo implementation.

Step 1: Open Visual Studio 2015 and create a new ASP.NET WEB Application and name it as MVC_Print_PDF. Select Empty MVC application template to create an empty application.

Step 2: Since this application uses an EntityFramework, in the App_Data folder of the project add a new Sql Server database of name ApplicationDB.mdf. In this database add a new table of the name EmployeeInfo using the following script

CREATE TABLE [dbo].[EmployeeInfo] (
    [EmpNo]       INT          IDENTITY (1, 1) NOT NULL,
    [EmpName]     VARCHAR (50) NOT NULL,
    [Salary]      INT          NOT NULL,
    [DeptName]    VARCHAR (50) NOT NULL,
    [Designation] VARCHAR (50) NOT NULL,
    [HRA]         AS           ([Salary]*(0.2)),
    [TA]          AS           ([Salary]*(0.15)),
    [DA]          AS           ([Salary]*(0.18)),
    [GrossSalary] AS           ((([Salary]+[Salary]*(0.2))+[Salary]*(0.15))+[Salary]*(0.18)),
    [TDS]         AS           (((([Salary]+[Salary]*(0.2))+[Salary]*(0.15))+[Salary]*(0.18))*(0.25)),
    [NetSalary]   AS           (((([Salary]+[Salary]*(0.2))+[Salary]*(0.15))+[Salary]*(0.18))-((([Salary]+[Salary]*(0.2))+[Salary]*(0.15))+[Salary]*(0.18))*(0.25)),
    PRIMARY KEY CLUSTERED ([EmpNo] ASC)
);

In the above table HRA, TA, DA, GrossSalary, TDS, NetSalary columns are generated based on the formula using the Salary column. In this table add test data.

Step 3: Right-Click on the Models folder and add a new ADO.Net Entity Data Model of name AppEntities. In the Entity Model Wizard select Code First from database as shown in the following image.

code-first-from-database

This will generate EmployeeInfo entity class and AppEntities class in the Model folder.

Step 4: To use the Rotativa package in the application, right-click on the references and select Manage NuGet Packages option. This will select NuGet Package Manager window. In this window search for Rotativa from the search window, the package will be displayed as shown in the following image:

rotativa

Install this package, to add Rotativa assembly in the project. The new folder of the name Rotativa will be created in the project containing wkhtmltopdf.exe. This exe is a command line tool to render HTML into PDF.

Step 5: In the Controllers folder, right-click and add a new Empty MVC Controller of the name EmployeeInfoController. In this controller class add the following action methods:

using System.Linq;
using System.Web.Mvc;
using MVC_Print_PDF.Models;
using Rotativa;

namespace MVC_Print_PDF.Controllers
{
    public class EmployeeInfoController : Controller
    {
        AppEntities ctx;
        public EmployeeInfoController()
        {
            ctx = new Models.AppEntities(); 
        }
        public ActionResult Index()
        {
            var emps = ctx.EmployeeInfoes.ToList();
            return View(emps);
        }
        public ActionResult PrintAllReport()
        {
            var report = new ActionAsPdf("Index");
            return report;
        }
        public ActionResult IndexById(int id)
        {
            var emp = ctx.EmployeeInfoes.Where(e=>e.EmpNo==id).First();
            return View(emp);
        }
        public ActionResult PrintSalarySlip(int id)
        {
            var report = new ActionAsPdf("IndexById",new  {id=id});
            return report;
        }
    }
}

The above controller class does the following:

1. The Action Method Index() returns View object showing all Employees.

2. The Action method PrintAllReports() creates an instance of ActionAdPdf() class. The constructor of this class accepts a View Name as string parameter. In this case, the Index view is passed to it. This class prints the HTML rendered output of the Index view as PDF document.

3. The Action method IndexById() accepts an id parameter. This method searches an Employee based on its id and returns a view object showing an Employee information.

4. The Action method PrintSalarySlip() accepts an id parameter. Like the PrintAllreport() action method, this method too creates an instance of ActionAsPdf class. The constructor of this class accepts IndexById view. This method returns HTML rendered IndexById view as a PDF document.

mvc-print-rotativa

Step 6: To add view for the action methods, right click inside the Index() action method and select option Add View. Select List view template and EmployeeInfo model class.

This will add Index.cshtml in EmployeeInfo subfolder of the Views folder and will show all properties from the EmployeeInfo class.

Modify this view to show EmpName, Salary, DeptName, Designation and NetSalary. Replace the Create New action link as shown in the following code:

@Html.ActionLink("Print","PrintAllReport")

Doing so will make a request to the PrintAllReport action method.

Remove Edit, Details and Delete action link from the bottom of the Index.cshtml and add the following action link:

@Html.ActionLink("Print Salary Slip", "PrintSalarySlip", new { id=item.EmpNo })

..to execute PrintSalarySlip action method.

Step 7: Right-click inside the IndexById action method and add an empty view with EmployeeInfo model.

Doing so will add IndexById.cshtml in the EmployeeInfo subfolder of the Views folder. This view will be used to show the Salary Slip. The view will have the following code:

@model MVC_Print_PDF.Models.EmployeeInfo

@{
    ViewBag.Title = "IndexById";
}


<div>
    <h2>Salary Details of : @Model.EmpName</h2>
    <table class="table table-bordered table-condensed table-striped">
        <tr>
            <td>Department Name :</td>
            <td>@Model.DeptName</td>
        </tr>
        <tr>
            <td>Designation :</td>
            <td>@Model.Designation</td>
        </tr>
    </table>
    <table class="table table-bordered table-condensed table-striped">
        <tr>
            <td>
                <table class="table table-bordered table-condensed table-striped">
                    <tr>
                        <td colspan="2">Income Details</td>
                    </tr>
                    <tr>
                        <td>Salary</td>
                        <td>@Model.Salary</td>
                    </tr>
                    <tr>
                        <td>HRA</td>
                        <td>@Model.HRA</td>
                    </tr>
                    <tr>
                        <td>TA</td>
                        <td>@Model.TA</td>
                    </tr>
                    <tr>
                        <td>DA</td>
                        <td>@Model.DA</td>
                    </tr>
                    <tr>
                        <td>Gorss Salary</td>
                        <td>@Model.GrossSalary</td>
                    </tr>
                </table>
            </td>
            <td>
                <table class="table table-bordered table-condensed table-striped">
                    <tr>
                        <td colspan="2">
                            Deductions
                        </td>
                    </tr>
                    <tr>
                        <td>TDS</td>
                        <td>@Model.TDS</td>
                    </tr>

                    <tr>
                        <td>Net Salary</td>
                        <td>
                            @Model.NetSalary
                        </td>
                    </tr>

                </table>
            </td>
        </tr>
    </table>
<p>
       @Html.ActionLink("Back to List", "Index")
</p>
</div>

Step 8: In the RouteConfig.cs of the App_Start folder update the default value of the Route as shown in the following code:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "EmployeeInfo", action = "Index", id = UrlParameter.Optional }
);

This code will run the EmployeeInfoController when application runs.

Run the Application, to display the Index view:

res-index

Click on the Print link to display the PDF result:

pdf-index

..which can be saved as PDF on the local machine as well as can be send to the printer.

Click on the Print Salary Slip link for any record, the PDF result of the Salary Slip for the selected record will be display as shown in the following image:

salary-slip

Conclusion: The Rotativa package provides an extremely easy way to convert a HTML response directly into a PDF document and  print the PDF document in an ASP.NET MVC or similar web application.

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Mahesh Sabnis is a DotNetCurry author and Microsoft MVP having over 17 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). Follow him on twitter @maheshdotnet


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!