-
-
Save uatisdeproblem/c4204778ed983f99bbbc18758ac1aed0 to your computer and use it in GitHub Desktop.
AWS Lambda: html2pdf (IDEA)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// | |
// AWS Lambda: idea_html2pdf (Node.js >= 18) | |
// File: index.js | |
// -- ITER IDEA, 2023. | |
// This function's source code is defined in the following GitHub Gist: | |
// https://gist.github.com/uatisdeproblem/c4204778ed983f99bbbc18758ac1aed0 | |
// | |
// required through AWS Lambda layer | |
const puppeteer = require('puppeteer-core'); | |
const chromium = require('@sparticuz/chromium'); | |
chromium.setHeadlessMode = true; | |
chromium.setGraphicsMode = false; | |
exports.handler = async (event, _, callback) => { | |
const params = { | |
body: event.body ?? '', | |
header: event.header ?? '', | |
footer: event.footer ?? '', | |
pdfOptions: event.pdfOptions ?? {} | |
}; | |
try { | |
const data = await html2pdf(params); | |
callback(null, data); | |
} catch (err) { | |
callback(err); | |
} | |
}; | |
async function html2pdf(params) { | |
let browser; | |
try { | |
params.pdfOptions.displayHeaderFooter = Boolean(params.header || params.footer); | |
params.pdfOptions.headerTemplate = params.header; | |
params.pdfOptions.footerTemplate = params.footer; | |
params.pdfOptions.format = params.pdfOptions.format ?? 'A4'; | |
params.pdfOptions.printBackground = | |
params.pdfOptions.printBackground === undefined ? true : params.pdfOptions.printBackground; | |
params.pdfOptions.margins = params.pdfOptions.margins ?? { top: '2cm', right: '1cm', bottom: '2cm', left: '1cm' }; | |
const browser = await puppeteer.launch({ | |
args: chromium.args.concat('--font-render-hinting=none'), | |
defaultViewport: chromium.defaultViewport, | |
executablePath: await chromium.executablePath(), | |
headless: chromium.headless, | |
}); | |
const page = await browser.newPage(); | |
await page.setContent(params.body, { waitUntil: 'networkidle2' }); | |
await page.emulateMediaType('screen'); | |
const pdfData = await page.pdf(params.pdfOptions); | |
if (browser) await browser.close(); | |
return pdfData.toString('base64'); | |
} catch(error) { | |
if (browser) await browser.close(); | |
throw error; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// | |
// AWS Lambda: idea_html2pdf_viaS3Bucket (Node.js >= 18) | |
// Alternate version of idea_html2pdf that uses an intermediate S3 bucket to avoid Lambda's payload limits. | |
// File: index.js | |
// -- ITER IDEA, 2023. | |
// This function's source code is defined in the following GitHub Gist: | |
// https://gist.github.com/uatisdeproblem/c4204778ed983f99bbbc18758ac1aed0 | |
// | |
// required through AWS Lambda layer | |
const puppeteer = require('puppeteer-core'); | |
const chromium = require('@sparticuz/chromium'); | |
chromium.setHeadlessMode = true; | |
chromium.setGraphicsMode = false; | |
const { S3Client } = require('@aws-sdk/client-s3'); | |
const { Upload } = require('@aws-sdk/lib-storage'); | |
const s3 = new S3Client(); | |
exports.handler = async (event, _, callback) => { | |
const params = { | |
body: event.body ?? '', | |
header: event.header ?? '', | |
footer: event.footer ?? '', | |
pdfOptions: event.pdfOptions ?? {}, | |
s3Bucket: event.s3Bucket, | |
s3Prefix: event.s3Prefix | |
}; | |
try { | |
const data = await html2pdfViaS3Bucket(params); | |
callback(null, data); | |
} catch (err) { | |
callback(err); | |
} | |
}; | |
async function html2pdfViaS3Bucket(params) { | |
let browser; | |
try { | |
params.pdfOptions.displayHeaderFooter = Boolean(params.header || params.footer); | |
params.pdfOptions.headerTemplate = params.header; | |
params.pdfOptions.footerTemplate = params.footer; | |
params.pdfOptions.format = params.pdfOptions.format ?? 'A4'; | |
params.pdfOptions.printBackground = | |
params.pdfOptions.printBackground === undefined ? true : params.pdfOptions.printBackground; | |
params.pdfOptions.margins = params.pdfOptions.margins ?? { top: '2cm', right: '1cm', bottom: '2cm', left: '1cm' }; | |
const browser = await puppeteer.launch({ | |
args: chromium.args.concat('--font-render-hinting=none'), | |
defaultViewport: chromium.defaultViewport, | |
executablePath: await chromium.executablePath(), | |
headless: chromium.headless, | |
}); | |
const page = await browser.newPage(); | |
await page.setContent(params.body, { waitUntil: 'networkidle2' }); | |
await page.emulateMediaType('screen'); | |
const pdfData = await page.pdf(params.pdfOptions); | |
const s3Bucket = params.s3Bucket ?? 'idea-downloads'; | |
const s3Prefix = params.s3Prefix ?? 'html2pdf'; | |
const s3ParamsToRetrievePDF = await uploadPDFDataInS3Bucket(pdfData, s3Bucket, s3Prefix); | |
if (browser) await browser.close(); | |
return s3ParamsToRetrievePDF; | |
} catch(error) { | |
if (browser) await browser.close(); | |
throw error; | |
} | |
} | |
async function uploadPDFDataInS3Bucket(buffer, s3Bucket, s3Prefix) { | |
const Bucket = s3Bucket; | |
const Key = s3Prefix.concat('/', new Date().getTime().toString().concat(Math.random().toString(36).slice(2)), '.pdf'); | |
const upload = new Upload({ client: s3, params: { Bucket, Key, Body: buffer } }); | |
await upload.done(); | |
return { Bucket, Key }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment