Javascript Puppeter npm如何从本地文件设置字体

Javascript Puppeter npm如何从本地文件设置字体,javascript,css,node.js,fonts,puppeteer,Javascript,Css,Node.js,Fonts,Puppeteer,我想在使用Puppeter节点模块渲染PDF时从本地文件加载字体 它对我有用,但不满足要求 我的环境: 节点:v10.18.1 木偶师:“木偶师”:“^2.0.0” 铬:铬79.0.3945.88 Fedora项目 操作系统:CentOS Linux 8.0.1905版(核心版) 以下是我迄今为止尝试过的代码:使用@font-face加载字体、更改networkidle的值、设置超时、为字体更新设置事件侦听器。事件I设置此回调以获取返回“Open SAN”但呈现的PDF文件不是Open SA

我想在使用Puppeter节点模块渲染PDF时从本地文件加载字体

它对我有用,但不满足要求

我的环境:

  • 节点:v10.18.1
  • 木偶师:“木偶师”:“^2.0.0”
  • 铬:铬79.0.3945.88 Fedora项目
  • 操作系统:CentOS Linux 8.0.1905版(核心版)
以下是我迄今为止尝试过的代码:使用@font-face加载字体、更改networkidle的值、设置超时、为字体更新设置事件侦听器。事件I设置此回调以获取返回“Open SAN”但呈现的PDF文件不是Open SAN字体的字体属性

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
const puppeter=require('puppeter');
常量chromiumExecutablePath='/bin/chromium browser';
让文档=`
@字体{
字体系列:“开放式SAN”;
字体风格:普通;
字体大小:400;
src:local(“OpenSans”)url(“/opt/www/webapp/resources/packed/OpenSans Regular.eot”);
src:local(“OpenSans”)url(“/opt/www/webapp/resources/packed/OpenSans Regular.woof”)格式(“woff”),
本地(“开放SAN”)url(“/opt/www/webapp/resources/packed/OpenSans Regular.ttf”)格式(“truetype”);
}
html,正文{
字体系列:“开放式Sans”,无衬线;
}
你好,世界报道
`
const browser=wait puppeter.launch({
参数:['--no sandbox','--disable setuid sandbox','--disable web security','--font render hinting=none'],
无头:是的,
可执行路径:chromiumExecutablePath
});
const page=wait browser.newPage()
const session=wait page.target().createCDPSession();
等待session.send('DOM.enable');
等待session.send('CSS.enable');
等待新的承诺(resolve=>setTimeout(resolve,500));
session.on('CSS.fontsUpdated',event=>{
console.log(事件);
//当浏览器由于webfont加载而更新页面上的字体时,将收到事件。
});
wait page.goto(“数据:text/html;charset=UTF-8,”+文档,{waitUntil:'networkidle0'});
等待页。等待(2000年);
等待page.evaluateHandle('document.fonts.ready');
常量选择器='h1';
常量getFontProperty=async(第页)=>{
常量字体=等待页面。评估((选择器)=>{
const title=document.querySelector(选择器);
返回getComputedStyle(title).font;
},选择器);
返回字体;
}
console.log(等待getFontProperty(第页));//输出:700 32px“开放式SAN”,无衬线
等待第页。仿真媒体(“打印”);
等待页面.pdf({
displayHeaderFooter:错误,
路径:outputPath,
宽度:400+‘px’,
高度:400+‘px’,
背景:是的,
保证金:{
顶部:“20px”,
底部:“40px”
}
}); // 输出是有效的PDF文件,但没有打开的SAN字体

关于如何解决这个问题有什么想法吗?关于如何从本地文件渲染图像,也有一个类似的问题,但我无法从答案中解决如何使用字体。我理解,但不要这样解决

如果在系统上正确安装字体,则可能是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;
     }
    `

}
在CSS中相应地使用
字体


注意:这些文件对换行符很敏感。

看起来访问字体源有问题,因为“url”指向一个相对于css代码位置的web路径,但它看起来不像Puppeter会有那个上下文,因为您正在侧加载内容。当您使用该内容创建html文件并手动启动Chromium时会发生什么情况,它会加载字体吗?当您将字体文件放置在指定的相对路径中时会发生什么情况,该路径也是相对于html文件的?