C#

iTextSharp PDF Birleştirme

Herkese merhaba, C# yazılarımıza kaldığımız yerden devam ediyoruz. Bu yazımızda iTextSharp kütüphanesi ile PDF dosyalarını birleştirmeyi anlatacağım. Hadi başlayalım !

iTextSharp kütüphanesi, PDF dosyaları üzerinde işlem yapmayı sağlayan tamamen ücretsiz bir kütüphane ve C# kurulumu ile beraber gelmiyor, yani kütüphaneyi indirip projeye eklememiz gerekiyor. Projeye 3. parti bir paket eklemenin en kolay ve hızlı yolu ise Nuget kullanmak. Nuget, Visual Studio ile beraber gelen ve Visual Studio’ya entegre bir şekilde çalışan, terminal komutlarıyla projeye paket eklememizi sağlayan bir paket yöneticisi. Bir tane Windows Forms yada Console projesi oluşturduktan sonra Visual Studio üzerinden Tools > NuGet Package Manager > Package Manager Console adımlarını izleyerek Nuget terminalini açabilirsiniz. iTextSharp paketini projeye eklemek için açılan terminalde şöyle bir komut gireceğiz;

install-package itextsharp

Bu komutun ardından Nuget, iTextSharp paketini indirecek ve projeye dahil edecektir. Bu komutun tamamlanmasının ardından iTextSharp paketini kullanabiliriz.

iTextSharp kütüphanesini projeye dahil etsek bile kod yazacağımız dosyada bu paketi ve kullanacağımız diğer kütüphaneleri çağırmamız gerekiyor. Bunun için dosyanın en başına gelerek şu satırları ekleyelim;

using System.IO;
using iTextSharp.text.pdf;

Bu kodları da ekledikten sonra artık iTextSharp kütüphanesini kullanarak PDF birleştirme işlemini yapabiliriz.

Ben bir fonksiyon yazacağım ve bu fonksiyon ile birden fazla PDF dosyasını tek bir PDF dosyasında birleştireceğim. Yazacağımız fonksiyon string dizisi olarak birleştirilecek dosyaları ve birleştirilen dosyaları kaydetmek için de hedef dosya adresini parametre olarak alacak. Yani fonksiyon gövdesi şöyle olacaktır;

public void PdfBirlestir(string[] kaynakDosyalar, string hedefDosya) { }

PDF dosyalarını birleştirme işlemini PdfConcatenate adında bir sınıf yapıyor ve bu sınıfı kullanabilmek için yeni bir nesnesini türetmemiz gerekiyor. Yeni bir nesnesini ise constructor metodunu kullanarak yapabiliyoruz. Constructor metodu ise bir tane FileStream nesnesi istiyor. Bu FileStream nesnesi doğrudan hedef dosya üzerinde bağlı olması gerekiyor. Yani PdfConcatenate sınıfı birleştirilecek dosyaları okuyup FileStream nesnesi üzerinden dosyaya yazma ve dosyayı kaydetme işlemlerini yapıyor. Bu yüzden öncelikle FileStream sınıfından yeni bir nesne türetmemiz gerekiyor. Constructor metodunu kullanarak FileStream nesnesi türetebiliyoruz ve bu metod 2 tane parametre istiyor. Parametrelerden ilki dosyanın yolunu, ikincisi ise dosyaya erişim yöntemi olacak. Dosyaya erişim yöntemi ise FileMode enumu üzerinden belirtilebilmekte. Bu enum, işletim sisteminin dosyayı ne şekilde açacağını belirtmek için kullanılıyor. Biz yeni bir dosya oluşturacağımız için FileMode enum’unun Create propertysini kullanacağız.

FileStream fs = new FileStream(hedefDosya, FileMode.Create);

FileStream sınıfından yeni bir nesne oluşturduğumuza göre artık PdfConcatenate sınıfından da yeni bir nesne oluşturabiliriz. Oda şu şekilde olacaktır;

PdfConcatenate pdfConcat = new PdfConcatenate(fs);

Yazacağımız PdfBirlestir fonksiyonuna birleştirilmek istenen dosyalar birden fazla geleceği için her bir dosyayı teker teker okuyup birleştirme işlemi yapmamız gerekiyor. Bir dizi içerisinde tüm verileri teker teker okumanın en makul yolu ise döngü kullanmak. Ben foreach döngüsü kullanacağım fakat siz while, do-while veya for döngüsü kullanarakta bu işlemi yapabilirsiniz. foreach döngüsü kullanarak yazacağımız döngü gövdesi şu şekilde olacaktır;

