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
