[Ajuda] Renderizar PDF a partir de HTML com Node.js
Situação: tenho alguns templates em html + css e estava usando Puppeteer. Localmente estava dando certo, porém rodo minha api na AWS, ao upar a api com o puppeteer, dá erro, e configurar o chromium/lambda no estado atual não é possível para mim.
Estou tentando utilizar o html-pdf e html-pdf-node, porém está quebrando as imagens e até divs, fica cortado pela metade nas páginas. O css parece não funcionar muito bem com essa lib, os exemplos utilizam até bootstrap, achei que ajudaria, mas em partes apenas.
Alguém teria alguma outra sugestão ou dica ?
const pdf = require("html-pdf-node");
const generatePDF = async (htmlContent, format, landscape) => {
const options = {
format, // Tamanho do papel, como "A4" ou "Letter"
landscape, // Orientação: true para paisagem, false para retrato
preferCSSPageSize: true,
printBackground: true,
};
// Criação do PDF a partir do HTML
const file = { content: htmlContent };
try {
const pdfBuffer = await pdf.generatePdf(file, options);
return pdfBuffer;
} catch (error) {
throw new Error(`Erro ao gerar PDF: ${error.message}`);
}
};
Utilizo esse código, que diz que resolve a quebra, porém sem sucesso 100%
/* Evita quebras de elementos dentro de uma página */
.no-break,
.header,
.checklist-item,
.value-item {
page-break-inside: avoid;
break-inside: avoid;
}
é muito importante que o pdf seja gerado no backend? pois muitas vezes é mais fácil gerar no front usando control+P
ou
function salvarpdf() { window.print(); }
até porque rodar o puppeteer na aws vai sair muito caro
Tenho um usecase parecido com o seu em minha aplicação B2B, onde usuarios podem construir seus PDFs. Inicialmente parti para uma abordagem construindo esse PDF no frontend, e usando diversas ferramentas que o convertiam para que o usuário pudesse fazer o download.
Decidimos tentar essa abordagem fazendo uma POC, e logo vimos as infinitas limitações que esse tipo de solução teria.
Construimos então toda a lógica no backend, o que se mostrou um completo sucesso. Utilizamos a lib pdfkit
. Acho que não há melhor do que ela hoje. Eu não recomendo tentar transformar HTML diretamente em um PDF, isso vai levar a diversas inconsistencias visuais, quebra de linhas incorretas, overlap de conteudos, quebra de paginas incorretas e etc, o que aconteceu conosco em nossas diversas POCs dessa feature.
Com o pdfkit
conseguimos criar todo tipo de PDF personalizado. Recomendo dar uma olhada: https://pdfkit.org/
Como comentou que vai rodar em lambdas, recomendo tomar cuidado ao lidar com muitas imagens bufferizadas nas paginas, isso geralmente acarreta em um uso excessivo de memória. Sucesso no projeto.
Gera o pdf no front e chama o visualizador de pdf do navegador. depois o usuário se vira pra baixar ou imprimir.
Tente usar o Gotenberg. Encontrei recentemente e estou usando em todos os meus projetos. Ele oferece várias maneiras de criar PDFs
Uma coisa que pensei é verificar com o windom.print se a página html + css está sendo a mesma dessa lib que utilizado com nodejs. Se for, pode ser que resolva com algumas linhas de css.
Se não der certo. veja na biblioteca issues abertas/fechadas no repositório. veja se já tiveram esse problema.
Use --no-sandbox dentro de args ao instanciar seu Browser. Veja sobre outras configurações de Sandbox como --disable-setuid-sandbox, pois elas interagem diretamente com as configurações de superusuário do Chrome.
Voce pode também utilizar o Libre Office ao invés do pupeeeter. É mais eficiente, e voce pode usar chields para executar os comandos. Só nao sei se ele consegue abrir o HTML, teria que testar
Uso o weasyprint para gerar pdf em relatórios na empresa. https://weasyprint.org/
Até hoje a melhor opção para mim foi o wkhtmltopdf.