توليد تقارير PDF بلغة Rust: مكتبة printpdf

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

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

ابدأ الدورة

توليد تقارير PDF بلغة Rust باستخدام مكتبة printpdf



في عالم البرمجة الحديث، تُستخدم Rust بشكل متزايد لإنشاء تطبيقات خادم عالية الأداء وأدوات سطر الأوامر. من المهام المطلوبة بشكل شائع توليد تقارير PDF — سواء كانت لوحات تحليلية، فواتير، أو وثائق. توفر مكتبة printpdf طريقة خفيفة وموثوقة لإنشاء مستندات PDF بلغة Rust الخالصة دون الاعتماد على أنظمة خارجية (مثل LaTeX أو wkhtmltopdf).



ما هي printpdf؟



printpdf هي مكتبة Rust خالصة لتوليد مستندات PDF من الصفر. تدعم:

  • نصوص بخطوط مختلفة (بما في ذلك الخطوط المضمنة TrueType/OpenType).
  • رسومات متجهة (خطوط، مستطيلات، أشكال بيضاوية).
  • صور (PNG، JPEG) مع شفافية.
  • جداول وتنسيق معقد من خلال التموضع اليدوي.
  • صفحات بأي حجم (A4، Letter، مخصصة).


لا تستخدم المكتبة عمليات خارجية، مما يجعلها مثالية للتضمين في خدمات الويب، أدوات CLI، أو تطبيقات سطح المكتب بلغة Rust.



التثبيت



أضف إلى Cargo.toml:



[dependencies]printpdf = "0.7"


ستحتاج أيضًا إلى crate rusttype للعمل مع الخطوط (يتم سحبه تلقائيًا كاعتماد).



مثال أساسي: إنشاء تقرير بسيط



لنكتب برنامجًا ينشئ PDF بعنوان ونص وخط. سنحفظ النتيجة في ملف report.pdf.



use printpdf::*;use std::fs::File;use std::io::BufWriter;

fn main() { // إنشاء مستند بحجم A4 let (doc, page1, layer1) = PdfDocument::new( "تقريري", Mm(210.0), Mm(297.0), "الطبقة 1", );

// الحصول على الخط (Helvetica المدمج) let font = doc.add_builtin_font(BuiltinFont::Helvetica).unwrap();

// البدء في الرسم على الطبقة الأولى let current_layer = doc.get_page(page1).get_layer(layer1);

// نص: عنوان current_layer.use_text( "تقرير المبيعات", 24.0, Mm(20.0), Mm(270.0), &font, );

// نص: عادي current_layer.use_text( "تاريخ التقرير: 2025-03-15", 12.0, Mm(20.0), Mm(250.0), &font, );

// رسم خط فاصل current_layer.set_outline_color(Color::Rgb(Rgb::new(0.5, 0.5, 0.5))); current_layer.set_stroke_width(1.0); current_layer.add_line( Point::new(Mm(20.0), Mm(240.0)), Point::new(Mm(190.0), Mm(240.0)), );

// حفظ في ملف let file = File::create("report.pdf").unwrap(); let writer = BufWriter::new(file); doc.save(&mut std::io::BufWriter::new(writer)).unwrap();

println!("تم إنشاء تقرير PDF: report.pdf");}


ينشئ هذا الكود PDF بصفحة واحدة يحتوي على عنوان وتاريخ وخط رمادي. جميع الإحداثيات محددة بالمليمترات (يمكن استخدام النقاط أيضًا).



إضافة جدول بالبيانات



غالبًا ما تحتاج التقارير إلى جداول. لا تحتوي printpdf على هياكل جداول جاهزة، ولكن يمكن تنفيذها يدويًا بسهولة:



use printpdf::*;use std::fs::File;use std::io::BufWriter;

fn draw_table( layer: &PdfLayerReference, font: &IndirectFontRef, data: Vec<[&str; 3]>, start_x: Mm, start_y: Mm,) { let col_widths = [Mm(40.0), Mm(60.0), Mm(50.0)]; let row_height = Mm(10.0); let header_bg = Color::Rgb(Rgb::new(0.9, 0.9, 0.9));

for (row_idx, row_data) in data.iter().enumerate() { let y = start_y - row_height * (row_idx as f32);

// خلفية للعنوان if row_idx == 0 { layer.set_fill_color(header_bg); layer.add_rectangle( start_x, y - row_height,

توصيات