عبدالفتاح الصلوي

تحويل ملف HTML إلى PDF عن طريق laravel ومكتبة mpdf

كتبها : عبدالفتاح الصلوي / في رصيف : Laravel

تحويل ملف HTML إلى PDF عن طريق laravel ومكتبة mpdf

العديد من المشاكل تواجه المطورين عند تصدير 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

            
                <!DOCTYPE html>
                <html lang="ar" dir="rtl">

                <head>
                    <meta charset="UTF-8">
                    <meta name="viewport" content="width=device-width, initial-scale=1.0">
                    <meta http-equiv="X-UA-Compatible" content="ie=edge">
                    <title>pdf test</title>
                    <style>
                        body {
                            font-size: 16px;
                            font-family: "adobearabic",'Roboto', 'Montserrat', 'Open Sans', sans-serif;
                            padding: 0px;
                            margin: 0px;
                            background: #F7F7F7;
                        }
                    </style>
                </head>

                <body>
                    <div>
                        هذا النص باللغة العربية<br>
                        مرحباً يا :
                        {{$name}}
                    </div>
                </body>

                </html>
            
        
            يمكن أيضاً اضافة خطوط آخرى وايضاً باوزان مختلفة راجع توثيق الحزمة .
        

ملاحظة : لمن يظهر له خطأ من نوع

            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 من نوع القيمة المعادة في الدالة  بحيث تصبح الدالة في الواجهة بهذا الشكل :

إذا وجدت المقال مفيداً لما لا تشاركة مع اصدقائك ؟

علامات ذات صلة :