Laravel’da PDF oluşturmak, hangi problemi sahiplenmek istediğinizi seçmek demektir. dompdf, CSS’yi 2011 gibi yazmanıza zorlar. Snappy, sizi terkedilmiş bir ikiliye bağlar. Browsershot ise güzel bir şekilde PDF’lerinizi oluşturur ve PHP sunucunuzu bir Node ve Chrome host’una dönüştürür.
Dördüncü bir seçenek daha var: Blade görünümünüzü tarayıcıda olduğu gibi render etmek, HTML’yi bir API’ye POST edip gerçek bir vektör PDF almak. Bu makale, üç geleneksel seçeneğin neden sorun çıkardığını ve API yolu ile uygulamanın pratikte nasıl göründüğünü ele alıyor.
dompdf’nin Zayıf Yönleri
dompdf’nin Zayıf Yönleri
dompdf, saf bir PHP render motorudur ve bu yüzden insanlar bunu tercih eder: composer require ile başlar ve doğrudan PDF’ler üretirsiniz. Fakat bunun bedeli render motorunun kısıtlılığıdır. dompdf, CSS 2.1 ile kısmi CSS3 katmanını uygular ve bu limit, onun üzerine inşa ettiğiniz her şeyi şekillendirir.
Flexbox yok. Grid yok. Float’lar genellikle çalışır, bu yüzden internetteki her dompdf fatura şablonu float ve tablodan oluşur. Web fontları, yalnızca çalışmak yerine font yükleyici ile kaydedilmelidir. Ve JavaScript motoru olmadığı için, görünümünüzün istemci tarafında hesapladığı her şey gerçekleşmez.
Pratikte bu, stillerinizin iki farklı versiyonunu oluşturur. Uygulamanızda gerçekten kullanılan bir stil sayfası ve PDF’ler için ikinci bir, daha kötü bir stil sayfası vardır; bu ikisi her tasarım değişikliğinde ayrılır. Müşterinizin web’de gördüğü fatura ile e-postalarına ekli olan farklı uygulamalardır.
Snappy Terkedilmiş Bir Motoru Sarıyor
Snappy Terkedilmiş Bir Motoru Sarıyor
laravel-snappy, wkhtmltopdf’yi kullanarak gerçek bir tarayıcı motoru ile render yapar. Ancak, hangi motorun kullanıldığı sorunu ortaya çıkar: 2012 civarına kadar donmuş bir Qt WebKit yapısıdır ve şimdi arşivlenmiş, bakımı yapılmamaktadır.
Bu motor, CSS grid’den önceki bir zamana aittir ve yalnızca antik 2009 flexbox sözdizimini destekler. Özel nitelikler yoktur. Güvenlik güncellemeleri projenin durmasıyla birlikte sona erdi. Daha önce wkhtmltopdf sorununu detaylı bir şekilde ele aldık, ama Laravel için özet şu: Modern CSS’inizi yanlış yorumlayabilen on yıl önceki bir tarayıcı için sunucunuza bir ikili derlemektesiniz.
Browsershot Altyapınızda Doğru Bir Şekilde Render Ediyor
Browsershot Altyapınızda Doğru Bir Şekilde Render Ediyor
Browsershot render sorununu düzgün bir şekilde çözüyor. Puppeteer üzerinden headless Chrome’u çalıştırarak flexbox, grid, özel nitelikler ve web fontları tam olarak tarayıcınızda olduğu gibi çalışır.
Ancak maliyeti operasyondur. Laravel sunucunuz artık Node, Puppeteer ve Chrome ikilisini, versiyon uyumlarını korumak zorundadır. Bu, kontrol ettiğiniz bir sunucuda sorun değil. Ancak paylaşımlı hostingde baş ağrısı, sunucusuzda bir savaş ve PDF hacmi arttığında gerçek bir operasyon yükü haline gelir. Aynı problemi resim render işlemi için Browsershot makalemizde belirttik; PDF’ler bunun hepsini miras alır.
Blade Görünümünü Render Et, POST Et, PDF Al
Blade Görünümünü Render Et, POST Et, PDF Al
HTML to PDF API yolu Chrome’un renderını korur ve Chrome’u sunucunuzdan kaldırır. Görünümünüzü bir dizeye render eder, format: "pdf" ile gönderir ve bitmiş belgeye bir URL alırsınız:
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders([
'X-API-Key' => config(),
])->post(, [
=> view(, [=> $invoice])->render(),
=> ,
]);
$url = $response->json();
// https://i.html2img.com/image-....pdf
Yanıt, bir resim render ile aynı JSON zarfıdır, dosya gerçek bir vektör PDF’dir ve diğer tüm renderler gibi bir krediye mal olur. Metin seçilebilir ve arama yapılabilir kalır, web fontları gömülüdür ve uzun içerikler otomatik olarak A4 sayfaları arasında pagine edilir. Renderleme, güncel Chrome’da gerçekleştiği için, stil sayfası zaten uygulamanızda kullanmakta olduğunuz stil sayfasıdır. İki farklı versiyon yok.
Ya da Laravel Paketini Kullanın
Ya da Laravel Paketini Kullanın
Versiyon 1.1’den itibaren, Laravel paketi, aynı seçeneği bir enum olarak sunar:
composer require html2img/html2img-laravel
use Html2img\Enum\Format;
use Html2img\Laravel\Facades\Html2img;
use Html2img\Request\HtmlRequest;
$response = Html2img::html(new HtmlRequest(
: view(, [=> ])->render(),
: Format::Pdf,
));
= Html2img::store(, $invoice->number});
Html2img::store(), tamamlanan PDF’yi uygulamanızın yapılandırdığı herhangi bir dosya sistemi diskine (S3 dahil) kaydeder, ki genellikle bir faturanın sonuçlanması gereken yerdir.
Mailable’a Ekleyin
Mailable’a Ekleyin
Laravel PDF’lerinin en yaygın hedefi bir e-posta. Dosya bir diske kaydedildikten sonra, eklenmesi Mailable içinde bir satırdır:
use Illuminate\Mail\Mailables\Attachment;
public function attachments(): array
{
return [
Attachment::fromStorage($this->invoice->number})
->withMime(),
];
}
Eğer faturayı e-posta içinde ek yerine çevrimiçi göstermek istiyorsanız, PNG olarak render edin ve format parametresini atlayın. Aynı görünüm, iki çıktı.
PDF’nin Ne Olduğunu Bilin
PDF’nin Ne Olduğunu Bilin
HTML yapınızı buna göre ayarlamak önemlidir. Sayfalar A4 dikeydir ve içerik sayfa genişliğine göre akış yapar, bu yüzden width, height, dpi, fullpage ve selector PDF modunda işlevsizdir. Belge normal ekran CSS’inizle renderlenir, bu da anlamına geliyor ki PDF, bir resim render’ı gibi tam olarak görünür. Görünümü, sabit piksel boyutlarına göre değil, bir belge gibi akacak şekilde yazın ve sayfalama kendiliğinden halledilecektir. format parametre belgeleri tam davranışı kapsar.
Büyük belgeler için, bir webhook_url ekleyin, biz de tamamlanan URL’yi POST olarak size göndereceğiz ve isteğinizi açık tutmak yerine doğal olarak bir kuyruk işine bağlanacaksınız.
Özellikle Blade görünümünden faturalar, sertifikalar veya raporlar almak istiyorsanız, sayfanızda bir tarayıcı olmadan, şablonlar galerisini gözden geçirin veya belgelere göz atın ve başlayın.
Bugün Laravel’da PDF’leri nasıl oluşturuyorsunuz? Kurulumunuzu aşağıdaki yorumlarda paylaşın.
Kaynak: Orijinal Makale


