Node.js İle Pdf Raporu Oluşturma Servisi Nasıl Yapılır?

Node.js İle Pdf Raporu Oluşturma Servisi Nasıl Yapılır?
Node.js İle Pdf Raporu Oluşturma Servisi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce sisteminizde Node.js'in güncel bir LTS (Long Term Support) sürümünün kurulu olduğundan emin olun. 2026 yılı itibarıyla Node.js 22 veya üzeri sürümler, performans ve güvenlik açısından en iyi deneyimi sunmaktadır.

Projenizi başlatmak için bir klasör oluşturun ve gerekli paketleri yükleyin. Puppeteer, Chrome'un başsız (headless) sürümünü kullanarak HTML'i PDF'e dönüştürmek için kullanılan en popüler kütüphanedir.

mkdir pdf-servisi
cd pdf-servisi
npm init -y
npm install puppeteer handlebars express

Burada Puppeteer tarayıcı otomasyonu, Handlebars HTML şablonlarını verilerle doldurmak, Express ise PDF servisini dış dünyaya açmak için kullanılacaktır.

PDF Oluşturma Yöntemlerinin Karşılaştırılması

Node.js ile PDF üretirken farklı yaklaşımlar mevcuttur. İhtiyacınıza göre en uygun yöntemi seçmek projenin başarısı için kritiktir.

Yöntem Avantajları Dezavantajları
Puppeteer CSS desteği tam, modern web tasarımı Sunucu kaynak tüketimi yüksek
PDFKit Düşük kaynak tüketimi, hızlı Karmaşık layoutlar için zorlayıcı
jsPDF İstemci tarafında çalışabilir Sunucu tarafında sınırlı özellikler

Adım Adım PDF Servisi Tasarımı

İlk adım olarak, PDF'imizin temelini oluşturacak olan HTML şablonunu hazırlamalıyız. Handlebars kullanarak dinamik veri alanlarını belirleyeceğiz.



  
    

Rapor: {{baslik}}

Tarih: {{tarih}}

