توليد تقارير PDF بلغة Kotlin: مراجعة المكتبات وأمثلة عملية
Kotlin، باعتبارها لغة حديثة لـ JVM، مناسبة تمامًا لإنشاء تطبيقات الخادم، بما في ذلك توليد تقارير PDF معقدة. على عكس Python، حيث تشتهر ReportLab أو FPDF، في نظام Kotlin/Java البيئي تُستخدم مكتبات مجرّبة عبر الزمن: iText وApache PDFBox وOpenPDF. في هذه المقالة، سنستعرض كلًا منها، ونعرض أمثلة على الكود بلغة Kotlin، ونقدم توصيات للاختيار.
1. iText (الإصداران 7 و8)
iText هو المعيار الفعلي لتوليد PDF على JVM. توفر المكتبة واجهة برمجة تطبيقات قوية لإنشاء المستندات من الصفر، والعمل مع النماذج والعلامات المائية والتوقيعات الرقمية. ومع ذلك، بدءًا من الإصدار 7، انتقل iText إلى ترخيص AGPL (أو تجاري)، وهو أمر مهم يجب مراعاته عند الاستخدام التجاري.
مثال لإنشاء PDF بسيط مع جدول بلغة Kotlin:
import com.itextpdf.kernel.pdf.PdfDocumentimport com.itextpdf.kernel.pdf.PdfWriterimport com.itextpdf.layout.Documentimport com.itextpdf.layout.element.Paragraphimport com.itextpdf.layout.element.Tableimport com.itextpdf.layout.property.UnitValue
fun generateReportItext(outputPath: String) { val writer = PdfWriter(outputPath) val pdf = PdfDocument(writer) val document = Document(pdf)
// العنوان document.add(Paragraph("تقرير المبيعات").setFontSize(20))
// الجدول val table = Table(UnitValue.createPercentArray(3)).useAllAvailableWidth() table.addCell("المنتج") table.addCell("الكمية") table.addCell("السعر") table.addCell("حاسوب محمول") table.addCell("10") table.addCell("75000") table.addCell("شاشة") table.addCell("5") table.addCell("25000")
document.add(table) document.close() println("تم إنشاء PDF: $outputPath")}2. Apache PDFBox
PDFBox هي مكتبة مجانية (ترخيص Apache 2.0) لا تسمح فقط بإنشاء PDF، بل أيضًا باستخراج النص، وملء النماذج، وعرض الصفحات كصور. واجهة برمجة التطبيقات أقل مستوى قليلاً من iText، ولكنها تمنح تحكمًا كاملاً في المحتوى.
مثال مع صورة وتنسيق النص:
import org.apache.pdfbox.pdmodel.PDDocumentimport org.apache.pdfbox.pdmodel.PDPageimport org.apache.pdfbox.pdmodel.PDPageContentStreamimport org.apache.pdfbox.pdmodel.font.PDType0Fontimport org.apache.pdfbox.pdmodel.graphics.image.PDImageXObjectimport java.io.File
fun generateReportPdfBox(outputPath: String) { val document = PDDocument() val page = PDPage() document.addPage(page)
val contentStream = PDPageContentStream(document, page) // تحميل الخط (TrueType) val font = PDType0Font.load(document, File("fonts/DejaVuSans.ttf")) contentStream.setFont(font, 14f)
// النص contentStream.beginText() contentStream.newLineAtOffset(50f, 750f) contentStream.showText("تقرير يناير 2025") contentStream.endText()
// الصورة (الشعار) val image = PDImageXObject.createFromFile("logo.png", document) contentStream.drawImage(image, 50f, 650f, 100f, 50f)
contentStream.close() document.save(outputPath) document.close() println("تقرير PDFBox جاهز: $outputPath")}3. OpenPDF
OpenPDF هو فرع من الإصدار القديم من iText (LGPL)، والذي يظل مجانيًا تمامًا. مثالي للتقارير البسيطة: النص، الجداول، الرسوم الأولية الأساسية. تشبه واجهة برمجة التطبيقات iText 2.x، ولكن هذا ليس مشكلة في كود Kotlin الحديث.
مثال لإنشاء PDF مع فقرات وقائمة:
import com.lowagie.text.Documentimport com.lowagie.text.Paragraphimport com.lowagie.text.pdf.PdfWriterimport java.io.FileOutputStream
fun generateReportOpenPdf(outputPath: String) {