Convert HTML to PDF in MVC with iTextSharp in MVC Razor

I am trying to convert HTML to PDF with iTextSharp in MVC Razor, but everything I have tried has not worked. Does anyone know how to accomplish this?

2,870 25 25 gold badges 39 39 silver badges 45 45 bronze badges asked May 13, 2013 at 7:51 233 1 1 gold badge 3 3 silver badges 9 9 bronze badges

9 Answers 9

Here is how you implement this solution using the Razor engine NOT with the weird

This way you have full control over the pdf presentation using standard html output.

The project with an example solution and source code is available here with nuget installation instructions:

Install-Package MvcRazorToPdf 

This also uses the new itextsharp licence, so does not suffer from any of the negatives mentioned in the other answers.

answered Nov 25, 2013 at 17:05 hutchonoid hutchonoid 33.2k 15 15 gold badges 100 100 silver badges 105 105 bronze badges Man, you rock, thanks. Can i change the page orientation somehow? Commented May 27, 2014 at 22:57

@EdgarSalazar No problem. As it uses the iTextXmlWorker underneath, I think you should be able to resolve this by styling a div to your landscape proportions.

Commented May 28, 2014 at 9:23 @sports yes, table example here: github.com/andyhutch77/MvcRazorToPdf/blob/master/… Commented Oct 20, 2014 at 21:34 this dll does not support culture specific characters Commented Oct 22, 2015 at 15:43

You should check out RazorPDF which is using iText to generate the PDF, but in a friendlier way.

answered May 20, 2013 at 9:14 Rosdi Kasim Rosdi Kasim 25.6k 25 25 gold badges 133 133 silver badges 160 160 bronze badges

Hi Rosdi Kasim. Appearantly the latest iTextSharp version (5.4.4) is not working properly with RazorPDF and has rendered it useless.

Commented Oct 2, 2013 at 21:54

@real_yggdrasil Be careful.. latest iTextSharp (starting from 5.x) has different license. Also 'rendered useless' is not helpful.. try submit your question with some example or detailed description..

Commented Oct 3, 2013 at 2:46

I disagree. It has been rendered useless in that it does nothing and has not been updated since 2012.

Commented May 13, 2014 at 21:56
public virtual void printpdf(string html) < String htmlText = html.ToString(); Document document = new Document(); string filePath = HostingEnvironment.MapPath("~/Content/Pdf/"); PdfWriter.GetInstance(document, new FileStream(filePath + "\\pdf-"+Filename+".pdf", FileMode.Create)); document.Open(); iTextSharp.text.html.simpleparser.HTMLWorker hw = new iTextSharp.text.html.simpleparser.HTMLWorker(document); hw.Parse(new StringReader(htmlText)); document.Close(); >

just pass html string in to parameter that string you will get by renderpartialview text = viewname.

630 8 8 silver badges 25 25 bronze badges answered Jan 29, 2014 at 6:58 Vinit Patel Vinit Patel 2,444 6 6 gold badges 30 30 silver badges 54 54 bronze badges

There's a detailed and step-by-step tutorial on CodeProject you might follow. It illustrates how you could serve an ASP.NET MVC View as PDF file using iTextSharp for the conversion. Bear in mind though that iTextSharp was not meant for converting HTML to PDF so it might not cope very well with complex HTML pages and CSS styles.

answered May 13, 2013 at 7:56 Darin Dimitrov Darin Dimitrov 1.0m 273 273 gold badges 3.3k 3.3k silver badges 2.9k 2.9k bronze badges

I want to know that if iTextSharp was not meant for converting HTML to PDF, which one with free source?

Commented Mar 21, 2014 at 11:36 IF TODAY DATE >14.07.2015 DO NOT LOOK TO THIS ANSWER! Commented Jul 14, 2015 at 10:45 @MDDDC why not? Where should I look then? Commented Nov 24, 2015 at 17:08 This step by step tutorial is not "Razor". It is aspx, web forms. It is not up to date. Commented Feb 5, 2017 at 23:47

