【问题标题】:Pdf height and width changes when generating file with Puppeteer使用 Puppeteer 生成文件时 Pdf 高度和宽度发生变化
【发布时间】:2018-08-02 21:34:36
【问题描述】:

我正在尝试从我的网站页面生成 pdf。 为此,我有一个运行 Puppeteer 的快速服务器并做了几件事: - 当用户查看页面时,取浏览器的宽度。 - 调整 chrome 无头浏览器的大小。 - 计算页面的高度。 - 将宽度/高度信息作为参数传递给page.pdf({})

我网站的某些页面可以在一个页面上很好地呈现。但其他人确实在两个页面上呈现,好像某些元素将内容高度推到高于 Puppeteer 上 javascript 中计算的高度。

如果它确实有帮助,我想我在代码开头使用了这个 sn-p:await page.emulateMedia('screen');

我检查了几个假设: - 使用调试控制台,我在调整页面大小时得到了文档的实际高度。 - 我检查了这些信息是否正确传递给了 Puppeteer。 - 我通过将其转换为像素来检查以英寸为单位的高度是否正确。

这三个假设是正确的。

这是我的 Puppeteer 代码:

    const page = await browser.newPage();
    await page.emulateMedia('screen');

    // Resize window to the width it had when the client has seen it.
    async function resizeWindow(width, height) {
      await page.setViewport({height, width});

      // Window frame - probably OS and WM dependent.
      height += 85;

      // Any tab.
      const {targetInfos: [{targetId}]} = await browser._connection.send(
        'Target.getTargets'
      );

      // Tab window.
      const {windowId} = await browser._connection.send(
        'Browser.getWindowForTarget',
        {targetId}
      );

      // Resize.
      await browser._connection.send('Browser.setWindowBounds', {
        bounds: {height, width},
        windowId
      });
    }
    resizeWindow(parseInt(req.body.evidenceWidth), 0); // Use 0 as a default height because it is required, but not relevant.
    // Wait for page width to be actually changed
    await page.mainFrame().waitForFunction(`window.innerWidth === ${parseInt(req.body.evidenceWidth)}`);

    // Go to the page and wait for all the connection on the page to be resolved
    await page.goto(`${req.body.url}`, {waitUntil: 'networkidle0'});

    // Calculate real page height
    const realPageHeight = await page.evaluate(() => {
      const body = document.body,
            html = document.documentElement;
      const pageHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );

      return pageHeight;
    });

    // Convert size from pixel to inches to avoid rounding issues caused by Puppeteer
    const convertPixelToInches = (value) => {
      let inches = Math.ceil(value/ 96 * 1000) / 1000;

      return `${parseFloat(inches).toFixed(3)}in`; // Calculate inches value and round it up.
    }
    const pageWidth = convertPixelToInches(req.body.evidenceWidth);
    const pageHeight = convertPixelToInches(realPageHeight < req.body.evidenceHeight ? req.body.evidenceHeight : realPageHeight);


    // Send the response
    switch(req.body.format) {
      case 'html':
        const html = await page.content();

        await fs.writeFile(join(__dirname, HTML_EVIDENCE_FD, `${uuid}.html`), html, (err) => {
          if (err) {
            console.error(`Evidence html could not be generated`, err);
          } else {
            res.status(200).sendFile(join(__dirname, HTML_EVIDENCE_FD, `${uuid}.html`));
          }
        });
        break;

      case 'pdf':
        await page.pdf({
          path: join(__dirname, PDF_EVIDENCE_FD, `${uuid}.pdf`),
          height: pageHeight,
          width: pageWidth,
          printBackground: true,
        });

        res.status(200).sendFile(join(__dirname, PDF_EVIDENCE_FD, `${uuid}.pdf`));
        break;

      default:
        res.status(501).send({ error: 'The format you chose is not supported'});
        break;
    }

    await page.close();
    await browser.close();
  });

  app.on("listening", function() {
    console.log("Listening on port %d", app.port);
  });
  return app;

还有!我注意到另一个问题,假设我在 750 像素处有一个断点,我将 800 像素传递给 Puppeteer,我希望我的 pdf 中不会遇到该断点。但是在 pdf 中完成的渲染就像页面宽度在断点下一样。 pdf生成过程中是否添加了一些不可见的边距?

【问题讨论】:

    标签: javascript node.js pdf puppeteer google-chrome-headless


    【解决方案1】:

    所以经过几天的搜索,我发现了问题:

    • 我在 css 中使用 rem 作为字体大小和行高,所以我删除了它们 来自犯罪分子。
    • 我没有重置 css,在我的顶部添加 normalize.css 样式解决了我的大部分身高问题。
    • 即使使用 normalize.css,Chrome 也会在周围添加一个 rem 填充 段落,我添加以设置像素值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      • 2012-08-21
      • 2018-08-04
      • 1970-01-01
      相关资源
      最近更新 更多