HTML'den PDF'e Dönüştürme: Basit Yazdırmadan Otomasyona
HTML'yi kaliteli bir şekilde PDF'e dönüştürmek için yöntemi görevinize göre seçin: tek seferlik belgeler için tarayıcıdaki "Yazdır" işlevini kullanın (Ctrl+P → PDF olarak Kaydet), otomatik rapor veya fatura oluşturma için ise headless tarayıcılar (Puppeteer/Playwright) veya özel kütüphaneler (WeasyPrint, PrinceXML) uygulayın. Başarının anahtarı, @media print CSS kurallarının doğru ayarlanması ve yazı tipi yönetimidir.
Aşağıda temel dönüştürme yöntemlerini, baskı için düzenleme teknik detaylarını ve tipik hataların çözüm yollarını inceleyeceğiz.
İçindekiler
Dönüştürme Yöntemleri: Hangi Aracı Seçmeli
Aracın seçimi; görev hacmine, düzen kalitesi gereksinimlerine ve otomasyon ihtiyacına bağlıdır.
1. Tarayıcı Çıktısı (Manuel Mod)
Tek bir sayfayı kaydetmek için en basit yöntemdir.
- Nasıl Kullanılır: Sayfayı Chrome, Edge veya Firefox'ta açın,
Ctrl+P(Mac'teCmd+P) tuşlarına basın ve "PDF olarak Kaydet" seçeneğini belirleyin. - Avantajları: Yazılım kurulumu gerektirmez, modern CSS ve JavaScript'i destekler.
- Dezavantajları: Toplu dönüştürmeyi otomatikleştirmek imkansızdır; sonuçlar farklı tarayıcılarda değişiklik gösterebilir.
2. Headless Tarayıcılar (Puppeteer, Playwright)
Geliştiriciler için endüstri standardıdır. Bu araçlar, grafiksel arayüz olmadan bir tarayıcı çalıştırır ve sayfayı programlı olarak kaydeder.
- Kimler İçin: Fatura, bilet veya rapor üreten web uygulamaları için.
- Avantajları: Mükemmel render kalitesi (gerçek Chrome/WebKit motoru kullanıldığı için), JS üzerinde tam kontrol ve içerik yüklenmesini bekleme imkanı.
- Dezavantajları: Sunucu kaynakları gerektirir, ortam kurulumu daha karmaşıktır.
3. Özel Kütüphaneler (WeasyPrint, wkhtmltopdf, PrinceXML)
HTML/CSS'yi PDF'e dönüştürmek için özel olarak oluşturulmuş araçlardır.
- WeasyPrint (Python): Modern CSS ile mükemmel çalışır, hafiftir.
- PrinceXML: Karmaşık tipografi ve Paged Media standartları için en iyi desteğe sahip ticari çözüm.
- wkhtmltopdf: Eski Qt WebKit tabanlı eski bir çözüm. Modern CSS (Flexbox/Grid) desteği zayıf olduğu için yeni projelerde önerilmez.
Baskı İçin HTML ve CSS Hazırlığı
PDF statik bir format olduğundan, web sayfasındaki dinamik öğelerin uyarlanması gerekir.
@media print Kullanımı
PDF'e özgü tüm stiller bir medya sorgusu içine alınmalıdır. Bu, gereksiz öğeleri (menüler, alt bilgiler, düğmeler) gizlemeye ve metni optimize etmeye olanak tanır.
@media print {
/* Navigasyon ve reklamları gizle */
nav, .ads, .no-print {
display: none !important;
}
/* Belge gövdesini yapılandır */
body {
font-size: 12pt;
color: #000;
background: #fff;
}
/* Gerekli yerlerde sayfa sonlarını garanti et */
h1, h2, h3 {
page-break-after: avoid;
}
table {
page-break-inside: auto;
}
tr {
page-break-inside: avoid;
page-break-after: auto;
}
}
@page ile Sayfa Boyutlarının Ayarlanması
Kenar boşluklarını ve kağıt boyutunu kontrol etmek için @page kuralını kullanın:
@page {
size: A4;
margin: 2cm;
}
Puppeteer kullanıyorsanız, kenar boşluğu ayarlarını page.pdf() yönteminde programlı olarak iletebilirsiniz; bu, CSS stillerine göre önceliklidir.
Sık Yapılan Hatalar ve Çözümleri
Güçlü araçlar kullanılsa bile, dönüştürme işlemi genellikle düzenleme nüansları nedeniyle bozulur.
1. Sayfa Sonlarında Kesilen İçerik
Sorun: Metin veya görüntü, yeni sayfaya geçerken ortadan ikiye bölünür.
Çözüm: break-inside, page-break-inside ve orphans/widows özelliklerini kullanın.
.card, .table-row {
break-inside: avoid; /* Öğenin bölünmesini engeller */
}
p {
orphans: 3; /* Sayfanın altındaki minimum satır sayısı */
widows: 3; /* Yeni sayfanın başındaki minimum satır sayısı */
}
2. Yazı Tiplerinin Eksikliği veya Bozuk Karakterler
Sorun: PDF'de özel yazı tipleri yerine standart yazı tipleri kullanılır veya semboller hatalı görüntülenir. Neden: Yazı tipleri yüklenmemiştir veya yolları render motoru tarafından erişilemez durumdadır. Çözüm:
- Yazı tipi dosyalarına mutlak yollar kullanın.
- Puppeteer'da yazı tipi yükleme olayını bekleyin:
await page.evaluateHandle('document.fonts.ready'). - WeasyPrint için yazı tiplerinin sisteme yüklü olduğundan veya doğru URL'lerin belirtildiğinden emin olun.
3. Boş PDF veya JS İçeriğinin Eksikliği
Sorun: AJAX/Fetch üzerinden yüklenen veriler dosyaya dahil edilmemiştir. Neden: Dönüştürme, API isteği tamamlanmadan önce başlamıştır. Çözüm:
- Headless tarayıcılarda açık beklemeler (
waitForSelector,waitForNetworkIdle) kullanın. - Sadece
DOMContentLoadedolayına güvenmeyin, çünkü bu asenkron verileri beklemaz.
4. Arka Plan Renkleri ve Görüntüleriyle İlgili Sorunlar
Sorun: Öğelerin arka planları PDF'de kaybolmuştur. Neden: Tarayıcılar varsayılan olarak mürekkepten tasarruf eder ve arka planları yazdırmaz. Çözüm:
- CSS'e şunu ekleyin:
-webkit-print-color-adjust: exact; print-color-adjust: exact;. - Puppeteer ayarlarında
printBackground: truebayrağını etkinleştirin.
Popüler Araçların Karşılaştırılması
| Araç | Dil/Ortam | CSS Kalitesi | Kurulum Zorluğu | Maliyet |
|---|---|---|---|---|
| Chrome Print | Herhangi biri (UI) | Yüksek | Düşük | Ücretsiz |
| Puppeteer | Node.js | Yüksek | Orta | Ücretsiz |
| Playwright | Node/Py/.NET | Yüksek | Orta | Ücretsiz |
| WeasyPrint | Python | İyi | Düşük | Ücretsiz (AGPL) |
| PrinceXML | CLI/API | Mükemmel | Düşük | Ücretli Lisans |
| wkhtmltopdf | CLI | Eskimiş | Düşük | Ücretsiz |
Modern projeler için wkhtmltopdf kullanımından kaçının. CSS Grid, Flexbox ve birçok modern özelliği desteklemez, bu da bozuk düzenlere neden olur.
SSS
Sonuç PDF dosyasının boyutu nasıl küçültülür? HTML'ye eklemeden önce görüntüleri optimize edin (fotoğraflar için PNG yerine JPEG/WebP kullanın). Puppeteer'da çıktı kalitesi düşürülebilir, ancak bu metin netliğini etkiler. Kullanılmayan yazı tiplerini kaldırın ve yalnızca gerekli kalınlıkları bırakın.
Üstbilgi/altbilgi (header/footer) eklenebilir mi?
Evet. Puppeteer'da bu, HTML işaretlemesinin iletildiği headerTemplate ve footerTemplate parametreleri aracılığıyla yapılır. Yazıcılar için CSS'de, @page kuralı içinde @top-center, @bottom-right kullanılabilir, ancak bu özelliğin desteği farklı render motorlarında değişkenlik gösterir.
URL yerine HTML dizesi nasıl dönüştürülür?
Puppeteer'da page.setContent(htmlString) kullanın. WeasyPrint'te dizeyi doğrudan HTML(string=html_content) yapıcısına iletin. Bu sırada, kaynaklara (görüntüler, stiller) yönelik göreli yolların mutlak yollara veya base64'e dönüştürüldüğünden emin olun.
Çevrimiçi dönüştürücüler kullanmak güvenli midir? Herkese açık veriler için evet. Kişisel veriler, faturalar veya dahili belgeler için hayır. Verileri yabancı bir sunucuya göndermiş olursunuz. Gizli bilgiler için her zaman yerel kütüphaneleri veya kendi sunucu çözümlerinizi kullanın.