العديد من المشاكل تواجه المطورين عند تصدير Html إلى pdf وبالأخص مشاكل اللغة العربية وعرضها،ومن تلك المشاكل مشكلة عرض النص على شكل علامات استفهام (؟؟؟) وايضاً ظهور النصوص العربية بشكل متقطع أو من الشمال إلى اليمين.
كنا فيما سبق قد تحدثنا عن بعض الحلول منها استخدام نظام التشغيل للقيام بذلك كما في مقال كيف تقوم بتحويل ملف HTML إلى PDF عن طريق PHP , ومن ثم تحدثنا في مقالنا تحويل ملف HTML إلى PDF نصوص عربية عن طريق laravel عن استخدام laravel-dompdf , Ar-PHP عبر حزمة laravel-arabic-html التي انشأناها لاستخدام utf8Glyphs مع ال view. اليوم سنتحدث عن استخدام مكتبة mPDF عن طريق حزمة niklasravnsborg/laravel-pdf. وتعتبر من أسهل الحلول وسنترك لك حرية لاختيار ما يناسبك. حيث أن لكل مكتبة تنسيقاتها وبعض المشاكل التي قد تحلها مكتبة آخرى .
لنعد إلى الكود ، فكل ما عليك تقوم بتنزيل الحزمة عن طريق الآمر التالي
composer require niklasravnsborg/laravel-pdf
بعدها قم بتصدير ملف الإعدادات إلى مجلد config عن طريق الأمر
php artisan vendor:publish
من ثم اختار الرقم الذي يظهر بجانب الحزمة niklasravnsborg/laravel-pdf. ثم انتقل إلى مجلد ال config حيث ستجد ملف جديد pdf.php يمكننا الان استخدام الخطوط الموجودة مثلاً خط DejaVu ولكن اذا اردنا اختيار خط آخر مثلاً سأستخدم انا هنا AdobeArabic اذهب إلى نهاية الملف ومن ثم اضف إليه الكود التالي :
'font_path' => storage_path('app/fonts/'), 'font_data' => [ 'adobearabic' => [ 'R' => 'AdobeArabicRegular.ttf', 'useOTL' => 0xFF, ] // ...add as many as you want. ]
حيث سنقوم بنسخ الخط ووضعه في مجلد storage/app/fonts وايضاً سنقوم بتعديل مسار tempDir حيث سيتم نسخ الخطوط التابعة للمكتبة إلى المسار ليصبح مساره الجديد كما يلي
'tempDir' => storage_path('temp/'),
بالطبع يمكنك تغيير الاعدادت الأخرى بما يناسبك سيصبح الملف كاملا بحسب التعديلات التي قمنا بها كما يلي :
'utf-8', 'format' => 'A4', 'author' => '', 'subject' => '', 'keywords' => '', 'creator' => 'Laravel Pdf', 'display_mode' => 'fullpage', 'tempDir' => storage_path('temp/'), 'pdf_a' => false, 'pdf_a_auto' => false, 'icc_profile_path' => '', 'font_path' => storage_path('app/fonts/'), 'font_data' => [ 'adobearabic' => [ 'R' => 'AdobeArabicRegular.ttf', 'useOTL' => 0xFF, ] // ...add as many as you want. ] ];
مثال على الاستخدام
function generate_pdf() { $data = [ 'name' => 'My mpdf Doc ' ]; $pdf = PDF::loadView('pdf', $data); return $pdf->stream('document.pdf'); }
وهذا مثال لكود ال pdf.blade.php
pdf test هذا النص باللغة العربية
مرحباً يا : {{$name}}
يمكن أيضاً اضافة خطوط آخرى وايضاً باوزان مختلفة راجع توثيق الحزمة .
ملاحظة : لمن يظهر له خطأ من نوع
Declaration of Mpdf\Mpdf::setLogger(Psr\Log\LoggerInterface $logger) must be compatible with Psr\Log\LoggerAwareInterface::setLogger(Psr\Log\LoggerInterface $logger): void
سبب الخطأ هو تعارض في الإصدارات حيث أن مكتبة ال mPdf لا تدعم النسخة الثالثة من Psr\Log لإصلاح المشكلة هناك عدة حلول منها :
1- استخدم الامر composer why psr/log
للتأكد من الباجات التي تستخدم المكتبة حيث سيعيد قائمة بالباكجات التي تعتمد الباكج وكذا الاصدارات ، انظر في الاصدارات التي تطلبها الباكجات إذا لم تجد تعارض حيث يمكن استخدام المكتبة في الإصدار الثاني، قم بعمل Downgrading إلى الإصدار
الثاني عن طريق الكود التالي
composer require psr/log:2.0
لا ينصح باستخدام هذا الحل.
2- الحل الآخر ، بالنظر الى التعارض الحاصل بين الإصدارين سنلاحظ أن في مكتبة mpdf تحديداً دالة SetLogger تعيد قيمة من نوع $this بينما تفترض ال Interface في Psr\Log\LoggerAwareInterface أن الدالة تعيد قيمة خالية void وهذا ما يسبب التعارض لذا وبينما يتم حل هذا التعارض من قبل المطورين سنظطر إلى أن تقوم بحذف void من نوع القيمة المعادة في الدالة بحيث تصبح الدالة في الواجهة بهذا الشكل :
public function setLogger(LoggerInterface $logger);
إذا وجدت المقال مفيداً لما لا تشاركة مع اصدقائك ؟