A good way to convert from MVC HTML View to PDF (even if it's not directly on the subject regarding iTextSharp) is using Rotativa :

Install-Package Rotativa 

This is based on wkhtmltopdf but it has better css support than iTextSharp has and is very simple to integrate with MVC as you can simply return the view as pdf:

public ActionResult GetPdf() < //. return new ViewAsPdf(model);// and you are done! >
answered Aug 10, 2016 at 15:32 meJustAndrew meJustAndrew 6,481 8 8 gold badges 55 55 silver badges 85 85 bronze badges

I worked with Rotativa , it works based on popup and need to unblock popup blocker. Moreover after use ViewAsPdf or ActionAsPdf all Sessions will be cleared.

Commented Jul 31, 2018 at 7:27

Here is a complete example for MVC Razor in C# using the evo html to pdf for .net to convert the current MVC view to PDF and send the resulted PDF to browser for download:

[HttpPost] public ActionResult ConvertCurrentPageToPdf(FormCollection collection) < object model = null; ViewDataDictionary viewData = new ViewDataDictionary(model); // The string writer where to render the HTML code of the view StringWriter stringWriter = new StringWriter(); // Render the Index view in a HTML string ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, "Index", null); ViewContext viewContext = new ViewContext( ControllerContext, viewResult.View, viewData, new TempDataDictionary(), stringWriter ); viewResult.View.Render(viewContext, stringWriter); // Get the view HTML string string htmlToConvert = stringWriter.ToString(); // Get the base URL String currentPageUrl = this.ControllerContext.HttpContext.Request.Url.AbsoluteUri; String baseUrl = currentPageUrl.Substring(0, currentPageUrl.Length - "Convert_Current_Page/ConvertCurrentPageToPdf".Length); // Create a HTML to PDF converter object with default settings HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter(); // Convert the HTML string to a PDF document in a memory buffer byte[] outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlToConvert, baseUrl); // Send the PDF file to browser FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf"); fileResult.FileDownloadName = "Convert_Current_Page.pdf"; return fileResult; >
answered Sep 28, 2016 at 9:08 523 3 3 silver badges 9 9 bronze badges

here you can find a different approach in case you want to write plain xml, i find it much simpler and lighter.

answered Jul 29, 2013 at 9:04 936 8 8 silver badges 16 16 bronze badges

This is how to do it using MVC :

[Route("ABCDD")] [HttpGet] public void ABCDD() < WebClient wc = new WebClient(); // string url = HttpContext.Current.Request.Url.AbsoluteUri; string url = "http://localhost:3042/Reports/COAListing"; string fileContent = wc.DownloadString(url); ListtableContents = GetContents(fileContent, table_pattern); string HTMLString = String.Join(" ", tableContents.ToArray()); Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f); PdfWriter.GetInstance(pdfDoc, HttpContext.Current.Response.OutputStream); pdfDoc.Open(); pdfDoc.Add(new Paragraph("Welcome to dotnetfox")); List htmlarraylist = HTMLWorker.ParseToList(new StringReader(HTMLString), null); for (int k = 0; k < htmlarraylist.Count; k++) < pdfDoc.Add((IElement) htmlarraylist[k]); >pdfDoc.Close(); HttpContext.Current.Response.ContentType = "pdf/application"; HttpContext.Current.Response.AddHeader("content-disposition", "attachment;" + "filename=sample.pdf"); HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.Write(pdfDoc); HttpContext.Current.Response.End(); > 
8,551 7 7 gold badges 52 52 silver badges 85 85 bronze badges answered May 18, 2016 at 17:13 Vivek Shukla Vivek Shukla 1,565 1 1 gold badge 13 13 silver badges 13 13 bronze badges Your answer uses HTMLWorker , which is deprecated. You should use XMLWorker . Commented May 18, 2016 at 17:21 it giving error XMLWorker does not exist in current Context Commented May 18, 2016 at 17:28 Which version of iTextSharp are you using? Can you reproduce it in iTextSharp 5.5.9? Commented May 18, 2016 at 17:36 Yes its iTextSharp 5.5.9 Commented Jul 1, 2018 at 18:45 Can you reproduce it in iText 7.1.2 + pdfHTML? Commented Jul 1, 2018 at 18:55

In case you are using ASP.NET Core and iTextSharp is not that important to you here is my solution using PhantomJS: http://nikolay.it/Blog/2018/03/Generate-PDF-file-from-Razor-view-using-ASP-NET-Core-and-PhantomJS/37

Get HTML string from a Razor view

This step is pretty straight-forward. There is a service called IRazorViewEngine in ASP.NET Core which can be injected and then used to get the view. After providing the view with default ViewDataDictionary and ActionContext we can request the view to be rendered into StringWriter which can be easily converted to string. Here is ready-to-use code for getting a string from given Razor view file:

public interface IViewRenderService < TaskRenderToStringAsync(string viewName, object model); > public class ViewRenderService : IViewRenderService < private readonly IRazorViewEngine razorViewEngine; private readonly ITempDataProvider tempDataProvider; private readonly IServiceProvider serviceProvider; public ViewRenderService( IRazorViewEngine razorViewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider) < this.razorViewEngine = razorViewEngine; this.tempDataProvider = tempDataProvider; this.serviceProvider = serviceProvider; >public async Task RenderToStringAsync(string viewName, object model) < var httpContext = new DefaultHttpContext < RequestServices = this.serviceProvider >; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); using (var sw = new StringWriter()) < var viewResult = this.razorViewEngine.GetView(null, viewName, false); if (viewResult.View == null) < throw new ArgumentNullException($"does not match any available view"); > var viewDictionary = new ViewDataDictionary( new EmptyModelMetadataProvider(), new ModelStateDictionary()) < Model = model >; var viewContext = new ViewContext( actionContext, viewResult.View, viewDictionary, new TempDataDictionary(actionContext.HttpContext, this.tempDataProvider), sw, new HtmlHelperOptions()); await viewResult.View.RenderAsync(viewContext); return sw.ToString(); > > > 

