Aprenda como você pode gerar um documento PDF a partir de qualquer página da web usando NodeJS, Puppeteer e Chromium
Como desenvolvedor da web, você pode querer gerar um arquivo PDF de uma página da web para compartilhar com seus clientes, usá-lo em apresentações ou adicioná-lo como um novo recurso em seu aplicativo da web. Não importa o motivo, Puppeteer, a API Node do Google para Chrome e Chromium sem cabeça, torna a tarefa bastante simples para você.
Neste tutorial, veremos como converter páginas da web em PDF com Puppeteer e Node.js. Vamos começar o trabalho com uma rápida introdução ao que é o Puppeteer.
O que é Puppeteer, e por que é incrível?
Nas próprias palavras do Google, Puppeteer é, “Uma biblioteca Node que fornece uma API de alto nível para controlar o Chrome ou Chromium headless sobre o protocolo DevTools”.
O que é um navegador sem cabeça?
Se você não está familiarizado com o termo navegadores sem cabeçalho, trata-se simplesmente de um navegador sem GUI. Nesse sentido, um navegador sem cabeça é simplesmente outro navegador que entende como renderizar páginas da web HTML e processar JavaScript. Devido à falta de uma GUI, as interações com um navegador headless ocorrem por meio de uma linha de comando.
Mesmo que o Puppeteer seja principalmente um navegador sem cabeça, você pode configurá-lo e usá-lo como um Chrome ou Chromium sem cabeça.
O que você pode fazer com o Puppeteer?
Os poderosos recursos do navegador do Puppeteer o tornam um candidato perfeito para testes de aplicativos da web e web scraping.
Para citar alguns casos de uso em que o Puppeteer fornece as funcionalidades perfeitas para desenvolvedores da web,
- Gere PDFs e capturas de tela de páginas da web
- Automatizar o envio do formulário
- Raspar páginas da web
- Execute testes de IU automatizados enquanto mantém o ambiente de teste atualizado.
- Gerar conteúdo pré-renderizado para aplicativos de página única (SPAs)
Configure o ambiente do projeto
Você pode usar o Puppeteer no backend e frontend para gerar PDFs. Neste tutorial, estamos usando um back-end Node para a tarefa.
Inicialize o NPM e configure o servidor Express normal para começar com o tutorial.
const express = require("express");
const puppeteer = require("puppeteer");
const app = express();
app.listen(3000, () => {
console.log("Server started");
});
Certifique-se de instalar o pacote Puppeteer NPM com o seguinte comando antes de começar.
npm install puppeteer
Converter páginas da web em PDF
Agora chegamos à parte emocionante do tutorial. Com o Puppeteer, precisamos apenas de algumas linhas de código para converter páginas da web em PDF.
Primeiro, crie uma instância do navegador usando a launch
função do Puppeteer .
const browser = await puppeteer.launch();
Em seguida, criamos uma nova instância de página e visitamos o URL da página fornecida usando o Puppeteer.
const webPage = await browser.newPage();
const url = "https://livecodestream.dev/post";
await webPage.goto(url, {
waitUntil: "networkidle0"
});
Definimos a waitUntil
opção para networkidle0
. Quando usamos a networkidle0
opção, o Puppeteer espera até que não haja novas conexões de rede nos últimos 500 ms. É uma forma de determinar se o carregamento do site foi concluído. Não é exato e o Puppeteer oferece outras opções, mas é uma das mais confiáveis na maioria dos casos.
Por fim, criamos o PDF a partir do conteúdo da página rastreada e o salvamos em nosso dispositivo.
await webPage.pdf({
printBackground: true,
path: "webpage.pdf",
format: "Letter",
margin: {
top: "20px",
bottom: "40px",
left: "20px",
right: "20px"
}
});
await browser.close();
A função de impressão em PDF é bastante complicada e permite muitas personalizações, o que é fantástico. Aqui estão algumas das opções que usamos:
- printBackground : quando esta opção é definida como true, o Puppeteer imprime no PDF todas as cores ou imagens de fundo que você usou na página da web.
- path : Path especifica onde salvar o arquivo PDF gerado. Você também pode armazená-lo em um fluxo de memória para evitar a gravação no disco.
- formato : você pode definir o formato PDF para uma das opções fornecidas: Carta, A4, A3, A2, etc.
- margem : você pode especificar uma margem para o PDF gerado com esta opção.
Quando a criação do PDF terminar, feche a conexão do navegador com browser.close()
.
Crie uma API para gerar e responder PDFs de URLs
Com o conhecimento que adquirimos até agora, podemos criar um novo endpoint que receberá uma URL como uma string de consulta e, em seguida, enviará de volta para o cliente o PDF gerado.
Aqui está o código:
const express = require("express");
const puppeteer = require("puppeteer");
const app = express();
app.get("/pdf", async (req, res) => {
const url = req.query.target;
const browser = await puppeteer.launch({
headless: true
});
const webPage = await browser.newPage();
await webPage.goto(url, {
waitUntil: "networkidle0"
});
const pdf = await webPage.pdf({
printBackground: true,
format: "Letter",
margin: {
top: "20px",
bottom: "40px",
left: "20px",
right: "20px"
}
});
await browser.close();
res.contentType("application/pdf");
res.send(pdf);
})
app.listen(3000, () => {
console.log("Server started");
});
Se você iniciar o servidor e visitar a /pdf
rota, com um target
parâmetro de consulta contendo a URL que queremos converter. O servidor servirá o PDF gerado diretamente, sem nunca armazená-lo no disco.
Exemplo de URL: http://localhost:3000/pdf?target=https://google.com
O que irá gerar o seguinte PDF, conforme parece na imagem:
É isso aí! Você concluiu a conversão de uma página da web em PDF. Não foi fácil?
Conforme mencionado, o Puppeteer oferece muitas opções de personalização, portanto, certifique-se de brincar com as oportunidades para obter resultados diferentes.
Em seguida, podemos alterar o tamanho da janela de visualização para capturar sites em diferentes resoluções.
Capture sites com janelas de visualização diferentes
No PDF criado anteriormente, não especificamos o tamanho da janela de visualização para a página da Web que o Puppeteer está visitando; em vez disso, usamos o tamanho da janela de visualização padrão, 800 × 600px.
No entanto, podemos definir com precisão o tamanho da janela de visualização da página antes de rastrear a página.
await webPage.setViewport({ width: 1200, height: 800 });
await webPage.goto(url, {
waitUntil: "networkidle0"
});