إنشاء تقارير PDF باستخدام TypeScript: مكتبة PDF-Lib

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

إنشاء تقارير PDF باستخدام TypeScript مع مكتبة PDF-Lib

\n\n

في تطوير الويب الحديث، غالبًا ما تنشأ الحاجة إلى إنشاء مستندات PDF معقدة: التقارير، الفواتير، الشهادات أو لوحات التحليل. بفضل الكتابة الصارمة، تجعل TypeScript هذه العملية موثوقة وقابلة للتنبؤ. من بين العديد من المكتبات للعمل مع PDF على منصة Node.js وفي المتصفح، تبرز PDF-Lib - أداة خفيفة الوزن وقوية ومكتوبة بالكامل بلغة TypeScript.

\n\n

لا تتطلب PDF-Lib تثبيت تبعيات أصلية إضافية (على عكس الحلول الثقيلة مثل Puppeteer أو wkhtmltopdf)، وتعمل في كل من Node.js والمتصفح، وتدعم جميع ميزات PDF الحديثة: تضمين الخطوط والصور، إنشاء النماذج، التعليقات التوضيحية وغيرها الكثير.

\n\n

التثبيت وإنشاء أول مستند

\n\n

للبدء، يكفي تثبيت الحزمة عبر npm:

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

لنقم بإنشاء مستند PDF بسيط مع نص:

\n\n
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';\n\nasync function createSimplePdf() {\n  // إنشاء مستند PDF جديد\n  const pdfDoc = await PDFDocument.create();\n\n  // إضافة صفحة (حجم A4)\n  const page = pdfDoc.addPage([595.28, 841.89]); // A4 بالنقاط\n\n  // تضمين خط قياسي\n  const font = await pdfDoc.embedFont(StandardFonts.Helvetica);\n\n  // رسم النص\n  page.drawText('مرحباً بالعالم!', {\n    x: 50,\n    y: 700,\n    size: 30,\n    font: font,\n    color: rgb(0.2, 0.4, 0.8),\n  });\n\n  // حفظ المستند كبايتات\n  const pdfBytes = await pdfDoc.save();\n  return pdfBytes;\n}\n\n// مثال على الاستخدام\ncreateSimplePdf().then((bytes) => {\n  // في Node.js يمكن الكتابة إلى ملف\n  // require('fs').writeFileSync('hello.pdf', bytes);\n  console.log('تم إنشاء PDF! الحجم:', bytes.length, 'بايت');\n});
\n\n

العمل مع النص العربي والخطوط المخصصة

\n\n

إحدى المهام الرئيسية عند إنشاء التقارير باللغة العربية هي العرض الصحيح للأحرف العربية. الخطوط القياسية لـ PDF (Helvetica, Times, Courier) لا تحتوي على رسوم عربية. الحل هو تضمين خط TrueType يدعم Unicode.

\n\n
import { PDFDocument, rgb } from 'pdf-lib';\nimport fontkit from '@pdf-lib/fontkit';\nimport fs from 'fs';\n\nasync function createArabicPdf() {\n  const pdfDoc = await PDFDocument.create();\n\n  // تسجيل fontkit للعمل مع الخطوط المخصصة\n  pdfDoc.registerFontkit(fontkit);\n\n  // تحميل خط يدعم العربية (مثل Noto Naskh Arabic)\n  const fontBytes = fs.readFileSync('NotoNaskhArabic-Regular.ttf');\n  const customFont = await pdfDoc.embedFont(fontBytes);\n\n  const page = pdfDoc.addPage([595.28, 841.89]);\n\n  page.drawText('إنشاء تقرير باستخدام TypeScript', {\n    x: 50,\n    y: 750,\n    size: 24,\n    font: customFont,\n    color: rgb(0, 0, 0),\n  });\n\n  page.drawText('التاريخ: 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

إنشاء الجداول والتقارير المنظمة

\n\n

لا تحتوي PDF-Lib على وحدة مدمجة للجداول، ولكن يمكن تنفيذها يدويًا بسهولة عن طريق رسم الخطوط وتحديد موضع النص. للراحة، يمكن إنشاء دالة مساعدة:

\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  // رسم العناوين\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                    

توصيات