foreach (string kaynakDosya in kaynakDosyalar) { }

Döngü içerisinde öncelikle dosyayı iTextSharp paketi ile okuyacak ve bu dosyanın sayfalarını tespit edeceğiz. Tespit ettiğimiz sayfaları az önce oluşturduğumuz PdfConcatenate sınıfını kullanarak birleştirecek ve işlemi tamamlayacağız. PDF dosyasını okumak ve sayfalarını tespit etmek için iTextSharp paketi altında bulunan PdfReader sınıfını kullanacağız. Tabiki bu sınıfı kullanabilmek için öncelikle yeni bir nesnesini türetmemiz gerekiyor. Yeni bir nesnesini constructor metodu kullanarak yapabiliriz ve bu metod parametre olarak yeni bir FileStream sınıfı nesnesi istiyor. Oluşturacağımız yeni FileStream sınıfı nesnesini bu sefer var olan dosyayı okuma olarak oluşturacağız. Yani FileMode olarak az önce Create verdik ya, bu sefer Open vereceğiz. Bu sayede işletim sistemi var olan bir dosyayı açtığımızı ve okumak istediğimizi anlayacak ve bu şekilde işlem yapacaktır. FileStream sınıfının constructor metodunun ilk parametresi ise dosyanın yolunu temsil eden kaynakDosya değişkeni olacak. Yani şu şekilde yeni bir FileStream ve sonrasında PdfReader nesneleri oluşturabiliriz;

FileStream reader = new FileStream(kaynakDosya, FileMode.Open);
PdfReader pdfReader = new PdfReader(reader);

PDF dosyasını okuduk, şimdi sıra geldi sayfalarını tespit etmeye. Bir PDF dosyasında kaç sayfa olduğunu her zaman bilemeyeceğimiz için programlamatik bir şekilde yapmamız gerekiyor. Bir PDF dosyasında kaç sayfa olduğunu az önce oluşturduğumuz PdfReader sınıfı nesnesi (pdfReader değişkeni) altındaki NumberOfPages propertysi ile tespit edebiliyoruz. Bu property bize dosyada kaç sayfa olduğunu söylüyor fakat bize tam olarak sayfa sayısı değil, sayfaların kendisi lazım. Burada yapacağımız işlem adımları ise; PdfReader nesnesine şu şu sayfaları kullan diyeceğiz. Kullanacağı sayfaların doğrudan sayfa numaralarını belirterek PdfReader sınıfının o sayfaları kullanmasını belirtebiliyoruz. Yani 1, 2, 3, 4, … sayfalarını oku diyeceğiz. Birden fazla sayfa numarası söyleyeceğimiz için bu sayfa numaralarını bir dizi içerisine koyabiliriz. NumberOfPages propertysi toplam sayfa sayısını söylediğine göre 0’dan başlayıp NumberOfPages sayısına kadar döngü ile gezer ve her bir adımda ilgili sayfa numarasını oluşturacağımız diziye eklersek aslında tüm sayfaları dizi içerisinde toplamış oluruz. Yani kısaca şöyle bir kod yazacağız;

int[] sayfalar = new int[pdfReader.NumberOfPages + 1];
for (int i = 0; i <= pdfReader.NumberOfPages; i++)
    sayfalar[i] = i;

sayfalar dizisinin uzunluğunu pdfReader.NumberOfPages propertysinin 1 fazlası olarak belirttik, çünkü döngü içerisine bakarsanız üst limiti son sayfanın dahil olabilmesi için küçük eşittir (<=) şeklinde yazdık.

Birleştirilecek sayfa numaralarını da tespit ettiğimize göre artık PdfReader sınıfına bu sayfaları kullan diyebiliriz. Bunun için PdfReader nesnesi altındaki SelectPages() fonksiyonunu kullanacağız. Bu fonksiyon bir tane int dizisini parametre olarak istiyor ve parametre olarak gönderdiğimiz sayfaları okuyor.

pdfReader.SelectPages(sayfalar);

