We are going to separate the task into 3 sub-tasks:

  1. Get the HTML contents from the razor view using IRazorViewEngine
  2. Create HTML page and generate PDF file from it using PhantomJS
  3. Return the PDF file contents to the user

These steps and the provided code are tested in ASP.NET Core 2.0 application deployed in Microsoft Azure.

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:

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:

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:

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<IViewRenderService, ViewRenderService>() and services.AddScoped<IHtmlToPdfConverter, HtmlToPdfConverter>()). Now lets see the code wrapped up together:

In case you have any questions or comments please use the comments section here or write me an email to blog [at] nikolay.it.