Puppeteer - 自定义字体未在 pdf 中加载,但确实出现在屏幕截图中

Dha*_*rmi 7 javascript node.js next.js puppeteer

我正在尝试使用 puppeteer lib 动态创建 PDF 文件,但生成的 pdf 不使用自定义字体(.woff),而是使用默认系统字体,即 Times new roman。

我使用 Next.js 创建网站,并进行了相当棘手的设置来加载自定义字体以及侧面样式组件。最好是我不必搞乱 Nextjs 设置,然后无论如何让它工作。

我什至添加了一个延迟(超时),只是为了确保在生成 pdf 之前正确下载字体,但徒劳无功。然而,截屏显示了正确的自定义字体。

  1. 如何让自定义字体显示在pdf中?

  2. 生成 pdf 会导致背景颜色出现在某些 div 后面,我该如何调试,或者可能存在什么问题,因为网页/屏幕截图上的图像后面没有出现这样的背景颜色?

下面是我用来创建 pdf 的代码。

傀儡师代码:

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch({headless: true});
  const page = await browser.newPage();
  await page.goto('https://threads-web.vercel.app/threads/1385978750743973894', {
    waitUntil: 'networkidle2',
  });
  // const document = await page.evaluate(() => document);
  // console.log(document.fonts) ----- This also returns undefined
  try {
    await page.screenshot({ path: 'beforeTimeout.png' });
    await page.waitForTimeout(15000);
    await page.screenshot({ path: 'afterTimeOut.png' });
    await page.evaluateHandle('document.fonts.ready');
    await page.pdf({ path: 'hn.pdf', format: 'a4' });
  }
  catch (err) {
      console.log(err)
  }

  await browser.close();
})();
Run Code Online (Sandbox Code Playgroud)

Next.js:_app.js

const GlobalStyle = createGlobalStyle`
    @font-face {
    font-family: 'ProximaNova-Regular';
    src: url('/fonts/ProximaNova-Regular.woff') format('woff');
    font-style: normal;
    font-weight: 400;
    font-display: swap;
  }
  @font-face {
    font-family: 'ProximaNova-Bold';
    src: url('/fonts/ProximaNova-Bold.woff') format('woff');
    font-style: bold;
    font-weight: 700;
    font-display: swap;
  }
`;
function MyApp({ Component, pageProps }) {
  const [open, setOpen] = useState(false);
  return (
    <>
      <ThemeProvider theme ={{colors: colors.light, bp: bp}}>
        <GlobalStyle />
            <Layout open={open} setOpen={setOpen}>
              <Component {...pageProps} />
            </Layout>
      </ThemeProvider>
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激!谢谢!

Man*_*ddy 4

文件:face.css

@font-face {
    font-family: "MyFontRegular";
    src: url("data:font/ttf;base64,--fontInBase64FontHere--");
}
Run Code Online (Sandbox Code Playgroud)

注意:上面的“--fontInBase64FontHere--”是任何字体,例如 true type 字体,使用任何在线工具获取该数据并转换为 base64 格式。Buffer.from("FontFileDataHere").toString('base64')与动态转换也一样,但静态转换速度更快。

文件:main.js

import myFont from "./face.css";

const html = `
    <style>
        ${myFont}
    </style>

    <div style="font-family: MyFontRegular">
        Welcome to Ben's Minecraft
    </div>
`;

// convert "html" to pdf code here
Run Code Online (Sandbox Code Playgroud)