Looking to incorporate locally loaded fonts when generating a PDF using the Puppeteer node module.
I successfully implemented web fonts, but this does not meet the specified requirements.
Environment Details:
- Node: v10.18.1,
- Puppeteer: "puppeteer": "^2.0.0",
- Chromium: Chromium 79.0.3945.88 Fedora Project,
- OS: CentOS Linux release 8.0.1905 (Core)
Attempted code includes loading fonts with @font-face, adjusting networkidle values, setting timeouts, adding event listeners for font updates. Even after setting up callbacks to retrieve font properties returning "Open Sans," the resulting PDF file does not display the Open Sans font.
const puppeteer = require('puppeteer');
const chromiumExecutablePath = '/bin/chromium-browser';
let document = `
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
@font-face {
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
src: local("Open Sans") url("/opt/www/webapp/resources/packed/OpenSans-Regular.eot");
src: local("Open Sans") url("/opt/www/webapp/resources/packed/OpenSans-Regular.woof") format("woff"),
local("Open Sans") url("/opt/www/webapp/resources/packed/OpenSans-Regular.ttf") format("truetype");
}
html, body {
font-family: 'Open Sans', sans-serif;
}
</style>
<sript>
</script>
<link rel="stylesheet" type="text/css" href="font.css">
</head>
<body>
<div class="content">
<h1 id="hello-world">Hello world long report</h1>
</div>
</body>
</html>
`
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-web-security', '--font-render-hinting=none'],
headless: true,
executablePath: chromiumExecutablePath
});
const page = await browser.newPage()
const session = await page.target().createCDPSession();
await session.send('DOM.enable');
await session.send('CSS.enable');
await new Promise(resolve => setTimeout(resolve, 500));
session.on('CSS.fontsUpdated', event => {
console.log(event);
// event will be received when browser updates fonts on the page due to webfont loading.
});
await page.goto("data:text/html;charset=UTF-8,"+document, { waitUntil: 'networkidle0' }).catch(e => console.error(e));
await page.waitFor(2000);
await page.evaluateHandle('document.fonts.ready');
const selector = 'h1';
const getFontProperty = async (page) => {
const font = await page.evaluate((selector) => {
const title = document.querySelector(selector);
return getComputedStyle(title).font;
}, selector);
return font;
}
console.log(await getFontProperty(page)); // output: 700 32px "Open Sans", sans-serif
await page.emulateMedia("print");
await page.pdf({
displayHeaderFooter: false,
path: outputPath,
width: 400+'px',
height: 400+'px',
printBackground: true,
margin: {
top: '20px',
bottom: '40px'
}
}); // output is valid PDF file but without Open Sans font
Seeking suggestions on how to resolve this issue. There was mention of rendering images from local files in a related question, but the solution provided did not address how to handle fonts.