1

I need to create a pdf file from an HTML on the server-side (dotnet core 2) and send it as an attachment of an email. I have created a node service (createPdf.js) as follows and kept it in a local directory (NodeService) within the solution -

module.exports = function (callback, html, outputFilePath) {
    var pdf = require('html-pdf');
    var options = { format: 'A3', orientation: 'portrait' };

    pdf.create(html, options)
        .toFile(outputFilePath, function (err, res) {
            if (err)
                return callback(null, false);

            callback(null, true);
        });
} 

And I am triggering this function as follows -

    public static async Task<bool> GeneratePdf(INodeServices nodeService, string html, string outputFilePath)
    {
        string pdfGenerationNodeService = Path.Combine(Directory.GetCurrentDirectory(), "NodeService", "createPdf.js");
        try
        {
            return await nodeService.InvokeAsync<bool>(pdfGenerationNodeService, html, outputFilePath);
        }
        catch (Exception ex)
        {
            throw;
        }
    }

For calling this method from the controller -

public async Task<IActionResult> SendQuotationToHospitalAsync([FromServices]INodeServices nodeService, int id)
{
    ...
    bool isAdminPdfGenerationSuccess = await PdfHelperService.GeneratePdf(nodeService, htmlContent, filePath);
    ...
}

I have also registered the node service in StartUp.cs -

services.AddNodeServices();

When I am triggering the function in debug mode, it's working properly and the pdf file is getting generated. However, once I deploy the application on the server, the node function is not getting triggered. Any help regarding the issue will be very helpful. Thanks.

P.S. As it is a home project, I can not afford any premium HTML-to-PDF converter

Raj
  • 417
  • 1
  • 3
  • 17
  • your problem probably isn't this 2 methods but the code that calls your node method. Edit your post with the place where you call your function – Pedro Brito Sep 13 '19 at 14:06
  • I have updated the query – Raj Sep 13 '19 at 14:14
  • the SendQuotationToHospitalAsync is triggered? – Pedro Brito Sep 13 '19 at 14:28
  • yes it gets triggered. I don't think the issue is in calling the method on server-side. – Raj Sep 13 '19 at 14:32
  • and the params like nodeService his values are similar to your dev enviroment?! – Pedro Brito Sep 13 '19 at 14:35
  • I'm unable to determine that as it has already been deployed and I can not debug it to determine the value of the nodeService param. Then again I need to install any logger (serilog etc) to log it. – Raj Sep 13 '19 at 14:43
  • Yeap, for you to solve your problem yes! You need a logger to understand what is happening in the server, otherwise his impossible to help you and you will have only suspicions about what may cause the problem – Pedro Brito Sep 13 '19 at 14:49
  • I kept log as discussed and found out that - *await nodeService.InvokeAsync(pdfGenerationNodeService, html, outputFilePath);* upto this line the function is triggering properly. However no response is coming back from the node function – Raj Sep 14 '19 at 09:11

2 Answers2

0

You may have a look at this as a working example of what you are trying to achieve with NodeServices. It runs on Docker, so you can get a hint from the Dockerfile of what you need to have installed on the server to get it working there as well.

Another approach is to use PuppeteerSharp, as follows:

await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
  Headless = true,
  Args = new string[] { "--no-sandbox" }
});

var page = await browser.NewPageAsync();
await page.SetContentAsync(htmlContent);
await page.PdfAsync(filePath); // page.PdfStreamAsync() to generate only in-memory
rph
  • 2,104
  • 2
  • 13
  • 24
  • I tried the second approach by installing PuppeteerSharp but the BrowserFetcher can not be found – Raj Sep 14 '19 at 04:32
  • You need to have `` in your `csproj` and add the using directive like `using PuppeteerSharp;`. – rph Sep 14 '19 at 13:14
0

I'm using angular 7 for client-side and had npm packages installed accordingly, which included the html-pdf package as well. However, I had not installed it in the directory where I have kept the node script. I was hoping that the package would be taken from the vendor.js after deployment, which was clearly not the case. I had to create another package.json file in the directory and installed it separately after deployment and everything went smooth thereafter.

That's what I was missing when deploying the application - a little manual npm install for installing the package I'm using, in the local directory of the node script.

Thanks a lot for discussing the issue, it helped me a lot in understanding what other mistakes I might have done.

Raj
  • 417
  • 1
  • 3
  • 17