One important think here: if you use view compilation (pre-compiling views to YourProject.Web.PrecompiledViews.dll ) then it is important to get the view using the GetView method instead of FindView . More information here.

Generate the PDF file from HTML using PhantomJS

For this task we are going to use a headless browser which will render the HTML (with all CSS and JS included in it). There are many such tools but I will use PhantomJS (headless WebKit scriptable with a JavaScript API). PhantomJS can save the rendered page to small-sized PDF pretty fast. For the PDF export to work we are going to need a .js file which will use the PhantomJS API to tell the tool that we want to export the file:

"use strict"; var page = require('webpage').create(), system = require('system'), address, output; console.log('Usage: rasterize.js [URL] [filename] [paperformat]'); address = system.args[1]; output = system.args[2]; page.viewportSize = < width: 600, height: 600 >; page.paperSize = < format: system.args[3], orientation: 'portrait', margin: '0.5cm' >; page.open(address, function (status) < if (status !== 'success') < console.log('Unable to load the address!'); phantom.exit(1); >else < window.setTimeout(function () < page.render(output); phantom.exit(); >, 200); > >); 

The next thing is to run the phantomjs.exe process and pass the rasterize.js file along with paths for the HTML file and the output file name for the PDF result. This is done in HtmlToPdfConverter.cs :

public interface IHtmlToPdfConverter < byte[] Convert(string htmlCode); >public class HtmlToPdfConverter : IHtmlToPdfConverter < public byte[] Convert(string htmlCode) < var inputFileName = "input.html"; var outputFileName = "output.pdf"; File.WriteAllText(inputFileName, htmlCode); var startInfo = new ProcessStartInfo("phantomjs.exe") < WorkingDirectory = Environment.CurrentDirectory, Arguments = string.Format( "rasterize.js \"\" \"A4\"", inputFileName, outputFileName), UseShellExecute = true, >; var process = new Process < StartInfo = startInfo >; process.Start(); process.WaitForExit(); var bytes = File.ReadAllBytes(outputFileName); File.Delete(inputFileName); File.Delete(outputFileName); return bytes; > > 

If you are going to deploy your application in Azure it is important to have UseShellExecute set to true .

Use the code together

Since we now have implemented both IViewRenderService and IHtmlToPdfConverter we can start using them by first register them in the Startup.cs file where your ConfigureServices method should be located ( services.AddScoped() and services.AddScoped() ). Now lets see the code wrapped up together:

private readonly IViewRenderService viewRenderService; private readonly IHtmlToPdfConverter htmlToPdfConverter; public DashboardController( IViewRenderService viewRenderService, IHtmlToPdfConverter htmlToPdfConverter) < this.viewRenderService = viewRenderService; this.htmlToPdfConverter = htmlToPdfConverter; >[HttpGet] public async Task GetPdf(SomeInputModel input) < var model = this.GetViewModel(input); var htmlData = await this.viewRenderService.RenderToStringAsync("~/Views/Dashboard/GetPdf.cshtml", model); var fileContents = this.htmlToPdfConverter.Convert(htmlData); return this.File(fileContents, "application/pdf"); >