HTML ve XML'i PDF'e Dönüştürme Kapsamlı Rehberi
Web içeriğinin PDF'e dönüştürülmesi; raporlar, faturalar, arşivler ve tarayıcıdan bağımsız belgeler oluşturmak için gereklidir. HTML sayfaları için headless tarayıcılar (Chrome/Puppeteer) en etkili çözümlerdir, XML verileri için ise XSL-FO üzerinden dönüşüm veya ara HTML oluşturma yöntemleri kullanılır. Aracı seçimi, düzenin karmaşıklığına ve görüntüleme doğruluğu gereksinimlerine bağlıdır.
Bu makalede temel yaklaşımları inceleyecek, popüler kütüphaneleri karşılaştıracak ve mükemmel sonuç için stil ayarlarına ilişkin öneriler sunacağız.
Kısa cevap: Tek bir sayfayı hızlıca kaydetmeniz gerekiyorsa tarayıcıdaki «PDF olarak yazdır» özelliğini kullanın. HTML'den otomatik ve toplu belge üretimi için Puppeteer veya Playwright tercih edin. XML verilerinden titiz tipografik çıktı almak için XSL-FO + Apache FOP kombinasyonunu kullanın.
Web içeriğini neden PDF'e dönüştürmeliyiz?
Değişmezliği sayesinde PDF, belge yönetimi için fiili standart olmaya devam ediyor. Başlıca kullanım senaryoları şunlardır:
- Arşivleme ve hukuki geçerlilik: Bir web sayfasının veya işlemin belirli bir andaki durumunun sabitlenmesi.
- Çevrimdışı erişim: Kullanıcılar, orijinal biçimlendirmeyi koruyarak materyalleri internet olmadan okuyabilir.
- Markalama: Normal HTML görüntülemede uygulanması zor olan logolar, üst/alt bilgiler ve kurumsal fontların eklenmesi.
- Raporlamada standardizasyon: Dağınık verilerin (API'lerden, XML/JSON formatındaki veritabanlarından) tek bir okunabilir formata dönüştürülmesi.
Dönüşüm yöntemleri: Basitten karmaşığa
Teknoloji seçimi, veri kaynağına (HTML veya XML) ve görev hacmine bağlıdır.
1. Tarayıcıyla Yazdırma (Manuel Mod)
Tek seferlik görevler için en basit yöntem.
- Nasıl çalışır:
Ctrl+P(veyaCmd+P) → «PDF olarak kaydet». - Avantajlar: Yazılım kurulumu gerektirmez, görsel kontrol sağlar (WYSIWYG).
- Dezavantajlar: Otomatikleştirilemez, karmaşık sayfaların düzeni sıklıkla bozulur, sayfa sonlarına müdahale edilemez.
2. Headless Tarayıcılar (HTML → PDF)
Modern web geliştirme için altın standart.
- Araçlar: Puppeteer, Playwright, Selenium.
- Nasıl çalışır: Gizli bir Chrome/Chromium örneği başlatılır; sayfa normal bir tarayıcı gibi render edilir ve PDF olarak dışa aktarılır.
- Avantajlar: Modern CSS (Flexbox, Grid), JavaScript ve web fontlarının tam desteği. Yüksek doğrulukta yeniden üretim.
- Dezavantajlar: Sunucu kaynakları (CPU/RAM) gerektirir, ortam kurulumu daha karmaşıktır.
3. Özel Motorlar (HTML → PDF)
Tarayıcılara hafif alternatifler.
- Araçlar: wkhtmltopdf (eskimekte ancak popüler), WeasyPrint (Python), PrinceXML (ticari).
- Avantajlar: Headless tarayıcılardan daha hızlı, entegrasyonu daha kolay. WeasyPrint, CSS Paged Media ile mükemmel çalışır.
- Dezavantajlar: JS ve en yeni CSS özelliklerinin sınırlı desteği. wkhtmltopdf eski bir WebKit sürümüne dayanır.
4. XML Veri Dönüşümü (XML → FO → PDF)
Kurumsal belge yönetimi için klasik yaklaşım.
- Araçlar: Apache FOP, RenderX XEP.
- Nasıl çalışır: XML verileri XSLT kullanılarak, sayfadaki öğelerin kesin konumunu tanımlayan XSL-FO (Formatting Objects) formatına dönüştürülür. Ardından FO işlemcisi PDF üretir.
- Avantajlar: Tipografi, sayfa sonları ve numaralandırma üzerinde mükemmel kontrol. Web teknolojilerinden bağımsızlık.
- Dezavantajlar: Yüksek giriş eşiği (karmaşık XSL-FO sözdizimi), duyarlılığı sürdürmek zordur.
İpucu: XML verileriniz varsa ancak ekibiniz yalnızca HTML/CSS biliyorsa, XML'i backend'de bir HTML şablonuna dönüştürün ve ardından PDF oluşturmak için Headless tarayıcı kullanın. Bu, XSL-FO öğrenmekten daha hızlıdır.
Araçların Karşılaştırılması
| Araç | Kaynak | Kurulum Zorluğu | CSS/JS Kalitesi | Öneri |
|---|---|---|---|---|
| Puppeteer/Playwright | HTML | Orta | Mükemmel | Modern web uygulamaları ve SPA'lar için |
| WeasyPrint | HTML/CSS | Düşük | İyi (JS yok) | Python projeleri ve statik raporlar için |
| wkhtmltopdf | HTML | Düşük | Orta (eski CSS) | Eski sistemler ve basit sayfalar için |
| Apache FOP | XML (XSL-FO) | Yüksek | Tipografik | Sıkı finansal/hukuki belgeler için |
| PrinceXML | HTML/XML | Orta | Mükemmel | Kusursuz PDF gerektiğinde ve bütçe varsa |
Adım Adım Uygulama
Senaryo 1: HTML'den Otomatik Üretim (Node.js + Puppeteer)
Bu yöntem fatura, bilet veya makale üretimi için uygundur.
- Puppeteer'ı yükleyin:
npm install puppeteer. - Üretim betiğini oluşturun:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Sayfaya gidin veya HTML dizesini yükleyin
await page.goto('https://example.com/invoice/123', { waitUntil: 'networkidle0' });
// PDF oluştur
await page.pdf({
path: 'invoice.pdf',
format: 'A4',
printBackground: true, // Arka plan renkleri için önemli
margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' }
});
await browser.close();
})();
Senaryo 2: XML'in Ara HTML Üzerinden Dönüşümü (Python)
Veriler XML olarak geliyorsa, XSL-FO yazmaktan ziyade bunları HTML'e dönüştürmek daha kolaydır.
- XML verilerinden HTML oluşturmak için bir şablon motoru (Jinja2, Mako) kullanın.
- Yazdırma için CSS uygulayın (
@media print). - HTML'i WeasyPrint veya Playwright aracılığıyla PDF'e dönüştürün.
Sayfa sonlarını yönetmek için örnek CSS:
@media print {
.page-break { page-break-after: always; }
h1, h2 { page-break-after: avoid; } /* Başlıklar sayfanın altında kalmamalı */
table { page-break-inside: auto; }
tr { page-break-inside: avoid; } /* Tablo satırları bölünmemeli */
}
Sık Yapılan Hatalar ve Çözüm Yolları
- Kesilmiş İçerik:
position: fixedveyaabsoluteolan öğeler yazdırma akışından çıkabilir.- Çözüm: Ana kapsayıcılar için
position: relativekullanın veya@pageiçinde açık boyutlar belirleyin.
- Çözüm: Ana kapsayıcılar için
- Font Sorunları: Web fontları üretim sırasında zamanında yüklenmeyebilir.
- Çözüm: Fontları base64 olarak gömün veya betiğin kaynakların tamamen yüklenmesini beklediğinden emin olun (
waitUntil: 'networkidle0').
- Çözüm: Fontları base64 olarak gömün veya betiğin kaynakların tamamen yüklenmesini beklediğinden emin olun (
- Tablo Bölünmeleri: Uzun tablolar satır ortasında bölünebilir.
- Çözüm: Tablo satırları (
<tr>) içinbreak-inside: avoidCSS özelliğini ekleyin.
- Çözüm: Tablo satırları (
- Arka Plan Renkleri Yazdırılmıyor: Tarayıcılar mürekkeplerden tasarruf etmek için varsayılan olarak arka planı kaldırır.
- Çözüm: API'de
printBackground: trueseçeneğini etkinleştirin veya tarayıcı yazdırma iletişim kutusunda «Arka plan grafikleri» kutusunu işaretleyin.
- Çözüm: API'de
Uyarı: PDF oluştururken JavaScript animasyonlarına güvenmeyin. Headless tarayıcılar, animasyon tamamlanmadan önce ekran görüntüsü alabilir; bu da boş bloklara yol açar. Yazdırma modu için animasyonları CSS aracılığıyla devre dışı bırakın.
SSS
wkhtmltopdf ve Puppeteer arasındaki fark nedir? wkhtmltopdf, modern CSS'i (Flexbox/Grid) ve JavaScript'i kötü destekleyen eski bir WebKit motoru kullanır. Puppeteer güncel Chrome'u kullanır; tarayıcıda kullanıcının gördüğüyle tam eşleşme sağlar ancak daha fazla bellek tüketir.
XML'i HTML olmadan doğrudan PDF'e dönüştürmek mümkün mü? Evet, XSL-FO standardı ve Apache FOP gibi işlemciler kullanarak mümkündür. Bu, sayfa düzeni üzerinde daha iyi kontrol sağlar ancak karmaşık FO sözdiziminin öğrenilmesini gerektirir. Çoğu web görevi için XML → HTML → PDF dönüşüm yolu daha kolaydır.
PDF'e sayfa numarası nasıl eklenir?
Yazdırma CSS'inde @page pseudo-elementlerini kullanın:
@page {
@bottom-center {
content: counter(page);
}
}
Bu özelliğin desteği değişkendir: WeasyPrint ve PrinceXML'de mükemmel çalışır, Chrome/Puppeteer'da sınırlıdır (orada genellikle HTML yapısı üzerinden üst/alt bilgiler kullanılır).
Harici URL'lerin dönüştürülmesi güvenli mi? Harici sayfaları dönüştürürken XSS veya kötü amaçlı komut dosyalarının yüklenme riski vardır. Tarayıcıyı her zaman izole bir ortamda (sandbox) çalıştırın, eklentileri devre dışı bırakın ve dosya sistemi erişimini kısıtlayın.