简体   繁体   中英

Handlebars + puppeteer using base64 to display a local png image

I have a project where I'm building up an html with handlebars and converting it over to pdf using puppeteer. I'm having an issue where my base64 encoded image does not display the images once the pdf has been rendered. For extra context, we are storing the pdf in our database once it is generated and our images are in a local assets directory. I'm able to get the images to load in a codesandbox but that doesn't include puppeteer so I'm thinking that is the issue.

 // takes the handlebars template and compiles it const compile = async (templateName, data) => { const filePath = path.join(__dirname, "templates", `${templateName}.hbs`); if (!filePath) { throw new Error(`Could not find ${templateName}.hbs in generatePDF`); } const html = await fs.readFile(filePath, "utf-8"); return hbs.compile(html)(data); }; // use puppeteer to take in compiled hbs doc and create a pdf const generatePDF = async (fileName, data) => { const preparedData = prepareDataForPDF(data); const browser = await puppeteer.launch({ args: ["--no-sandbox"], headless: true, }); const page = await browser.newPage(); const content = await compile(fileName, preparedData); await page.goto(`data: text/html;charset=UTF-8, ${content}`, { waitUntil: "networkidle0", }); await page.setContent(content); await page.emulateMedia("screen"); await page.waitFor(100); const pdf = await page.pdf({ format: "A4", printBackground: true, }); browser.close(); return pdf; }; // the helper to convert my image to base64 hbs.registerHelper("getIntro", async (context, idx) => { let bitmap = await fs.readFile( path.join(__dirname, "assets", `${context}_intro_${idx}.png`), ); const buff = await Buffer(bitmap).toString("base64"); let imgSrcString = `data:image/png;base64,${buff}`; console.log(imgSrcString); return imgSrcString; });
 <!-- for context "this" is just an index number as this gets iterated over for multiple images --> <img src="{{getIntro "Leadership" this}}">

I'm not marking this as an answer, but simply as the work around that I used to resolve this. I have a react FE and my app is in a mono-repo that was jointly deployed to Heroku. So I decided to place the images in my client/public directory, then in my handlebars code, I referenced the url for it and the name of the file. This let's me host my own images in an easier to manage fashion without having to force the customer to deal with yet another tool like s3 buckets. This solution isn't ideal but it works for now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM