Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Delphi ile Birden Fazla Pdf Dosyasını Birleştirme/Merge Hk.
#1
Merhaba,

Elimde her ay kesilmiş olunan birer sayfalık fatura pdf dosyaları olmakta. Ben bu pdf dosyalarında yer alan sayfaları tek bir pdf te birleştirerk toplu bir şekilde ve tek seferde yazdırmak istiyorum. bunun ile alakalı araştırma yaptım fakat hepsi ücretli componentler ile yapılmakta. Bu konu ile alakalı nasıl merge/birleştirme işlemi yapabilirim. Bu konu hakkında bilgi verebilecek olan var mı?
Cevapla
#2
(06-09-2023, Saat: 14:18)glagher Adlı Kullanıcıdan Alıntı: Merhaba,

Elimde her ay kesilmiş olunan birer sayfalık fatura pdf dosyaları olmakta. Ben bu pdf dosyalarında yer alan sayfaları tek bir pdf te birleştirerk toplu bir şekilde ve tek seferde yazdırmak istiyorum. bunun ile alakalı araştırma yaptım fakat hepsi ücretli componentler ile yapılmakta. Bu konu ile alakalı nasıl merge/birleştirme işlemi yapabilirim. Bu konu hakkında bilgi verebilecek olan var mı?

Merhabalar,

https://code.google.com/archive/p/pdfbinder/downloads

Kolay gelsin.
Amaç, bilginin de/aklın da zekat'ını vermek.
Cevapla
#3
"Google Chromium" kullananlar vardır. Sıkça ve severek kullanıyorum. 
Buna ek olarak Google'a ait bir de "Google PDFium" var. Onu da zaman zaman PDF işlemleri lazım olduğunda kullanıyorum ve size kullanımına ilişkin bir örnek hazırladım. Google Opensource linki için tıklayınız.

* Aşağıdaki örnek Button-1'e basınca açılan OpenDialog aracılığıyla PDF'leri çoklu seçerek bir liste kutusuna alıyor.
* Button-2'ye basınca basınca açılan SaveDialog aracılığıyla da verilen konum ve isimde pdf oluşturarak listedeki PDF dosyalarını birleştiriyor ve kaydediyor.
* x86 / x64 DLL dosyaları EXE klasöründe yer alıyor. Projenizi her iki platformda da üretebilirsiniz.

Örnek proje kayanağını bu linkten indirebilirsiniz.

İndirmeden incelemek isterseniz kaynak kod aşağıdaki gibidir.


uses PdfiumCore, PdfiumCtrl, PdfiumLib;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  With TOpenDialog.Create(nil) do
  try
    DefaultExt  := '.pdf';
    Options     := Options + [TOpenOption.ofAllowMultiSelect];
    Filter      := '*.pdf|*.pdf';
    if Execute then
    begin
      while Files.Count > 0 do
      begin
        ListBox1.Items.Add(Files[0]);
        Files.Delete(0);
      end;
    end;
  finally
    free;
  end;
end;

function MergePdfFiles( aList: TStrings ):TPdfControl;
var
  LPdf : TPdfDocument;
begin
  {$IFDEF CPUX64}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x64';
  {$ELSE}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x86';
  {$ENDIF CPUX64}

  result := TPdfControl.Create(nil);
  result.Align      := alClient;
  result.Color      := clGray;
  result.ScaleMode  := smFitWidth;
  result.PageColor  := RGB(255, 255, 200);

  result.LoadFromFile(aList[0]); // Referans
  aList.Delete(0);
  LPdf := TPdfDocument.Create;
  try
    while aList.Count > 0 do
    begin
        LPdf.LoadFromFile(aList[0]);
        result.Document.ImportAllPages(LPdf);
        aList.Delete(0);
    end;
  finally
    freeAndNil(LPdf);
  end;
end;


procedure TForm1.BitBtn2Click(Sender: TObject);
var
  LFinalPdf : TPDFControl;
begin
  With TSaveDialog.Create(nil) do
  try
    Filter      := '*.pdf|*.pdf';
    DefaultExt  := '.pdf';
    if Execute then
    begin
      LFinalPdf := MergePdfFiles(ListBox1.Items);
      try
        LFinalPdf.Document.SaveToFile( changefileext(FileName, DefaultExt) );
      finally
        freeAndNil(LFinalPdf);
      end;
    end;
    showmessage('OK');
  finally
    free;
  end;
end;





phj451bbhebqaybv9nom.gif
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#4
(06-09-2023, Saat: 18:35)mrmarman Adlı Kullanıcıdan Alıntı: "Google Chromium" kullananlar vardır. Sıkça ve severek kullanıyorum. 
Buna ek olarak Google'a ait bir de "Google PDFium" var. Onu da zaman zaman PDF işlemleri lazım olduğunda kullanıyorum ve size kullanımına ilişkin bir örnek hazırladım. Google Opensource linki için tıklayınız.

* Aşağıdaki örnek Button-1'e basınca açılan OpenDialog aracılığıyla PDF'leri çoklu seçerek bir liste kutusuna alıyor.
* Button-2'ye basınca basınca açılan SaveDialog aracılığıyla da verilen konum ve isimde pdf oluşturarak listedeki PDF dosyalarını birleştiriyor ve kaydediyor.
* x86 / x64 DLL dosyaları EXE klasöründe yer alıyor. Projenizi her iki platformda da üretebilirsiniz.

Örnek proje kayanağını bu linkten indirebilirsiniz.

İndirmeden incelemek isterseniz kaynak kod aşağıdaki gibidir.


uses PdfiumCore, PdfiumCtrl, PdfiumLib;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  With TOpenDialog.Create(nil) do
  try
    DefaultExt  := '.pdf';
    Options     := Options + [TOpenOption.ofAllowMultiSelect];
    Filter      := '*.pdf|*.pdf';
    if Execute then
    begin
      while Files.Count > 0 do
      begin
        ListBox1.Items.Add(Files[0]);
        Files.Delete(0);
      end;
    end;
  finally
    free;
  end;
end;

function MergePdfFiles( aList: TStrings ):TPdfControl;
var
  LPdf : TPdfDocument;
begin
  {$IFDEF CPUX64}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x64';
  {$ELSE}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x86';
  {$ENDIF CPUX64}

  result := TPdfControl.Create(nil);
  result.Align      := alClient;
  result.Color      := clGray;
  result.ScaleMode  := smFitWidth;
  result.PageColor  := RGB(255, 255, 200);

  result.LoadFromFile(aList[0]); // Referans
  aList.Delete(0);
  LPdf := TPdfDocument.Create;
  try
    while aList.Count > 0 do
    begin
        LPdf.LoadFromFile(aList[0]);
        result.Document.ImportAllPages(LPdf);
        aList.Delete(0);
    end;
  finally
    freeAndNil(LPdf);
  end;
end;


procedure TForm1.BitBtn2Click(Sender: TObject);
var
  LFinalPdf : TPDFControl;
begin
  With TSaveDialog.Create(nil) do
  try
    Filter      := '*.pdf|*.pdf';
    DefaultExt  := '.pdf';
    if Execute then
    begin
      LFinalPdf := MergePdfFiles(ListBox1.Items);
      try
        LFinalPdf.Document.SaveToFile( changefileext(FileName, DefaultExt) );
      finally
        freeAndNil(LFinalPdf);
      end;
    end;
    showmessage('OK');
  finally
    free;
  end;
end;





phj451bbhebqaybv9nom.gif

Verdiğiniz bilgiler için çok teşekür ederim. Yalnız bunu ek bir bileşen kullanmadan yapabilme şansımız var mı acaba?

(06-09-2023, Saat: 18:35)mrmarman Adlı Kullanıcıdan Alıntı: "Google Chromium" kullananlar vardır. Sıkça ve severek kullanıyorum. 
Buna ek olarak Google'a ait bir de "Google PDFium" var. Onu da zaman zaman PDF işlemleri lazım olduğunda kullanıyorum ve size kullanımına ilişkin bir örnek hazırladım. Google Opensource linki için tıklayınız.

* Aşağıdaki örnek Button-1'e basınca açılan OpenDialog aracılığıyla PDF'leri çoklu seçerek bir liste kutusuna alıyor.
* Button-2'ye basınca basınca açılan SaveDialog aracılığıyla da verilen konum ve isimde pdf oluşturarak listedeki PDF dosyalarını birleştiriyor ve kaydediyor.
* x86 / x64 DLL dosyaları EXE klasöründe yer alıyor. Projenizi her iki platformda da üretebilirsiniz.

Örnek proje kayanağını bu linkten indirebilirsiniz.

İndirmeden incelemek isterseniz kaynak kod aşağıdaki gibidir.