Birleştirme yapacağımız sayfaları tespit ettiğimize göre artık birleştirme işlemini yapabiliriz. Birleştirme işlemini yeni bir nesnesini türettiğimiz PdfConcatenate sınıfını kullanarak yapacağız. Bu sınıf birleştirme yapılacak sayfaları biriktiriyor ve hedef dosyaya yazma işlemi yapıyor. Biriktirilen dosyalara yenilerini eklemek için ise AddPages() fonksiyonunu kullanacağız. Bu fonksiyon bir tane PdfReader sınıfı nesnesini parametre olarak istiyor. Biz zaten PdfReader nesnesi oluşturup okunacak sayfaları tanıtmıştık, doğrudan bu nesneyi parametre olarak gönderebiliriz.

pdfConcat.AddPages(pdfReader);

foreach döngüsünün o anki adımında bulunan dosya birleştirilecek dosyalar arasına eklendi, artık bu dosya ile işimiz kalmadı. Bellekte serbest bırakmak ve diğer proseslerin bu dosyaya erişebilmesine izin vermek için hem PdfReader nesnesini hemde bu dosya için oluşturmuş olduğumuz FileStream nesnesini kapatmamız gerekiyor. Nesneleri kapatmak için her birinin Close() metodunu kullanacağız.

pdfReader.Close();
reader.Close();

foreach döngüsü ile işimiz bitti çünkü o anki dosya artık birleştirildi, döngünün dışına çıkabiliriz. Yani şu aşamada foreach döngüsü şu şekilde olacaktır;

foreach (string kaynakDosya in kaynakDosyalar)
{
    FileStream reader = new FileStream(kaynakDosya, FileMode.Open);
    PdfReader pdfReader = new PdfReader(reader);
    int[] sayfalar = new int[pdfReader.NumberOfPages + 1];
    for (int i = 0; i <= pdfReader.NumberOfPages; i++)
        sayfalar[i] = i;
    pdfReader.SelectPages(sayfalar);
    pdfConcat.AddPages(pdfReader);
    pdfReader.Close();
    reader.Close();
}

Döngü tamamlandığında bellekte birleştirme işlemi de tamamlanmış olacaktır fakat henüz hedef dosyaya yazma işlemini yapmadık. Yazma işleminin tamamlanması için PdfConcatenate sınıfı nesnesini kapatmamız gerekiyor. Kapatma işlemini yapınca birleştirme yapılacak dosyalar birleştirilip hedef dosyaya yazılıyor ve kaydediliyor. Ayrıca hedef dosyayı FileStream nesnesine bağlamıştık ya, onu da serbest bırakarak yani kapatarak diğer proseslerin hedef dosyaya erişebilmesine izin vermemiz gerekiyor. Bu iki işlemi hem PdfConcatenate hemde FileStream nesneleri altındaki Close() fonksiyonlarını kullanarak yapacağız.

pdfConcat.Close();
fs.Close();

Evet iTextSharp kütüphanesi ile PDF birleştirme işlemi tamamlandı, yazdığımız tüm kodları aşağıya toplu bir şekilde yazalım ve ayrıca fonksiyonu örnek olması için çağıralım;

public void PdfBirlestir(string[] kaynakDosyalar, string hedefDosya)
{
    FileStream fs = new FileStream(hedefDosya, FileMode.Create);
    PdfConcatenat pdfConcat = new PdfConcatenate(fs);
    foreach (string kaynakDosya in kaynakDosyalar)
    {
        FileStream reader = new FileStream(kaynakDosya, FileMode.Open);
        PdfReader pdfReader = new PdfReader(reader);
        int[] sayfalar = new int[pdfReader.NumberOfPages + 1];
        for (int i = 0; i <= pdfReader.NumberOfPages + 1; i++)
            sayfalar[i] = i;
        pdfReader.SelectPages(sayfalar);
        pdfConcat.AddPages(pdfReader);
        pdfReader.Close();
        reader.Close();
    }
    pdfConcat.Close();
    fs.Close();
}

public void Main(string[] args)
{
    string[] birlestirilecekDosyalar = new string[] { "c:/users/kullanici/desktop/dosya-1.pdf", "c:/users/kullanici/desktop/dosya-2.pdf", "c:/users/kullanici/desktop/dosya-3.pdf" };
    string hedefDosya = "c:/users/kullanici/desktop/birleştirilmiş.pdf";
    PdfBirlestir(birlestirileceDosyalar, hedefDosya);
}

Tüm C# yazılarımıza buraya tıklayarak ulaşabilirsiniz. Herkese hayırlı günler.

Skorumuz:
Oy Vermek İçin Tıklayın
[Toplam: 0 Ortalama: 0]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu