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

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

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

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

كيف تقوم بتحويل ملف HTML إلى PDF عن طريق PHP مع الأمثلة. هنا قمنا بتجميع أفضل الطرق والممارسات باستخدام مكتبة wkhtmltopdf و chrome-php  وغيرها .

#كلام_مبرمجين

توطئة :

دعنا نلقي نظرة على FFI php  (Foreign Function Interface ) أولاً:

ببساطة هي إضافة في اللغة (وأعني بقولي اللغة هنا php) (ابتداء من الإصدار 7.4 تقريبا) تهدف لاستخدام مكتبات مكتوبة بلغات برمجة اخرى تتبع نمط C-ABI (C- Application  Binary Interface) مثل (C, Golang , Rust),
وتعتبر هذه الطريقة أسرع من استخدام ال API's و RPC (Remote   procedure call) لأنها  تتواصل مباشرة مع المكتبات بصيغة binary في اللغة .


سبق و قرأت اسئلة كثيرة  عن افضل مكتبة تستخدم لتحويل صفحة html إلى  pdf بال php، وهناك قائمة طويلة بالمكتبات والباكجات التي تقوم بذلك، ولكن معظمها لا يدعم اللغة العربية، او لا يدعم التنسيقات وهناك مشاكل اخرى يواجهها الكثير, البعض يستطيع حلها وبعضهم لا.

  كيف يقوم المستخدم العادي بالأمر؟

 دعنا نكتب سيناريو :
- تقوم بفتح متصفح كروم أو فاير فوكس .
- يكتب رابط الموقع ، يضغط انتر .
- يضغط على زر الطباعة ويختار حفظ ك pdf .
-يختار مكان الحفظ .


هذا ما يقوم به المستخدم العادي، وكل هذه بالنسبة للغة البرمجة تعتبر أحداث تتلوها عمليات, هناك ميزات يتيحها لك المتصفح للقيام بذلك برمجياً عن طريق ال  shell أو موجه الأوامر وطالما أن العملية تتم بشكل آمن وطبيعي فلن يعترض النظام على تنفيذها (وقد يكون مسرورا وشاكراً لك).


أحدهم يسأل  انا لا أريد أن استخدم chrome هل يوجد حل آخر ؟

نعم يمكنك استخدام #wkhtmltopdf هل يبدوا هذا الاسم غامضاً أو أقرب إلى الشعوذة؟

لا تخف فهو و أخ له يدعى wkhtmltoimage ليسا سوى أداتان مفتوحتا المصدر(LGPLv3) تعتمد على موجه الأوامر لتحويل html إلى pdf أو صورة .
ولكي تستخدمهما سيتحتم عليك أن تقوم بتنصيبها أولاً من الموقع الرسمي https://wkhtmltopdf.org على جهازك او على السيرفر ولسمتخدمي الويندوز بعد التنزيل قم باضافة مسار التنزيل (C:\Program Files\wkhtmltopdf\bin)  أو المسار الذي قمت بتنزيل المكتبة عليه إلى متغيرات البيئة (environment variables ) .


هل تتذكر FFI وتسأل عن علاقتها بكل الموضوع ؟ وهل تحب استخدام مكتبة c .
 تتوفر المكتبة ايضا  بصيغة C زور الموقع ونزل المكتبة واستخدمها كما تحب.


وبعد ما قمت بالتنزيل يمكنك أن تجرب الأمر  من الcmd 

wkhtmltopdf https://droub.net droub.pdf

ستلاحظ أنه قام بتحويل موقع دروب أو أي موقع قمت بكتابته الى ملف pdf بإسم droub.pdf أليس ذلك رائعاً ؟

بلى بلى.


السؤال الأهم : كيف استخدمها عن طريق ال  php ؟
 عليك أن تلقي نظرة على هذا الرابط : https://www.php.net/manual/en/ref.exec.php فيه مجموعة من دوال الshell التي تقوم بتنفيذ عمليات عن طريق النظام.

 سأورد هذا المثال البسيط للزميل Piotr Horzycki :

