Search code examples
node.jsamazon-web-servicespdfserverlesshtml-pdf

pdf generation using html-pdf npm package , deploy on AWS as a GET api


I am able to generate a pdf using html-pdf in nodejs locally on my mac. The minute I deploy the my GET api using serverless on AWS everything fails. The pdf does not get generated and I get 400 bad request and message as html-pdf: Received the exit code '127'\n/var/task/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory\n

I changed version of the html-pdf package , tried installing fontmanager but nothing helped.

//pdf generation class
{
.....
const pdfSettings = {
                "border": '1cm',
                "header": {
                    "height": "15mm"
                }
            };

            const PDFBuffer = new Promise((resolve, reject) => {
                pdf.create(pdfContent, pdfSettings).toBuffer(
                    (err, buffer) => {
                        err ? reject(err) : resolve(buffer);
                    });
            });

            const buffer = await PDFBuffer;
            return actions.downloadPDF(contactId, buffer);
}

//function which returns pdf in binary to api gateway
downloadPDF(pdfName, pdfBuffer) {

    let responseObj = {
      statusCode: 200,
      isBase64Encoded: true,
      headers: {
        'Content-type': 'application/pdf',
        'accept-ranges': 'bytes',
        'Content-Disposition': 'attachment; filename=' + pdfName + '.pdf'
      },
      body: pdfBuffer && JSON.stringify(pdfBuffer.toString('base64'))
    }
    return responseObj;
  }

I should be able to generate pdf using the GET api in AWS. Please let me know any valuable suggestion that could help me with this issue. Thanks in advance


Solution

  • I was able to reach a better solution by using puppeteer library. Reasons for choosing a different library

  • html-pdf is deprecated
  • puppeteer has much better options
  • puppeteer has async/await feature
  • Although to make this work in AWS with serverless & serverless-plugin-optimize , I did face many challenges. Note out the following points while implementing this kind of similar scenario

    For API gateway to send any binary file(pdf / jpeg / jpg) as response

  • Binary Media Types should be set to */* in API Gateway resource Settings options , if going through serverless under provider in serverless.yaml add apiGateway: binaryMediaTypes: - */*
  • if by any chance you are using serverless-plugin-optimize to reduce lambda size , use "external" option for this package chrome-aws-lambda , ref link https://www.npmjs.com/package/serverless-plugin-optimize