توليد تقارير PDF بلغة Java: نظرة عامة على مكتبات iText وApache PDFBox
إنشاء مستندات PDF هو أحد المهام الشائعة في تطبيقات Java المؤسسية. التقارير، الفواتير، الإشعارات، الشهادات - كل هذا يمكن إنشاؤه برمجياً بسهولة. في النظام البيئي لـ Java، هناك مكتبتان رئيسيتان للعمل مع PDF: iText (المعيار الصناعي، ولكن مع ترخيص تجاري للإصدارات الجديدة) وApache PDFBox (مجانية تماماً ومفتوحة المصدر). في هذه المقالة، سنستعرض كلتيهما، ونعرض أمثلة برمجية، ونساعدك في اختيار الأداة المناسبة لمشروعك.
1. Apache PDFBox - بديل مجاني بإمكانيات واسعة
Apache PDFBox هي مكتبة مفتوحة المصدر (ترخيص Apache 2.0). تتيح لك إنشاء PDF من الصفر، تحرير الملفات الموجودة، واستخراج النصوص والبيانات الوصفية. لا تتطلب PDFBox ترخيصاً تجارياً، مما يجعلها خياراً مثالياً للشركات الناشئة والمشاريع مفتوحة المصدر.
الإمكانيات الرئيسية:
- إنشاء مستندات تحتوي على نصوص، صور، وجداول.
- العمل مع الخطوط (بما في ذلك السيريلية).
- إضافة الإشارات المرجعية، الروابط التشعبية، والعلامات المائية.
- التشفير والحماية بكلمة مرور.
- استخراج النصوص والصور من ملفات PDF الموجودة.
مثال: إنشاء تقرير PDF بسيط مع جدول
import org.apache.pdfbox.pdmodel.PDDocument;import org.apache.pdfbox.pdmodel.PDPage;import org.apache.pdfbox.pdmodel.PDPageContentStream;import org.apache.pdfbox.pdmodel.font.PDType0Font;import org.apache.pdfbox.pdmodel.common.PDRectangle;import java.io.File;import java.io.IOException;
public class PdfBoxReport { public static void main(String[] args) throws IOException { try (PDDocument document = new PDDocument()) { PDPage page = new PDPage(PDRectangle.A4); document.addPage(page);
// تحميل خط يدعم السيريلية PDType0Font font = PDType0Font.load(document, new File("fonts/arial.ttf"));
try (PDPageContentStream cs = new PDPageContentStream(document, page)) { // العنوان cs.beginText(); cs.setFont(font, 18); cs.newLineAtOffset(50, 750); cs.showText("تقرير المبيعات للربع الأول 2025"); cs.endText();
// الجدول (تنفيذ بسيط عبر الخطوط والنصوص) cs.setFont(font, 12); // رسم رؤوس الأعمدة float margin = 50; float yStart = 700; float tableWidth = 500; float rowHeight = 25; String[] headers = {"المنتج", "الكمية", "السعر (روبل)"}; String[][] data = {{"لابتوب", "10", "85000"}, {"فأرة", "50", "1500"}, {"لوحة مفاتيح", "30", "3500"}};
// رأس الجدول cs.setLineWidth(1f); for (int i = 0; i < headers.length; i++) { cs.addRect(margin + i * (tableWidth / 3), yStart - rowHeight, tableWidth / 3, rowHeight); cs.stroke(); cs.beginText(); cs.newLineAtOffset(margin + i * (tableWidth / 3) + 5, yStart - rowHeight + 5); cs.showText(headers[i]); cs.endText(); }
// البيانات float yPos = yStart - rowHeight; for (String[] row : data) { yPos -= rowHeight; for (int i = 0; i < row.length; i++) { cs.addRect(margin + i * (tableWidth / 3), yPos, tableWidth / 3, rowHeight); cs.stroke(); cs.beginText(); cs.newLineAtOffset(margin + i * (tableWidth / 3) + 5, yPos + 5); cs.showText(row[i]); cs.endText();