// we will send HTML contents to STDIN and save PDF output to a file

$process = popen('wkhtmltopdf - output.pdf', 'w');
fwrite($process, $html);
pclose($process);


- ايضاً يمكنك أن تستخدم  symfony process للمزيد يمكنك الإطلاع على الرابط https://symfony.com/doc/current/components/process.html
بالمناسبة الأداة تأتي مضمنة في laravel  وهذا مثال للإستخدام:

$process = new Process['wkhtmltopdf', '-', '-']);
$process->setInput($veryLongHtml);
$process->start();
$pid = $process->
getPid();
// do some other things here...
$process->wait();
echo $process->
getOutput();



كل هذه رؤوس أقلام وإن أردت المزيد هذا رابط مقال قم بزيارته بعد أن تكمل المقال وتختار ما يناسبك https://peterdev.pl/execute-a-shell-command-in-php/

هل أحببت موضوع السيناريو الذي تحدثنا عنه في بداية المقال ويتم فيه  فتح المتصفح وعمل حفظ وتريد حل مشابه يستخدم هذه الطريقة ؟


حاضر حواضر،طلباتك أوامر ، نقدم لك : Chrome PHP  وما هذه ؟
هذه مكتبة تستخدم chrome headless إن لم تتعرف عليه وقمت بترجمته في جوجل سيخبرك أنه( مقطوع الرأس 😅) هناك أيضاً firefox headless.

 سوف أوضح لك الموضوع حيث أن الإخوة في جوجل قدموا لنا معشر المبرجمين طريقة للتعامل مع جوجل كروم عن طريق موجه الأوامر او برمجيا. ويمكنك تنفيذ كل ما يتم تنفيذه في المتصفح العادي.  وقد قام Graham Campbell  تجهيز باكج الذي قد يساعدك في تنفيذ ذلك عن طريق ال php

رابط الباكج  https://github.com/chrome-php/chrome :

للتنزيل عن طريق الكمبوزر :

$ composer require chrome-php/chrome

مثال :

use HeadlessChromium\BrowserFactory;

$browserFactory = new BrowserFactory();

// starts headless chrome
$browser = $browserFactory->createBrowser();

try {
    // creates a new page and navigate to an url
    $page = $browser->createPage();
    $page->navigate('http://droub.net')->waitForNavigation();

    // get page title
    $pageTitle = $page->evaluate('document.title')->getReturnValue();

    // screenshot - Say "Cheese"! 😄
    $page->screenshot()->saveToFile('/droub.png');

    // pdf
    $page->pdf(['printBackground' => false])->saveToFile('/droub.pdf');
} finally {
    // bye
    $browser->close();
}


تم تطبيق الأمثلة السابقة وغيرها ورفعها على الجيت هب يمكنك الإطلاع عليها من خلال الرابط https://github.com/Ab-Alselwi/laravel-pdf-generate-examples

تم تنفيذ الأمثلة باستخدام :
  • wkhtmltopdf
  • php shell
  • symfony process
  • باكج chrome-php
  • ويوجد أيضاً أمثلة أخرى . 

قم بتنزيل الملفات ومن ثم نفذ الأمر التالي : clone the repostory and by composer run

$ composer install

ثم بعدها

$ php artisan serve

الروابط التي يمكنك الانتقال اليها عن طريق المتصفح :

  • 127.0.0.1:8000/ باستخدام HeadlessChromium
  • 127.0.0.1:8000/runProsses باستخدام runProsses by php shell
  • 127.0.0.1:8000/symfonyProcess باستخدام symfonyProcess with wkhtmltopdf library
  • 127.0.0.1:8000/phpchromepdf باستخدام dawood\phpChrome\Chrome package

وغيرها يمكنك الإطلاع عليها في الكود route/web.php, HomeController


أتمنى أن يكون الشرح واضح  .


والسلام عليكم .



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