PDF dosya ekleri belgenin gömülü dosya ağacında saklanır; bu yapıyı çoğu görüntüleyici bir ataç paneli ya da ekler kenar çubuğu olarak gösterir. Delphi kodundan PDFium Component bu ağacı TPdf üzerindeki küçük bir dizinli özellik kümesiyle sunar: tamsayı dizinle dolaşır, adları ve bayt yüklerini okur, yeni yuvalar oluşturur ve mevcut olanları silersiniz. API yüzeyi dardır; çevresine üretim kodu yazmadan önce bilinmeye değer yalnızca birkaç sıralama kısıtı ve bir temizleme kuralı vardır
Açık bir belgeden ekleri okumak
AttachmentCount, belgenin bildirdiği gömülü dosya sayısını verir. Doğrudan PDFium'un alttaki çağrısından okur; dolayısıyla yalnızca PDF dosyasının gerçekte içerdiğini yansıtır. Oradan AttachmentName[Index] görüntü adını bir WString olarak döndürür ve Attachment[Index] ham baytları bir TBytes dizisi olarak verir. Her ikisi de sıfır tabanlıdır. Her iki özelliği sorgulamadan önce belgenin açık olması gerekir (Pdf.Active = True); onları kapalı bir belgede çağırmak, istisna olmadan sıfır ya da boş bir sonuç verir
Akılda tutulacak bir şey: Attachment[Index] her okumada dosya yükünün tamamını ayırıp döndürür. Büyük bir gömülü varlık taşıyan bir belgede, bir görüntü listesi kurmak için tüm ekleri dolaşmak bu ayırma bedelini her çağrıda ödemek demektir. Görüntüleme amacıyla yalnızca adlara ihtiyacınız varsa önce AttachmentName okuyun ve bayt alımını kullanıcı dosyayı gerçekten isteyene dek erteleyin
procedure ListAttachments(Pdf: TPdf);
var
I: Integer;
Data: TBytes;
begin
if not Pdf.Active then
Exit;
for I := 0 to Pdf.AttachmentCount - 1 do
begin
Data := Pdf.Attachment[I];
Writeln(Format('%d: %s (%d bytes)',
[I, Pdf.AttachmentName[I], Length(Data)]));
end;
end;
Bir eki diske çıkarmak
Bir SaveAttachment yardımcısı yoktur. Baytları okur ve gerektiği yere yazarsınız; bu da yol kurma ve temizleme işini tümüyle kodunuza bırakır. Ek adları güvenilmeyen belgelerden geldiğinde bu önem taşır. PDF ek adları dosyanın içinde saklanan dizgelerdir; yol ayırıcıları, Unicode benzerleri ve doğrudan TFileStream.Create çağrısına verirseniz beklenmedik sonuçlar üretecek başka karakterler içerebilirler. Herhangi bir çıktı yolu kurmadan önce adı her zaman ExtractFileName içinden geçirin ve noktayla başlayan ya da sisteminizin beklediğinin dışında karakterler içeren adları reddetmeyi düşünün
Attachment[Index] tarafından döndürülen bayt dizisi çağırana aittir. Onu sıradan bir TFileStream ile yazın; bildirilen ada güvenmek yerine gerçek dosya biçimini doğrulamak için ilk birkaç baytı incelemek dahil, onunla istediğinizi yapabilirsiniz
procedure ExtractAttachment(Pdf: TPdf; Index: Integer; const OutputDir: string);
var
SafeName: string;
OutPath: string;
Data: TBytes;
FS: TFileStream;
begin
SafeName := ExtractFileName(Pdf.AttachmentName[Index]);
if SafeName = '' then
SafeName := Format('attachment_%d', [Index]);
OutPath := IncludeTrailingPathDelimiter(OutputDir) + SafeName;
Data := Pdf.Attachment[Index];
FS := TFileStream.Create(OutPath, fmCreate);
try
if Length(Data) > 0 then
FS.WriteBuffer(Data[0], Length(Data));
finally
FS.Free;
end;
end;
Ek eklemek ve iki adımlı yazma
Bir ek oluşturmak tek değil iki çağrı gerektirir. CreateAttachment(Name) gömülü dosya ağacında yeni bir yuva kaydeder ve başarıda True döndürür. O yuva boş başlar. Sonra en son oluşturulan girdiyi hedefleyerek Attachment[AttachmentCount - 1] konumuna yazarak yükü atarsınız. CreateAttachment False döndürürse yuva oluşturulmamıştır ve atama, o an son olan dizindeki eki bozar
Ek listesini değiştirdikten sonra değişiklikler yalnızca bellekte yaşar. Güncellenmiş gömülü dosya ağacıyla yeni bir dosya yazmak için SaveAs çağırın. PDFium Component o an açık olan aynı dosyaya geri kaydetmeyi desteklemez; çünkü motor kaynağa bir okuma tanıtıcısı tutar. Yerinde güncelleme için standart desen, geçici bir yola kaydetmek, belgeyi kapatmak, özgün dosyayı silmek ya da yeniden adlandırmak, sonra geçici dosyayı yerine adlandırıp yeniden açmaktır
procedure AddFileAttachment(Pdf: TPdf; const FilePath: string);
var
FS: TFileStream;
Data: TBytes;
AttachName: string;
begin
if not Pdf.Active then
Exit;
FS := TFileStream.Create(FilePath, fmOpenRead or fmShareDenyWrite);
try
SetLength(Data, FS.Size);
if FS.Size > 0 then
FS.ReadBuffer(Data[0], FS.Size);
finally
FS.Free;
end;
AttachName := ExtractFileName(FilePath);
if Pdf.CreateAttachment(AttachName) then
Pdf.Attachment[Pdf.AttachmentCount - 1] := Data;
end;
Ek tür bilgisi
Ad ve bayt yükünün ötesinde AttachmentType[Index], dosya ilk eklendiğinde kaydedilmişse PDF'in gömülü dosya sözlüğünde saklanan MIME türü dizgesini döndürür. Birçok üretici bu alanı boş bırakır ya da application/octet-stream gibi genel bir değere ayarlar; dolayısıyla bir üretim hattında biçim tespiti için ona güvenemezsiniz. Güvenilir tanımlama için yükün ilk birkaç baytını okuyup bilinen dosya imzalarını denetleyin: iç içe bir PDF için %PDF, Office Open XML belgeleri için ZIP yerel dosya başlığı PK\x03\x04, eski bileşik dosya ikilileri için \xD0\xCF\x11\xE0. Sözlükten gelen tür bilgisini bir arayüz etiketinde göstermek sorun değildir ama gerçek baytlar elinizdeyken işleme kararlarını sürmemelidir
Ekleri silmek
DeleteAttachment(Index) o konumdaki girdiyi kaldırır ve başarıda True döndürür. Silmeden sonra kalan girdiler aşağı kayar; dolayısıyla bir döngüde birden çok ek siliyorsanız her kaymadan sonra girdi atlamamak için ileriye değil son dizinden geriye doğru ilerlemeniz gerekir. Değişiklik, SaveAs çağırana dek bellektedir
Belge işleme hatlarında yaygın bir senaryo, güvenlik ya da boyut nedeniyle gelen bir PDF dosyasındaki bütün ekleri aşağı akışa vermeden önce sıyırmaktır. Döngüden önce bir kez sayın ve tersten ilerleyin:
procedure StripAllAttachments(Pdf: TPdf);
var
I: Integer;
begin
for I := Pdf.AttachmentCount - 1 downto 0 do
Pdf.DeleteAttachment(I);
end;
PDF ekleri pratikte nerede karşınıza çıkar
Ek API arayüzü PDFium'un açabildiği her PDF üzerinde çalışır ama gömülü dosyalarla gerçekten karşılaştığınız belgeler birkaç belirli durum çevresinde kümelenir. PDF/A-3 (ISO 19005-3), kaynak veriyi arşiv sunumunun yanında paketlemenin bir yolu olarak uyumlu gömülü dosyalara açıkça izin verir; ZUGFeRD ve Factur-X elektronik faturaları, insan tarafından okunabilir PDF düzeninin içine yapılandırılmış bir XML yükü gömmek için tam olarak buna dayanır. E-postadan türetilmiş PDF dosyaları bazen özgün ileti eklerini gömülü dosya ağacına iletilmiş olarak taşır. Yapılandırılmış yazım sistemlerinden gelen teknik belgeler de zaman zaman destekleyici varlıkları aynı biçimde paketler
Uygulamanız kuruluşunuzun dışından gelen PDF dosyalarını işliyorsa, belge girişinin bir parçası olarak AttachmentCount denetlemek iki bağımsız nedenle yapmaya değer. Birincisi, gömülü dosyalar bir fatura PDF dosyasının içindeki XML gibi çıkarıp işlemek isteyeceğiniz veri taşıyabilir. İkincisi, gömülü dosyalar rastgele çalıştırılabilir içerik taşıyabilir; dolayısıyla neyin bulunduğunu bilmek, onu hiç çıkarmayı düşünmeseniz bile önemlidir. Hiçbiri karmaşık bir şey yapmanızı gerektirmez: sayıyı okuyun, adları denetleyin ve baytlarla ne yapacağınıza karar verin
Burada gösterilen ek özellikleri, Delphi ve C++Builder için PDFium Component parçasıdır