baidouabdellah / laravel-arpdf
Generate Arabic-friendly PDFs in Laravel with a driver-based architecture (mPDF by default)
3.0.0
2026-03-06 15:27 UTC
Requires
- php: ^8.0
- chillerlan/php-qrcode: ^5.0
- illuminate/support: ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0
- mpdf/mpdf: ^8.2
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0
- phpunit/phpunit: ^10.5 || ^11.0
README
Laravel ArPDF
Arabic-first PDF generation for Laravel, rebuilt from scratch on top of mPDF.
laravel-arpdf is designed for production-grade Arabic documents (invoices, contracts, reports) with stable RTL rendering, Arabic shaping, and robust font handling.
Why This Is Stronger Than Dompdf
- Native mPDF engine focused on complex scripts (Arabic/RTL)
- Better Arabic glyph shaping and bidirectional text handling
- Reliable custom font loading and fallback strategy
- Rich PDF controls: metadata, margins, header/footer, watermark
Core Features
- Full Arabic + RTL + UTF-8 support
- Fluent Laravel API
- Custom Arabic fonts via config map
stream,download,save, and rawstringoutput- Header / footer HTML
- Text or image watermark
- Metadata API (
title,author,subject,keywords,creator) - Reusable document profiles (
profile('invoice_ar')) - Named templates with variable interpolation
- Layouts and reusable components for templates
- Report Builder DSL for business reports
- File queue pipeline for deferred rendering
- Laravel queue pipeline (
dispatch/dispatchSync) - Plugin API (before/after render hooks)
- Plugin marketplace with named built-ins (
watermark_text,signature_block,quick_qr,certificate_signature) - Snapshot testing workflow for PDF regression checks
- PDF render cache for repeated documents
Installation
composer require baidouabdellah/laravel-arpdf
Publish config and fonts (optional but recommended):
php artisan vendor:publish --provider="Baidouabdellah\LaravelArpdf\ArPDFServiceProvider"
Quick Example
use ArPDF; public function invoice() { return ArPDF::direction('rtl') ->title('فاتورة') ->author('My Company') ->header('<div style="text-align:right">رأس الصفحة</div>') ->footer('<div style="text-align:center">{PAGENO}</div>') ->watermarkText('سري') ->loadView('pdf.invoice', ['title' => 'فاتورة']) ->download('invoice.pdf'); }
Production Features
ArPDF::profile('invoice_ar') ->registerTemplate('invoice_basic', '<h1>{{ title }}</h1><p>{{ customer.name }}</p>') ->loadTemplate('invoice_basic', [ 'title' => 'فاتورة', 'customer' => ['name' => 'أحمد'], ]) ->useCache(true, 3600) ->download('invoice.pdf');
Layouts, Components, Reports, Queue
$pdf = app(\Baidouabdellah\LaravelArpdf\ArPDF::class); $pdf->registerLayout('base', '<html><body>{{ section:header }}{{ content }}{{ component:footer }}</body></html>') ->registerComponent('footer', '<footer>{{ company }}</footer>') ->registerTemplate('invoice', \"@layout('base')\\n@section('header')<h1>{{ title }}</h1>@endsection\\n<p>{{ customer.name }}</p>\") ->loadTemplate('invoice', [ 'title' => 'فاتورة', 'customer' => ['name' => 'أحمد'], 'components' => ['footer' => ['company' => 'My Co']], ]); $pdf->report(function ($r) { $r->heading('تقرير شهري')->table(['البند', 'القيمة'], [['المبيعات', 15000]]); }); $pipeline = $pdf->queuePipeline(); // file-based queue $jobId = $pipeline->enqueue($pdf, storage_path('app/reports/monthly.pdf')); $pipeline->processNext(); $pdf->laravelQueuePipeline()->dispatchSync($pdf, storage_path('app/reports/sync.pdf'));
Plugins & Snapshots
use Baidouabdellah\LaravelArpdf\Contracts\PdfPlugin; class FooterPlugin implements PdfPlugin { public function beforeRender($pdf, string $html, array $options): array { return ['html' => $html . '<footer>Signed</footer>', 'options' => $options]; } public function afterRender($pdf, string $binary, array $context): string { return $binary; } } $pdf->usePlugin(new FooterPlugin())->loadHTML('<h1>Doc</h1>'); $pdf->usePluginNamed('watermark_text', ['text' => 'CONFIDENTIAL', 'alpha' => 0.15]) ->usePluginNamed('signature_block', ['signer' => 'Admin', 'title' => 'CTO']) ->usePluginNamed('quick_qr', ['text' => 'INV-1001', 'size' => 90]) // offline QR ->loadHTML('<h1>Invoice</h1>'); $pdf->usePluginNamed('certificate_signature', [ 'private_key' => storage_path('keys/private.pem'), 'certificate' => storage_path('keys/cert.pem'), 'sidecar_path' => storage_path('app/signatures/invoice.sig.json'), ]); $check = \Baidouabdellah\LaravelArpdf\ArPDF::verifySignature( storage_path('app/invoices/invoice.pdf'), storage_path('app/signatures/invoice.sig.json'), storage_path('keys/cert.pem') ); // Artisan command // php artisan arpdf:verify-signature storage/app/invoices/invoice.pdf storage/app/signatures/invoice.sig.json --cert=storage/keys/cert.pem $result = $pdf->assertSnapshot('doc-v1'); // stores/compares sha256 snapshot if (! $result['matched']) { // regression detected }
Output Destinations
output($filename, $dest) supports:
- Legacy:
I,D,F,S - Named:
inline,download,file,string
Configuration
Main options in config/arpdf.php:
direction,default_font,fonts_path,fontspaper,orientation,marginsmetadatampdf(native mPDF overrides)
Testing
vendor/bin/phpunit -c tests/phpunit.xml
License
MIT
