Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

jQGrid PDF Export

0.00/5 (No votes)
18 Jun 2013 1  
Export your content from jQGrid to PDF format with less pain using iTextSharp.

Introduction

The aim of this article is to address the PDF export from client side grid frameworks. The solution is done using the iTextSharp in ASP.NET MVC 4 and Visual Studio 2012. jQGrid is one of the client grid framework built on top of the jQuery framework. It helps in building a beautiful grid with paging, sorting and exiting options. There are also other features available as extension plugins and developers can write their own if needed. Please do a nuget update before running the demo code if you face DLL reference issue. I have enabled nugget restore, hence references will be downloaded and updated during the build.

Background

The article assumes the developer to have a fair amount of knowledge on ASP.NET MVC and C#.

Tools used:

  • Visual Studio 2012
  • ASP.NET MVC 4
  • Nuget Package Manager

Developers can learn about the jQuery and jQueryUI at http://jquery.com/

jQgrid related wiki can be found at below links:

iTextSharp tutorials can be found at the following link

Using the code

You can download the jQgrid from the jQGrid homepage or as NUget package. I have given below the command to download the jQGrid through the package manager console. From the tools menu select “Library Package Manager” and then select “Package Manager Console”. I have given the screenshot below.

This command will pull down the latest JQGrid package and adds them in the script folder.

Once the script is downloaded and referenced in the project update the bundleconfig file to add the script reference in the pages. Bundleconfig can be found in the App_Start folder in the project structure. .

bundles.Add(new StyleBundle("~/Content/jqgrid").Include("~/Content/ui.jqgrid.css")); 
bundles.Add(new ScriptBundle("~/bundles/jquerygrid").Include(
  "~/Scripts/jqGrid/jquery.jqGrid*"));

Once added the config’s refer the bundles to the Views/Shared/LayoutPage.cshtml. Add the following lines to the head section of the page.

@Styles.Render("~/Content/jqgrid")

Add the following lines to the end of the page before html close tags.

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryui")
@Scripts.Render("~/bundles/jquerygrid") 

That’s all to be done from the view perspective. Once these steps are done the developer can start coding for the JQGrid. In this example we will modify the HomeController for the demo. The index action will be the default action. We will add an argument for this index action. Let it be nullable bool. It’s just to mark the PDF request. In Index.cshtml, we will add a table tag with an id “gridTable”. We will use this table for making the grid. Since jQGrid is an extension for the jQuery we will initialize the grid setting at the script section of the page. This script section is marked at the end of the page to improve performance. The script section is placed just below the bundle reference for jQuery and jQueryUI. This is the one of improvement factors from “why slow” provided by yahoo.

<table id="gridTable" class="scroll"></table>
<input type="button" value="Export PDF" onclick="exportPDF();" />
@section scripts
{
<script type="text/javascript">
$(document).ready(
function ()
{
$("#gridTable").jqGrid(
{
datatype: "json",
url: '@Url.Action("GetCustomerDetails")'">
  '@Url.Action("GetCustomerDetails")'</a />,
mtype: 'GET',
colNames: ["CustomerID", "CustomerName", 
   "Location", "PrimaryBusiness"],
colModel: [
{name:"CustomerID",width:40,index:"CustomerID",align:"center"},
{ name: "CustomerName", width: 40, index: "CustomerName", align: "center" },
{ name: "Location", width: 40, index: "Location", align: "center" },
{ name: "PrimaryBusiness", width: 40, index: "PrimaryBusiness", align: "center" },
],
height: 250,
autowidth: true,
sortorder: "asc",
rowNum: 10,
rowList: [5, 10, 15, 20],
sortname: "CustomerID",
sortorder: "desc",
viewrecords:true 
}
);
}
);function exportPDF() {
  document.location='@Url.Action("Index")?pdf=true'>;
}
</script>}

The exportPDF method just sets the document location to the Index action method with PDF Boolean as true just to mark for download PDF. An in-memory list collection is used for demo purpose. The GetCustomerDetails method is the server side action method that will provide the data as JSON list. We will see the method explanation below.

[HttpGet]
public JsonResult GetCustomerDetails()
{
    Var result = new
    {
        total = 1,
        page = 1,
        records = customerList.Count(),
        rows =(
        customerList.Select(e=>
        new {id=e.CustomerID,cell=new string[]{
          e.CustomerID.ToString(),e.CustomerName,e.Location,e.PrimaryBusiness}})
        ).ToArray()
    };
    return Json(result, JsonRequestBehavior.AllowGet);
}

jQGrid can understand the response data from server in certain format. The server method shown above is taking care of formatting the response so that JQGrid understand the data properly. The response data should contain total pages, current page, full record count, rows of data with ID and remaining columns as string array. The response is built using an anonymous object and will be sent as a MVC JsonResult. Since we are using HttpGet it’s better to mark the attribute as HttpGet and also the JSON requestbehavious as AllowGet. The in-memory list is initialized in the homecontroller constructor for reference.

