Blog Home  Home Feed your aggregator (RSS 2.0)  
Mayur's Blog - Extended method to create PDF of views in Asp.Net MVC
 
# Thursday, November 15, 2012

I am putting together a code snnipet which you can use to create an extended method for any controller in Asp.Net MVC. This method can look into the views, add in model to the views and send a btye stream with application content of PDF type. As all modern browser can understand this type of byte stream, these browsers are able to read the byte stream and show the PDF in browser window.

In your base controller add in the following method. You inherit other controllers from this base controller

public PDFContentResult RenderPDFUsingHTML(string viewName, object model)

{

StringWriter sw = new StringWriter();

RazorViewEngine rv = new RazorViewEngine();

ViewEngineResult vr = rv.FindPartialView(this.ControllerContext, viewName, false);

ViewData.Model = model;

ViewContext vc = new ViewContext(this.ControllerContext, vr.View, ViewData, TempData, sw);

vr.View.Render(vc, sw);

string s = sw.GetStringBuilder().ToString();

/*I am using iTextSharpt to convert raw html into PDF. The following GetHTMLToPDFBytes(s) is implementation of itextSharp. You can also use anyother utility to convet html string into PDF.*/

byte[] pdfByes = GetHTMLToPDFBytes(s);

/*PDFContentResult is a custom ActionResult type. See the following code snippet for the details*/

return new PDFContentResult(pdfByes, "application/pdf");

}

/*---------------------------------------------------------------*/

public class PDFContentResult : ActionResult

{

private readonly string contentType;

private readonly byte[] contentBytes;

public PDFContentResult(byte[] contentBytes, string contentType)

{

this.contentBytes = contentBytes;

this.contentType = contentType;

}

public override void ExecuteResult(ControllerContext context)

{

var response = context.HttpContext.Response;

response.Clear();

response.Cache.SetCacheability(HttpCacheability.Public);

response.ContentType = this.contentType;

using (var stream = new MemoryStream(this.contentBytes))

{

stream.WriteTo(response.OutputStream);

stream.Flush();

}

}

}

Code snippet is self explantory. RenderPDFUsingHTML takes name of view and model as argumets of the method signature. It tries to find out required RazorView based on the given view name, once it is found it inserts the model data to it. Once this is done, it converts the view (raw html) to string, sends this string to iTextSharp to build byte array of PDF.

To make things sipmpler it returns PDFContentResult which is cutom ActionResult type. This is responsible to create a required http response with byte array added to it.

You do the following in your controller to get PDF. Make sure that you first inherit your controller with base controller where you put in the above code snippet. 

public ActionResult GetMyPDF(MyModel model)

{

..... do coding ...... for controller ........

return RenderPDFUsingHTML("MyViewName",model)

}

It is good practice to create another view, which is a simplified version of the original view. Generally the views, which we use for web sites are little complicated as it holds html control such as buttons, dropdown menus, and javaScripts etc. We really do not show them in PDF reports. So the simplified veiw takes the same model but removes not needed javaScripts and other html controls.

Thursday, November 15, 2012 6:07:46 PM UTC  #       | 
Copyright © 2022 Mayur Bharodia. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: