javascript - Puppeteer npm 如何从本地文件设置字体

标签 javascript css node.js fonts puppeteer

我想在使用 puppeteer Node 模块渲染 PDF 时从本地文件加载字体。

使用 web fonts 对我有用但这不能满足要求。

我的环境:

  • Node :v10.18.1,
  • puppeteer 师:“puppeteer 师”:“^2.0.0”,
  • Chrome : Chrome 79.0.3945.88 Fedora 元素,
  • 操作系统:CentOS Linux 发行版 8.0.1905(核心)

  • 这是我迄今为止尝试过的代码:使用@font-face 加载字体、更改networkidle 的值、设置超时、设置用于字体更新的事件监听器。事件我设置此回调以获取返回“Open Sans”但呈现的 PDF 文件不是 Open Sans 字体的字体属性。
    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
    

    关于如何解决这个问题的任何想法?关于如何从本地文件渲染图像有一个类似的问题,但我无法从答案中解决如何使用字体完成。

    最佳答案

    我明白,但不要这样解决。
    如果您在系统上正确安装这些字体,则 PDF 可能会正确导入字体。但是,PDF 消费者(尤其是一些廉价打印机)在打印 PDF 时会遇到困难。在这些情况下,我看到了非常奇怪的错误,例如基于打印机的拖尾。然而,这些都是假设的。
    而是将整个字体嵌入为 base64。结果 PDF 将始终传输这些字体。 base64 myfont.woff > fontbase64.txt

    const yourOpenSans = require('fs').readFileSync('./fontbase64.txt')
    
    function genFont () {
    
    
        return `
    
         @font-face {
            font-family: 'YOUR Open Sans';
            src: url(data:font/truetype;charset=utf-8;base64,${yourOpenSans}) format('truetype');
            font-weight: normal;
            font-style: normal;
         }
        `
    
    }
    
    使用 font-face相应地在您的 CSS 中。
    注意:这些文件对换行很敏感。

    关于javascript - Puppeteer npm 如何从本地文件设置字体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60541577/

    相关文章:

    html - 加载动画不起作用

    node.js - apt-get 始终安装旧版本的 node.js

    javascript - Nodejs 编辑器可在 eclipse 上工作

    javascript - Node.js - Redis 教程

    javascript - 将 Flask Session 与新的 EventSource 结合使用

    javascript - 在 Google Apps 脚本中访问多个参数值

    javascript - Jquery - 计算时间表小时数

    html - 从另一个 CSS 导入 .css?

    javascript - onClick getElementByID(field).value=x 输入

    php - 包装器未正确显示内联内容