Génération de rapports PDF en TypeScript : la bibliothèque PDF-Lib

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Génération de rapports PDF en TypeScript avec la bibliothèque PDF-Lib

\n\n

Dans le développement web moderne, il est souvent nécessaire de créer des documents PDF complexes : rapports, factures, certificats ou tableaux de bord analytiques. TypeScript, grâce à son typage strict, rend ce processus fiable et prévisible. Parmi les nombreuses bibliothèques pour travailler avec des PDF sur la plateforme Node.js et dans le navigateur, PDF-Lib se distingue comme un outil léger, puissant et entièrement écrit en TypeScript.

\n\n

PDF-Lib ne nécessite pas l'installation de dépendances natives supplémentaires (contrairement aux solutions lourdes comme Puppeteer ou wkhtmltopdf), fonctionne à la fois dans Node.js et dans le navigateur, et prend en charge toutes les fonctionnalités PDF modernes : incorporation de polices, d'images, création de formulaires, d'annotations et bien plus encore.

\n\n

Installation et premier document

\n\n

Pour commencer, il suffit d'installer le package via npm :

\n\n
npm install pdf-lib
\n\n

Créons un document PDF simple avec du texte :

\n\n
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';\n\nasync function createSimplePdf() {\n  // Créer un nouveau document PDF\n  const pdfDoc = await PDFDocument.create();\n\n  // Ajouter une page (format A4)\n  const page = pdfDoc.addPage([595.28, 841.89]); // A4 en points\n\n  // Incorporer une police standard\n  const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n\n  // Dessiner du texte\n  page.drawText('Bonjour le monde !', {\n    x: 50,\n    y: 700,\n    size: 30,\n    font: font,\n    color: rgb(0.2, 0.4, 0.8),\n  });\n\n  // Sauvegarder le document en octets\n  const pdfBytes = await pdfDoc.save();\n  return pdfBytes;\n}\n\n// Exemple d'utilisation\ncreateSimplePdf().then((bytes) => {\n  // Dans Node.js, on peut écrire dans un fichier\n  // require('fs').writeFileSync('hello.pdf', bytes);\n  console.log('PDF créé ! Taille :', bytes.length, 'octets');\n});
\n\n

Gestion du texte en russe et des polices personnalisées

\n\n

L'une des tâches clés lors de la génération de rapports en russe est l'affichage correct du cyrillique. Les polices PDF standard (Helvetica, Times, Courier) ne contiennent pas de glyphes cyrilliques. La solution consiste à incorporer une police TrueType avec prise en charge Unicode.

\n\n
import { PDFDocument, rgb } from 'pdf-lib';\nimport fontkit from '@pdf-lib/fontkit';\nimport fs from 'fs';\n\nasync function createRussianPdf() {\n  const pdfDoc = await PDFDocument.create();\n\n  // Enregistrer fontkit pour travailler avec des polices personnalisées\n  pdfDoc.registerFontkit(fontkit);\n\n  // Charger une police avec cyrillique (par exemple, Roboto)\n  const fontBytes = fs.readFileSync('Roboto-Regular.ttf');\n  const customFont = await pdfDoc.embedFont(fontBytes);\n\n  const page = pdfDoc.addPage([595.28, 841.89]);\n\n  page.drawText('Génération de rapport en TypeScript', {\n    x: 50,\n    y: 750,\n    size: 24,\n    font: customFont,\n    color: rgb(0, 0, 0),\n  });\n\n  page.drawText('Date : 2024-01-15', {\n    x: 50,\n    y: 700,\n    size: 14,\n    font: customFont,\n    color: rgb(0.3, 0.3, 0.3),\n  });\n\n  return await pdfDoc.save();\n}
\n\n

Création de tableaux et de rapports structurés

\n\n

PDF-Lib n'a pas de module intégré pour les tableaux, mais ils peuvent être facilement implémentés manuellement en dessinant des lignes et en positionnant le texte. Pour plus de commodité, vous pouvez créer une fonction d'aide :

\n\n
interface TableCell {\n  text: string;\n  width: number;\n  height?: number;\n  align?: 'left' | 'center' | 'right';\n}\n\nasync function drawTable(\n  page: PDFPage,\n  headers: TableCell[],\n  rows: TableCell[][],\n  startX: number,\n  startY: number,\n  font: PDFFont,\n  fontSize: number = 12\n) {\n  const cellPadding = 5;\n  const rowHeight = fontSize + 2 * cellPadding;\n  let currentY = startY;\n\n  // Dessiner les en-têtes\n  let currentX = startX;\n  for (const header of headers) {\n    page.drawRectangle({\n      x: currentX,\n      y: currentY - rowHeight,\n      width: header.width,\n      height: rowHeight,\n      color: rgb(0.9, 0.9, 0.9),\n                    

Recommendations