NodeServices - Convert HTML To PDF In .Net Core Using Node.js

Introduction

The article explains how to convert HTML to PDF with Microsoft .Net Core 2.1 using Microsoft.AspNetCore.NodeServices to execute Node.js modules for conversion. The demo is created using an .NetCore console application.

Microsoft.AspNetCore.NodeServices

NodeServices provides a fast and robust way for .NET code to run JavaScript on the server inside a Node.js environment. These services can be used to consume arbitrary functionality from NPM packages at runtime in a ASP.NET Core app.

html-pdf (https://www.npmjs.com/package/html-pdf)

HTML to PDF converter uses phantomjs. This is an NPM package which can be used in NodeJs enviroment to convert HTML to pdf files. In this demo we do not explore all the options available with this package. The aim is to understand a very basic usage of package.

Application Walkthrough

NodeJs

Install Node.js enviroment on your machine following the steps from https://nodejs.org/en/

After installation you can verfiy by executing the following command in the command line:
  1. node -v  
.Net Core 
package.json
  1. {  
  2.   "version""1.0.0",  
  3.   "name""exp.pdfgen",  
  4.   "private"true,  
  5.   "dependencies": {  
  6.     "html-pdf""^2.2.0"  
  7.   }  

The file indicates the dependencies required to be downloaded. To install them copy the contents into the package.json file and execute the below command from command line.
  1. npm install  
After execution of the command, you will see node_modules folder created which will contain the node dependencies.

.Net Core 

generatePDF.js

This is a small module, which will be invoked by our application. This refers to the node_modules folder for dependencies.

This will read the html file, and pass and invoke the html-pdf module with the appropriate options and parameters.
  1. module.exports = function (callback, inputFilePath, outputFilePath) {  
  2.   
  3.     //callback : This is node style callback, since the NodeServices invokes the javascript Asynchronously  
  4.     //inputFilePath : The html file path  
  5.     //outputFilePath : The file path where the pdf is to be generated  
  6.   
  7.   
  8.     var fs = require('fs'); // get the FileSystem module, provided by the node envrionment  
  9.     var pdf = require('html-pdf'); // get the html-pdf module which we have added in the dependency and downloaded.  
  10.     var html = fs.readFileSync(inputFilePath, 'utf8'); //read the contents of the html file, from the path  
  11.     var options = { format: 'Letter' }; //options provided to html-pdf module. More can be explored in the module documentation  
  12.   
  13.     //create the pdf file  
  14.     pdf.create(html, options).toFile(outputFilePath, function (err, res) {  
  15.         if (err) return callback(null, "Failed to generate PDF");  
  16.         callback(null, "Generated PDF Successfully");  
  17.     });  
  18.   

Application Code
 
The paths mentioned can be changed as per your directory structure. To keep the article simple, publishing the node_modules and the project to relative paths is not done.
  1. using System;  
  2. using System.Threading.Tasks;  
  3. using Microsoft.AspNetCore.NodeServices;  
  4. using Microsoft.Extensions.DependencyInjection;  
  5.   
  6. namespace exp.pdfgen  
  7. {  
  8.     class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             //Instantiate DI container for the application  
  13.             var serviceCollection = new ServiceCollection();  
  14.   
  15.             //Register NodeServices  
  16.             serviceCollection.AddNodeServices();  
  17.   
  18.             //Request the DI container to supply the shared INodeServices instance  
  19.             var serviceProvider = serviceCollection.BuildServiceProvider();  
  20.             var nodeService = serviceProvider.GetRequiredService<INodeServices>();  
  21.   
  22.   
  23.             //Input file path of html file   
  24.             var inputFilePath = "D:\\Repository\\NetCore\\experiments\\exp\\exp.pdfgen\\sample.html";  
  25.               
  26.             //Output file path of pdf file  
  27.             var outputFilePath = "D:\\Repository\\NetCore\\experiments\\exp\\exp.pdfgen\\sampleOutput.pdf";  
  28.   
  29.             var taskResult = GeneratePdf(nodeService, inputFilePath, outputFilePath);  
  30.   
  31.             Task.WaitAll(taskResult);  
  32.   
  33.             if (taskResult.IsCompletedSuccessfully)  
  34.             {  
  35.                 Console.WriteLine(taskResult.Result);  
  36.             }  
  37.   
  38.             Console.ReadKey();  
  39.         }  
  40.   
  41.         private static async Task<string> GeneratePdf(INodeServices nodeService, string inputFilePath, string outputFilePath)  
  42.         {  
  43.   
  44.             //Invoke the javascript module with parameters to execute in Node environment.  
  45.             return await nodeService.InvokeAsync<string>(@"D:\\Repository\\NetCore\\experiments\\exp\\exp.pdfgen\\generatePDF.js", inputFilePath, outputFilePath);  
  46.   
  47.         }  
  48.   
  49.   
  50.     }  

Sample.html
  1. <html>  
  2.   
  3. <body>  
  4.     <p>This is Sample Text</p>  
  5.     <p style="font:20px;color:magenta;">This is Colored Text</p>  
  6.   
  7. </body>  
  8.   
  9. </html> 
Output
 
.Net Core 
 
.Net Core 
 
I hope the article helps you understand how to use Node.js based modules like html-pdf to generate PDF from HTML from .NetCore applications.