public class HomeController : Controller
{
    private readonly IList<CustomerViewModel> customerList;
    public HomeController()
    {
        customerList =new List<CustomerViewModel>() {
        new CustomerViewModel{CustomerID=100,
          CustomerName="Sundar",Location="Chennai",PrimaryBusiness="Teacing"},
        new CustomerViewModel{CustomerID=101,
          CustomerName="Sudhagar",Location="Chennai",PrimaryBusiness="Software"},
        new CustomerViewModel{CustomerID=102,
          CustomerName="Thivagar",Location="China",PrimaryBusiness="SAP"},
    };
    }
    public ActionResult Index(bool? pdf)
    {
        if (!pdf.HasValue)
        {
            return View(customerList);
        }
        else
        {
            string filePath = Server.MapPath("Content") + "Sample.pdf";
            ExportPDF(customerList, new string[] { "CustomerID", 
              "CustomerName", "Location", "PrimaryBusiness" }, filePath);
            return File(filePath, "application/pdf","list.pdf"); 
        }
    }
} 

The index actionmethod has a Boolean argument named pdf. It’s used to indicate for PDF download. When the application starts this method is first hit for initial page request. For PDF operation a filename is generated and then sent to the ExportPDF method which will take care of generating the PDF from the datasource. The ExportPDF method is listed below. This is a generic method which can handle any data source. since column names are passed as argument there is no need to worry about the property names.

private static void ExportPDF<TSource>(IList<TSource> customerList,string[] columns, string filePath)
{
    Font headerFont = FontFactory.GetFont("Verdana", 10, Color.WHITE);
    Font rowfont = FontFactory.GetFont("Verdana", 10, Color.BLUE);
    Document document = new Document(PageSize.A4);
    PdfWriter writer = PdfWriter.GetInstance(document, 
               new FileStream(filePath, FileMode.OpenOrCreate));
    document.Open();
    PdfPTable table = new PdfPTable(columns.Length);
    foreach (var column in columns)
    {
        PdfPCell cell = new PdfPCell(new Phrase(column, headerFont));
        cell.BackgroundColor = Color.BLACK;
        table.AddCell(cell);
    }
    
    foreach (var item in customerList)
    {
        foreach (var column in columns)
        {
            string value = item.GetType().GetProperty(column).GetValue(item).ToString();
            PdfPCell cell5 = new PdfPCell(new Phrase(value, rowfont));
            table.AddCell(cell5);
        } 
    }
    document.Add(table);
    document.Close();
}

iTextSharp is one of the pioneer in PDF export. It’s an opensource library readily available as NUget library.

This command will pulldown latest available library. I am using the version 4.1.2.0. The latest version may have changed. There are three main things in this library.

  • Document: This is the document class which takes care of creating the document sheet with particular size. We have used A4 size. There is also an option to define the rectangle size. This document instance will be further used in next methods for reference.
  • PdfWriter: PdfWriter takes the filename and the document as the reference. This class enables the document class to generate the PDF content and save them in a file.
  • Font: Using the FONT class the developer can control the font features. Since I need a nice looking font I am giving the Verdana font.

Following this PdfPTable and PdfPCell are used for generating the normal table layout. We have created two set of fonts for header and footer.

Font headerFont = FontFactory.GetFont("Verdana", 10, Color.WHITE);
Font rowfont = FontFactory.GetFont("Verdana", 10, Color.BLUE);

We are getting the header columns as string array. Columns argument array is looped and header is generated. We are using the headerfont for this purpose.

PdfWriter writer = 
   PdfWriter.GetInstance(document, new FileStream(filePath, FileMode.OpenOrCreate));
document.Open();
PdfPTable table = new PdfPTable(columns.Length);
foreach (var column in columns)
{
    PdfPCell cell = new PdfPCell(new Phrase(column, headerFont));
    cell.BackgroundColor = Color.BLACK;
    table.AddCell(cell);
}

Then reflection is used to generate the row wise details and form the grid.

foreach (var item in customerList)
{
    foreach (var column in columns)
    {
        string value = item.GetType().GetProperty(column).GetValue(item).ToString();
        PdfPCell cell5 = new PdfPCell(new Phrase(value, rowfont));
        table.AddCell(cell5);
    } 
}
document.Add(table);
document.Close();

Once the process id done the PDF table is added to the document and document is closed to write all the changes to the filepath given. Then the control moves to the controller which will take care of sending the response as a JSON result with a filename. If the file name is not given then the PDF will open in the same page otherwise a popup will open up asking whether to save the file or open file.

return File(filePath, "application/pdf","list.pdf");

The final result screen is shown below.

PDF file opened below to show the output.

Conclusion

This is how the export PDF is done for JQGrid. The problem area that is addressed here is the client-side grid frameworks won’t support PDF’s export. In that time it’s better to have a fine grained control over the data and generated PDF. iTextSharp has helped us to achieve our goal.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here