برای ساخت فایل های pdf در لاراول چند پکیج مختلف را آزمایش کردم. به این نتیجه رسیدم که پکیج laravel-pdf بهترین انتخاب برای ساخت pdf با فونت فارسی است.
اینجا روش درست کردن یک فایل pdf از روی سند html با این پکیج را توضیح میدهم.
اول از همه لاراول را نصب میکنیم
composer create-project laravel/laravel pdf-creator
پکیج niklasravnsborg/laravel-pdf را نصب میکنیم.
composer require niklasravnsborg/laravel-pdf
وارد فایل config/app.php
شوید.
به آرایه providers این عبارت را اضافه کنید.
'providers' => [
// ...
niklasravnsborg\LaravelPdf\PdfServiceProvider::class
]
به آرایه aliases هم این یکی را
'aliases' => [
// ...
'PDF' => niklasravnsborg\LaravelPdf\Falanguage-phpcades\Pdf::class
]
برای ساخت pdf به یک فایل view نیاز داریم. در این فایل view باید صفحه ای که قرار است به pdf تبدیل شود را با استفاده از html و css بسازیم.
من یک view آزمایشی در resources/views درست کردم به اسم pdf-template.blade.php :
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>فایل پی دی اف ساخته شده با لاراول</title>
<style>
@font-face{
font-family: 'samim';
src: url('../../public/fonts/Samim.eot'),
url('/../../fonts/Samim.woff'),
url('/../../fonts/Samim.woff2'),
url('/../../fonts/Samim.ttf');
}
body {
direction: rtl;
font-family: 'samim';
}
*{
direction: rtl;
}
html {
font: 14px/1.5 Arial, sans-serif;
}
body {
background: rgb(231, 231, 231);
padding: 0 20px;
width: 920px;
margin: 0 auto;
}
p{
font-size: 16px;
}
.main-title {
text-align : center;
margin-top: 20px;
}
.paragraph {
text-align: right;
}
.img-container{
text-align: center;
}
table, th, td{
border: 2px solid;
}
table{
border-collapse: collapse;
margin-left: auto;
margin-right:auto;
margin-bottom: 15px
}
table th, td{
padding: 25px
}
</style>
</head>
<body>
<h1 class="main-title">فایل پی دی اف نمونه</h1>
<p class="paragraph">
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه
روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف
بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان
را می طلبد تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی و فرهنگ پیشرو در زبان
فارسی ایجاد کرد. در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها و شرایط سخت تایپ به
پایان رسد وزمان مورد نیاز شامل حروفچینی دستاوردهای اصلی و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد
استفاده قرار گیرد.
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه
روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف
بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان
را می طلبد تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی و فرهنگ پیشرو در زبان
فارسی ایجاد کرد. در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها و شرایط سخت تایپ به
پایان رسد وزمان مورد نیاز شامل حروفچینی دستاوردهای اصلی و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد
استفاده قرار گیرد.
</p>
<div class="img-container">
<img class="image" src="{{asset('sample.png')}}" alt="">
</div>
<h2>فهرست ها</h2>
<ul>
<li>لورم ایپسوم
</li>
<li>
لورم ایپسوم
</li>
<li>
لورم ایپسوم
</li>
<li>
لورم ایپسوم
</li>
<li>
لورم ایپسوم
</li>
</ul>
<div style="text-align: center">
<table >
<thead>
<tr>
<th>عنوان اول</th>
<th>عنوان دوم</th>
<th>عنوان سوم</th>
<th>عنوان چهارم</th>
</tr>
</thead>
<tbody>
<tr>
<td>محصول 1</td>
<td>محصول 2</td>
<td> نحصول 3</td>
<td> محصول 4</td>
</tr>
<tr>
<td>لورم</td>
<td>ایپسوم</td>
<td> متن ساختگی</td>
<td> برای طراحی وب</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
برای فونت فارسی هم فونت رایگان صمیم را اضافه کردم.
صفحه html ای که ساختیم این شکلی خواهد شد:
الان باید این صفحه html به pdf تبدیل شود.
پس یک مسیر هم برای این کار میسازیم:
Route::get('/create-pdf',[PDFController::class,'CreatePDF']);
یک کنترلر ساختم به نام PDFController که وظیفه ساخت فایل پی دی اف را بر عهده دارد. همه کدهای مربوط به تبدیل html به pdf را اینجا مینویسیم.
داخل متد createPDF کدهای زیر را نوشتم تا کار تبدیل به پی دی اف را انجام دهند.
use PDF;
class PDFController extends Controller
{
public function CreatePDF(){
$pdf = PDF::loadView('pdf-template');
return $pdf->download('sample.pdf');
}
}
با استفاد از facade این کتابخانه، به نام PDF و متد loadView، یک شی میسازیم. داخل متد loadView آدرس view ای که ساخته بودیم را مینویسیم.
درنهایت با متد download فایل pdf را به کاربر تحویل میدهیم.
اگر می خواهید زبان فارسی در pdf به درستی نمایش داده شود، مطمئن شوید این متا تگ charset=utf-8
در داخل تگ head سند html وجود داشته باشد:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
حالا اگر به url مسیری که ساخته بودیم بروید فایل pdf برای شما دانلود میشود.
فایل pdf به درستی ایجاد شده اما یک مشکل دارد. آن هم اعمال نشدن فونت فارسی است. ما در html فونت صمیم را اضافه کردیم اما در فایل pdf این فونت را نمیبینیم.
برای حل مشکل فونت، اول باید فایل config پکیج را منتشر کنیم.
php artisan vendor:publish --provider="niklasravnsborg\LaravelPdf\PdfServiceProvider"
در پوشه configs یک فایل به نام pdf.php ایجاد میشود. داخل این فایل همه تنظیماتی که برای ساخت یک فایل پیدیاف می توانید اعمال کنید قرار گرفته است.
برای اینکه فونت فارسی به درستی نمایش داده شود باید دو مقدار به این قسمت اضافه کنیم:
return [
//...
'font_path' => base_path('resources/fonts/pdf-fonts/'),
'font_data' => [
'samim' => [
'R' => 'Samim.ttf',
'B' => 'Samim-bold.ttf' //optional
'useOTL' => 0xFF,
'useKashida' => 75,
],
]
];
مقدار font_path آدرس پوشهای است که در آن فونت های مورد استفاده قرار دارد.
مقدار بعدی font_data است که اطلاعات فونت استفاده شده باید به شکل یک آرایه اینجا قرار بگیرد.
R یعنی حالت regular فونت. پس اسم فایل فونت در حالت regular را مینویسیم. برای فونت bold هم میتوانیم یک عضو دیگر به این آرایه اضافه کنیم به اسم B که البته اختیاری است.
دقت داشته باشید که حتما فرمت ttf فونت را برای pdf استفاده کنید.
دو عضو دیگر یعنی useOTL و useKashida به همان شکلی که در کد بالا نوشته شده بنویسید.
حالا یک بار دیگر مسیرcreate-pdf/
را در مرورگر اجرا کنید. با انجام این تنظیمات باید فونت به درستی نمایش داده شود.
چطور دیتای دلخوهمان را به فایل pdf پاس بدهیم؟
فایلی که الان ساختیم استاتیک بود و اطلاعات متغیر نداشت. برای این که فایل های pdf داینامیک درست کنیم. می توانیم به عنوان پارامتر دوم اطلاعاتی که از دیتابیس گرفتیم را به متد loadView پاس بدهیم تا در view به آن دسترسی داشته باشیم.
namespace App\Http\Controllers;
use PDF;
class PDFController extends Controller
{
public function CreatePDF(){
$data = Order::all();
$pdf = PDF::loadView('pdf-template',$data);
return $pdf->stream();
}
}
استایل دهی به فایل pdf
این پکیج، استایل های css ای که نوشتیم را میخواند و در فایل pdf پیاده سازی میکند. اما یک سری محدودیت دارد. برای اینکه مطمئن شوید استایل هایی که استفاده می کنید توسط پکیج پشتیبانی می شود به مستندات پکیج mpdf مراجعه کنید. چون پکیج laravel-pdf فقط یک wrapper روی پکیج mpdf است.
نکته مهم: به هیچ وجه برای استایل دهی فایل pdf از فریمورکهای css استفاده نکنید. مخصوصا بوتسترپ که باعث میشود فرایند ساخت پیدیاف با مشکل و کندی شدید مواجه شود. چون عملا مجبورید کل بوتسترپ را برای ساخت یک صفحه لود کنید. استایل صفحاتی که قرار است به pdf تبدیل شود را با css خام بنویسید.