uses PdfiumCore, PdfiumCtrl, PdfiumLib;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  With TOpenDialog.Create(nil) do
  try
    DefaultExt  := '.pdf';
    Options     := Options + [TOpenOption.ofAllowMultiSelect];
    Filter      := '*.pdf|*.pdf';
    if Execute then
    begin
      while Files.Count > 0 do
      begin
        ListBox1.Items.Add(Files[0]);
        Files.Delete(0);
      end;
    end;
  finally
    free;
  end;
end;

function MergePdfFiles( aList: TStrings ):TPdfControl;
var
  LPdf : TPdfDocument;
begin
  {$IFDEF CPUX64}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x64';
  {$ELSE}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x86';
  {$ENDIF CPUX64}

  result := TPdfControl.Create(nil);
  result.Align      := alClient;
  result.Color      := clGray;
  result.ScaleMode  := smFitWidth;
  result.PageColor  := RGB(255, 255, 200);

  result.LoadFromFile(aList[0]); // Referans
  aList.Delete(0);
  LPdf := TPdfDocument.Create;
  try
    while aList.Count > 0 do
    begin
        LPdf.LoadFromFile(aList[0]);
        result.Document.ImportAllPages(LPdf);
        aList.Delete(0);
    end;
  finally
    freeAndNil(LPdf);
  end;
end;


procedure TForm1.BitBtn2Click(Sender: TObject);
var
  LFinalPdf : TPDFControl;
begin
  With TSaveDialog.Create(nil) do
  try
    Filter      := '*.pdf|*.pdf';
    DefaultExt  := '.pdf';
    if Execute then
    begin
      LFinalPdf := MergePdfFiles(ListBox1.Items);
      try
        LFinalPdf.Document.SaveToFile( changefileext(FileName, DefaultExt) );
      finally
        freeAndNil(LFinalPdf);
      end;
    end;
    showmessage('OK');
  finally
    free;
  end;
end;





phj451bbhebqaybv9nom.gif

pdf formatına dönüştürülmüş halini byte array formatında birden fazla pdf'in var aslında bu byte array formatında olan pdfleri nasıl birleştirebilirim?
Cevapla
#5
Size seçenek sundum o kadar. Karar sizindir. PDF reader farklı writer farklı beceri istiyor. Attachment, style vs. bir sürü bilinmesi gereken detay var. Bunu içeren bir yapı ticari bir hal alıyor olmalı ki henüz sağlam bir direkt kod kaynağı göremedim. 

- Bu verdiğim örnek içerik de açık bir kaynak ve Google tarafından destekleniyor. ARM versiyonu da var. DLL'lerin dağıtım iznini açık gördüğüm için paylaştım.

* Byte Array ise aşağıdaki örnek size yeni bir seçenek sunacaktır.
* FileToBytes ile bir PDF dosyayı TBytes olarak array haline dönüştürür. 
* Sizde her bir pdf içerik zaten TBytes array halinde ise bu kısmı yapılı varsayabilir direkt bir alttaki kısımdan yani LPdf.LoadFromBytes( xxx ); şeklinde kullanabilirsiniz. Örnek için her bir dosyayı TBytes array dönüştüren bir function ekledim.



function FileToBytes(const aFile: string ):TBytes;
var
  Ms: TMemoryStream;
begin
  Finalize(Result);
  if not FileExists(aFile) then
    Exit;
  Ms := TMemoryStream.Create;
  try
    Ms.LoadFromFile(aFile);
    SetLength(Result, Ms.Size);
    if Ms.Size > 0 then
    begin
      Ms.Position := 0;
      Ms.ReadBuffer(Pointer(result)^, Ms.Size);
    end;
  finally
    Ms.Free;
  end;
end;

function MergePdfFiles( aList: TStrings ):TPdfControl;
var
  LPdf    : TPdfDocument;
begin
  {$IFDEF CPUX64}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x64';
  {$ELSE}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x86';
  {$ENDIF CPUX64}

  result := TPdfControl.Create(nil);
  result.Align      := alClient;
  result.Color      := clGray;
  result.ScaleMode  := smFitWidth;
  result.PageColor  := RGB(255, 255, 200);

  result.LoadFromFile(aList[0]); // Referans
  aList.Delete(0);
  LPdf := TPdfDocument.Create;
  try
    while aList.Count > 0 do
    begin
        LPdf.Close;
      //LPdf.LoadFromFile(aList[0]);
        LPdf.LoadFromBytes( FileToBytes(aList[0]) );
        result.Document.ImportAllPages(LPdf);
        aList.Delete(0);
    end;
  finally
    freeAndNil(LPdf);
  end;
end;



Bir ekleme yapayım, eğer dll dosya eksikliği ihtimali projenizin çalışamaz hale geleceği şüphesi yaşıyorsanız, kaygınızı giderecek yöntem DLL'leri resource olarak exe'de gömülü taşıyın. Dinamik yükleyin veya temp klasörüne açıp oradan kullanın.

Örnekleri forumda paylaşmışım diye hatırlıyorum. SSL kütüphane konularında vardı.


bkz. bu link
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla
#6
(07-09-2023, Saat: 17:48)mrmarman Adlı Kullanıcıdan Alıntı: Size seçenek sundum o kadar. Karar sizindir. PDF reader farklı writer farklı beceri istiyor. Attachment, style vs. bir sürü bilinmesi gereken detay var. Bunu içeren bir yapı ticari bir hal alıyor olmalı ki henüz sağlam bir direkt kod kaynağı göremedim. 

- Bu verdiğim örnek içerik de açık bir kaynak ve Google tarafından destekleniyor. ARM versiyonu da var. DLL'lerin dağıtım iznini açık gördüğüm için paylaştım.

* Byte Array ise aşağıdaki örnek size yeni bir seçenek sunacaktır.
* FileToBytes ile bir PDF dosyayı TBytes olarak array haline dönüştürür. 
* Sizde her bir pdf içerik zaten TBytes array halinde ise bu kısmı yapılı varsayabilir direkt bir alttaki kısımdan yani LPdf.LoadFromBytes( xxx ); şeklinde kullanabilirsiniz. Örnek için her bir dosyayı TBytes array dönüştüren bir function ekledim.



function FileToBytes(const aFile: string ):TBytes;
var
  Ms: TMemoryStream;
begin
  Finalize(Result);
  if not FileExists(aFile) then
    Exit;
  Ms := TMemoryStream.Create;
  try
    Ms.LoadFromFile(aFile);
    SetLength(Result, Ms.Size);
    if Ms.Size > 0 then
    begin
      Ms.Position := 0;
      Ms.ReadBuffer(Pointer(result)^, Ms.Size);
    end;
  finally
    Ms.Free;
  end;
end;

function MergePdfFiles( aList: TStrings ):TPdfControl;
var
  LPdf    : TPdfDocument;
begin
  {$IFDEF CPUX64}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x64';
  {$ELSE}
    PDFiumDllDir := ExtractFilePath(ParamStr(0)) + 'x86';
  {$ENDIF CPUX64}

  result := TPdfControl.Create(nil);
  result.Align      := alClient;
  result.Color      := clGray;
  result.ScaleMode  := smFitWidth;
  result.PageColor  := RGB(255, 255, 200);

  result.LoadFromFile(aList[0]); // Referans
  aList.Delete(0);
  LPdf := TPdfDocument.Create;
  try
    while aList.Count > 0 do
    begin
        LPdf.Close;
      //LPdf.LoadFromFile(aList[0]);
        LPdf.LoadFromBytes( FileToBytes(aList[0]) );
        result.Document.ImportAllPages(LPdf);
        aList.Delete(0);
    end;
  finally
    freeAndNil(LPdf);
  end;
end;



Bir ekleme yapayım, eğer dll dosya eksikliği ihtimali projenizin çalışamaz hale geleceği şüphesi yaşıyorsanız, kaygınızı giderecek yöntem DLL'leri resource olarak exe'de gömülü taşıyın. Dinamik yükleyin veya temp klasörüne açıp oradan kullanın.

Örnekleri forumda paylaşmışım diye hatırlıyorum. SSL kütüphane konularında vardı.


bkz. bu link

Çok teşekkür ederim işime yaradı.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Delphi İle Shopify Entegrasyonu narkotik 1 109 13-02-2025, Saat: 14:48
Son Yorum: Hayati
Photo Delphi 12.2ilginç bir ide hatası tuna 0 81 12-02-2025, Saat: 11:22
Son Yorum: tuna
  Delphi için yapay zeka kod yardımcısı eklentisi csunguray 13 653 05-02-2025, Saat: 20:13
Son Yorum: mrmarman
  Delphi Ide hatası Bay_Y 6 244 04-02-2025, Saat: 10:56
Son Yorum: Bay_Y
  Delphi 7 kullanıcısı yeni versiyona başlamalımıyım kadir344 2 149 26-01-2025, Saat: 10:35
Son Yorum: enigma



Konuyu Okuyanlar: 1 Ziyaretçi