Geração de relatórios PDF em TypeScript com a biblioteca PDF-Lib
No desenvolvimento web moderno, surge frequentemente a necessidade de criar documentos PDF complexos: relatórios, faturas, certificados ou painéis analíticos. O TypeScript, graças à tipagem estrita, torna esse processo confiável e previsível. Entre as várias bibliotecas para trabalhar com PDF na plataforma Node.js e no navegador, destaca-se o PDF-Lib — uma ferramenta leve, poderosa e totalmente escrita em TypeScript.
O PDF-Lib não requer a instalação de dependências nativas adicionais (ao contrário de soluções pesadas como Puppeteer ou wkhtmltopdf), funciona tanto no Node.js quanto no navegador e suporta todos os recursos modernos do PDF: incorporação de fontes, imagens, criação de formulários, anotações e muito mais.
Instalação e primeiro documento
Para começar, basta instalar o pacote via npm:
npm install pdf-libVamos criar um documento PDF simples com texto:
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
async function createSimplePdf() { // Criando um novo documento PDF const pdfDoc = await PDFDocument.create();
// Adicionando uma página (formato A4) const page = pdfDoc.addPage([595.28, 841.89]); // A4 em pontos
// Incorporando a fonte padrão const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
// Desenhando o texto page.drawText('Olá, mundo!', { x: 50, y: 700, size: 30, font: font, color: rgb(0.2, 0.4, 0.8), });
// Salvando o documento em bytes const pdfBytes = await pdfDoc.save(); return pdfBytes;}
// Exemplo de usocreateSimplePdf().then((bytes) => { // No Node.js, pode-se escrever em um arquivo // require('fs').writeFileSync('hello.pdf', bytes); console.log('PDF criado! Tamanho:', bytes.length, 'bytes');});Trabalhando com texto em português e fontes personalizadas
Uma das principais tarefas ao gerar relatórios em português é a exibição correta de caracteres acentuados. As fontes padrão do PDF (Helvetica, Times, Courier) não contêm glifos acentuados. A solução é incorporar uma fonte TrueType com suporte a Unicode.
import { PDFDocument, rgb } from 'pdf-lib';import fontkit from '@pdf-lib/fontkit';import fs from 'fs';
async function createPortuguesePdf() { const pdfDoc = await PDFDocument.create();
// Registrando o fontkit para trabalhar com fontes personalizadas pdfDoc.registerFontkit(fontkit);
// Carregando uma fonte com acentos (por exemplo, Roboto) const fontBytes = fs.readFileSync('Roboto-Regular.ttf'); const customFont = await pdfDoc.embedFont(fontBytes);
const page = pdfDoc.addPage([595.28, 841.89]);
page.drawText('Geração de relatório em TypeScript', { x: 50, y: 750, size: 24, font: customFont, color: rgb(0, 0, 0), });
page.drawText('Data: 2024-01-15', { x: 50, y: 700, size: 14, font: customFont, color: rgb(0.3, 0.3, 0.3), });
return await pdfDoc.save();}Criação de tabelas e relatórios estruturados
O PDF-Lib não possui um módulo interno para tabelas, mas elas podem ser facilmente implementadas manualmente desenhando linhas e posicionando texto. Para facilitar, podemos criar uma função auxiliar:
interface TableCell { text: string; width: number; height?: number; align?: 'left' | 'center' | 'right';}
async function drawTable( page: PDFPage, headers: TableCell[], rows: TableCell[][], startX: number, startY: number, font: PDFFont, fontSize: number = 12) { const cellPadding = 5; const rowHeight = fontSize + 2 * cellPadding; let currentY = startY;
// Desenhando os cabeçalhos let currentX = startX; for (const header of headers) { page.drawRectangle({ x: currentX, y: currentY - rowHeight, width: header.width, height: rowHeight, color: rgb(0.9, 0.9, 0.9), Também na biblioteca
Trabalhando com arquivos ZIP em Node.js: bibliotecas archiver e adm-zip
Aprendizado de Máquina em Kotlin: visão geral das bibliotecas KMath, Smile, KotlinDL e DeepLearning4J
Autorização e Autenticação em Go: pacotes e exemplos práticos
Doctrine DBAL para PHP: guia completo com exemplos práticos