{{#each urunler}} {{/each}}
{{ad}}{{fiyat}} TL

Bu şablon, veritabanından gelen verilerin yerleşeceği iskeleti oluşturur. Handlebars, {{ }} işaretleri arasındaki değişkenleri çalışma anında doldurur.

Puppeteer ile HTML'den PDF'e Dönüştürme

Şablon hazırlandıktan sonra, Node.js içerisinde Puppeteer'ı kullanarak bu HTML'i PDF dosyasına dönüştüren fonksiyonu yazmalıyız. Bu fonksiyon, bir tarayıcı örneği başlatır ve içeriği PDF olarak kaydeder.

const puppeteer = require('puppeteer');
const fs = require('fs-extra');
const handlebars = require('handlebars');

async function pdfOlustur(data) {
  const html = await fs.readFile('template.hbs', 'utf-8');
  const template = handlebars.compile(html);
  const finalHtml = template(data);

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(finalHtml);
  await page.pdf({ path: 'rapor.pdf', format: 'A4' });

  await browser.close();
}

Bu kod bloğu, HTML içeriğini render eder ve belirtilen formatta PDF çıktısı üretir. await browser.close() satırı, bellek sızıntılarını önlemek için hayati öneme sahiptir.

Express ile PDF Servisini Yayına Alma

Oluşturduğumuz fonksiyonu bir API endpoint'i haline getirmek için Express'i kullanacağız. Bu sayede kullanıcılar bir istek gönderdiğinde PDF otomatik olarak üretilip indirilecektir.

const express = require('express');
const app = express();

app.get('/rapor-indir', async (req, res) => {
  const data = { baslik: 'Aylık Satış', tarih: '2026-05-01', urunler: [...] };
  await pdfOlustur(data);
  res.download('rapor.pdf');
});

app.listen(3000, () => console.log('Servis 3000 portunda çalışıyor.'));

Bu yapı, basit bir API uç noktası oluşturur. Gerçek projelerde res.download yerine buffer kullanarak dosyayı diske yazmadan doğrudan bellek üzerinden göndermek performansı artırır.

Güvenlik Uyarısı: Kullanıcıdan gelen verileri doğrudan HTML şablonuna yerleştirmeyin. XSS (Cross-Site Scripting) saldırılarını önlemek için verileri mutlaka sanitize edin (temizleyin). Ayrıca, üretim ortamında Puppeteer'ı bir Docker konteyneri içinde çalıştırmanız, sistem kaynaklarını izole etmenizi sağlar.

Performans İpuçları ve Hata Yönetimi

PDF oluşturma işlemleri CPU yoğunluklu süreçlerdir. Çok sayıda istek geldiğinde servisin kilitlenmemesi için bir kuyruk sistemi (örneğin BullMQ) kullanmanız önerilir. Hataları yakalamak için try-catch bloklarını ihmal etmeyin.

try {
  await pdfOlustur(data);
} catch (error) {
  console.error('PDF oluşturma hatası:', error);
  res.status(500).send('Rapor oluşturulamadı.');
}

Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce güvenlik açıklarını denetleyin, gerekli kütüphaneleri güncel tutun ve sunucu kaynaklarını optimize edin. Yazılımın neden olabileceği veri kayıplarından veya güvenlik ihlallerinden geliştirici sorumludur.

Sıkça Sorulan Sorular

Puppeteer neden çok fazla RAM tüketiyor?

Puppeteer her seferinde tam bir Chromium tarayıcı örneği başlatır. Bunu engellemek için tarayıcıyı bir kez başlatıp (singleton pattern) istekler arasında aynı örneği kullanmayı deneyin.

PDF dosyasında Türkçe karakter sorunu yaşıyorum, ne yapmalıyım?

HTML dosyanızın kısmına etiketini eklediğinizden ve sunucunuzun UTF-8 kodlamasını desteklediğinden emin olun.

PDF'e nasıl özel font ekleyebilirim?

Puppeteer'da CSS @font-face kuralını kullanarak web fontlarını içeri aktarabilir veya sistemde yüklü olan fontları CSS içerisinde tanımlayabilirsiniz.

Büyük verilerle çalışırken ne yapmalıyım?

Büyük raporlar için veriyi parçalara ayırın veya Puppeteer yerine daha düşük seviyeli PDFKit kütüphanesini tercih ederek bellek kullanımını minimize edin.

Servisimi nasıl ölçekleyebilirim?

PDF oluşturma servisini ana uygulamanızdan ayırarak ayrı bir mikroservis haline getirin ve Kubernetes gibi araçlarla yatay ölçeklendirme yapın.

PDF Servislerinde Kuyruk Yönetimi ile Asenkron İşleme

PDF oluşturma işlemleri, CPU ve bellek üzerinde yoğun yük oluşturan operasyonlardır. Eğer aynı anda onlarca kullanıcı rapor talep ederse, Node.js ana döngüsü (event loop) kilitlenebilir. Bu sorunu aşmak için BullMQ ve Redis kullanarak bir kuyruk yapısı kurmak en profesyonel yaklaşımdır.

Kuyruk mekanizması, gelen PDF taleplerini bir listeye alır ve arka planda çalışan "worker" süreçleri ile sırayla işler. Böylece ana uygulama yanıt vermeye devam ederken, PDF oluşturma süreci arka planda tamamlanır.

// worker.js - PDF oluşturma görevini işleyen kısım
const { Worker } = require('bullmq');

const worker = new Worker('pdf-queue', async job => {
  const { data } = job;
  console.log(`PDF işleniyor: ${job.id}`);
  // Burada Puppeteer veya PDFKit mantığınızı çalıştırın
  await generatePdf(data);
}, { connection: redisConnection });

PDF Dosyalarını Bulut Depolama Servislerine Yükleme

Üretilen PDF dosyalarını sunucunun yerel diskinde tutmak, özellikle yatay ölçeklenen (horizontal scaling) sistemlerde veri kaybına ve erişim sorunlarına yol açar. En iyi uygulama, oluşturulan dosyayı doğrudan AWS S3, Google Cloud Storage veya Azure Blob Storage gibi bir servise göndermektir.

Aşağıdaki örnekte, oluşturulan bir PDF buffer'ını AWS S3'e nasıl yükleyeceğinizi görebilirsiniz:

const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');

async function uploadToS3(pdfBuffer, fileName) {
  const s3 = new S3Client({ region: 'eu-central-1' });
  
  const params = {
    Bucket: 'raporlar-bucket',
    Key: `reports/${fileName}.pdf`,
    Body: pdfBuffer,
    ContentType: 'application/pdf'
  };

  return await s3.send(new PutObjectCommand(params));
}

PDF Oluşturma Süreçlerinde Birim Testleri

Raporlarınızın doğru formatta üretildiğini garanti etmek için test süreçlerini otomatize etmelisiniz. Jest ve Supertest kullanarak, PDF oluşturma endpoint'inizin doğru HTTP durum kodunu döndürdüğünü ve dönen verinin PDF formatında olduğunu doğrulayabilirsiniz.

Test Senaryosu Beklenen Sonuç
Geçersiz HTML verisi gönderimi 400 Bad Request
Başarılı PDF oluşturma 200 OK ve Content-Type: application/pdf
Zaman aşımı (Timeout) 504 Gateway Timeout

Özellikle büyük tablolar içeren raporlarda, sayfa kırılmalarının (page breaks) doğru çalışıp çalışmadığını test etmek için puppeteer ile üretilen PDF'in dosya boyutunu veya sayfa sayısını kontrol eden bir test yazmanız önerilir.

// test/pdf.test.js
const request = require('supertest');
const app = require('../app');

test('PDF servisi başarıyla yanıt vermeli', async () => {
  const response = await request(app)
    .post('/generate-pdf')
    .send({ html: '

Test Raporu

' }); expect(response.statusCode).toBe(200); expect(response.headers['content-type']).toBe('application/pdf'); });

Sonuç

Node.js ile PDF raporu oluşturma servisi geliştirmek, doğru araçları seçtiğinizde oldukça verimli bir süreçtir. Puppeteer ile modern web standartlarını kullanarak PDF üretmek, tasarım esnekliği sağlar. Bu rehberde öğrendiğiniz adımları takip ederek kendi raporlama modülünüzü oluşturabilir, ardından bu servisi bir kuyruk mekanizması ile güçlendirerek üretim ortamına hazır hale getirebilirsiniz. Bir sonraki adım olarak, PDF dosyalarınızı S3 veya benzeri bir bulut depolama servisine otomatik yükleyen bir yapı kurmayı deneyebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Deniz Arslan

On yıllık içerik üretim deneyimiyle karmaşık süreçleri herkesin anlayabileceği pratik rehberlere dönüştürüyorum. Günlük yaşamı kolaylaştıran çözümler üzerine uzmanlaşmış bir editörüm.

Yorumlar (0)

Yorum Yaz