Как правильно распечатать полную страницу SPA в pdf, используя NodeJS и Puppeteer? - PullRequest
0 голосов
/ 10 января 2020

Пожалуйста, помогите мне сгенерировать pdf-файл со страницы реагирующего одностраничного приложения с рендерингом на стороне клиента. Я реализовал клиентское приложение с кнопкой «Сохранить как pdf» и конечную точку на стороне сервера с кодом кукловода (см. Ниже). Когда я нажимаю «Сохранить как PDF», я хочу увидеть файл PDF с полной текущей страницей, но я вижу только первую страницу с только видимым содержимым. Где ошибка в моем коде?

Заранее спасибо.

const express = require("express");
const morgan = require("morgan");
const cors = require("cors");
const puppeteer = require("puppeteer");

const app = express();
const PORT = process.env.PORT || 3005;

const printPdf = async (projectId, reportName) => {
  const browser = await puppeteer.launch({
    headless: true
  });

  const page = await browser.newPage();

  page.setViewport({
    width: 1920,
    height: 1080
  });

  page.goto(
    `http://localhost:3000/project/${projectId}/report/${reportName}`,
    { waitUntil: "networkidle2" }
  );

  await page.waitForNavigation();
  await page.type("#username", process.env.USERNAME);
  await page.type("#password", process.env.PASSWORD);
  await page.click("#submit");
  await page.waitForSelector(".content", { visible: true });

  const pdfFile = await page.pdf({
    format: "A4",
    printBackground: true
  });

  await browser.close();

  return pdfFile;
};

app.use(cors());
app.use(morgan("combined"));

app.get("/export", function(req, res) {
  const { projectId, reportName } = req.query;

  printPdf(projectId, reportName)
    .then(pdf => {
      res.set({
        "Content-Type": "application/pdf",
        "Content-Length": pdf.length
      });

      res.send(pdf);
    })
    .catch(error => {
      console.log("!!ERROR", error);
    });
});

app.listen(PORT, () => {
  console.log("Server running on port %d", PORT);
});

1 Ответ

0 голосов
/ 10 января 2020

попробуйте удалить настройки ниже. Я получил PDF без этих строк. Кажется, проблема с навигацией. вместо этого попробуйте увеличить время ожидания.

//remove this    
 await page.waitForNavigation();
 await page.type("#username", process.env.USERNAME);
 await page.type("#password", process.env.PASSWORD);
 await page.click("#submit");
 await page.waitForSelector(".content", { visible: true });

Это код, который я использовал и работал.

const express = require('express');
const morgan = require('morgan');
const cors = require('cors');
const puppeteer = require('puppeteer');

const app = express();
const PORT = process.env.PORT || 3005;

const printPdf = async () => {
    console.log('i am in');
    const browser = await puppeteer.launch({
        headless: true
    });

    const page = await browser.newPage();

    page.setViewport({
        width: 1920,
        height: 1080
    });

    await page.goto('https://news.ycombinator.com', {
        waitUntil: 'networkidle2'
    });

    const pdfFile = await page.pdf({
        format: 'A4',
        printBackground: true
    });

    await browser.close();

    return pdfFile;
};

app.use(cors());
app.use(morgan('combined'));

app.get('/', function(req, res) {
    printPdf()
        .then(pdf => {
            res.set({
                'Content-Type': 'application/pdf',
                'Content-Length': pdf.length
            });

            res.send(pdf);
        })
        .catch(error => {
            console.log('!!ERROR', error);
        });
});

app.listen(PORT, () => {
    console.log('Server running on port %d', PORT);
});
...