PDFium Component untuk Delphi dan Lazarus mempertukarkan data formulir dan anotasi melalui XFDF, format pertukaran XML yang didefinisikan oleh ISO 19444-1. TPdf.ExportXFDF menserialisasikan setiap nilai bidang formulir dan setiap anotasi yang didukung dalam dokumen yang dimuat ke berkas XFDF atau TStream; TPdf.ImportXFDF membaca kembali dokumen XFDF, membuat ulang anotasi pada halamannya dan menerapkan nilai bidang. Satu round-trip tersebut mencakup dua alur kerja yang akhirnya dibutuhkan oleh setiap aplikasi dokumen: peninjau menandai PDF di Acrobat dan mengirimkan komentar kepada Anda untuk digabungkan, atau aturan kepatuhan yang menyatakan data formulir harus berada dalam berkas terpisah yang dapat dibandingkan (diffable) dan diaudit alih-alih ditanam langsung di dalam PDF itu sendiri
Apakah PDFium mendukung impor dan ekspor XFDF?
Pustaka PDFium itu sendiri tidak mendukungnya. API C native tidak memiliki fungsi XFDF atau FDF sama sekali — tidak ada dalam header publiknya yang membaca atau menulis salah satu format tersebut, sehingga pembungkusan (wrapping) sebanyak apa pun tidak akan membawa Anda ke sana. Oleh karena itu, PDFium Component mengimplementasikan seluruh mesin XFDF dalam Pascal, dalam unit khusus yang membangun dan mengurai XML secara langsung di atas model data anotasi dan bidang formulir TPdf yang sudah ada. Penulis memancarkan XML secara manual dan pembaca adalah parser mesin keadaan (state-machine parser) yang ditulis secara manual, sehingga fitur ini tidak menambah dependensi pada XMLDoc Delphi atau unit DOM FPC dan berperilaku identik pada Delphi dan Lazarus
Keputusan desain itu penting ketika Anda mengevaluasi alternatif. Jika Anda telah memanggil fungsi FPDF_* mentah dari Pascal, XFDF adalah sebuah dinding pembatas: kemampuan tersebut tidak ada di dalam DLL. Komponen ini melintasi dinding tersebut dengan memperlakukan XFDF sebagai masalah serialisasi murni — mengumpulkan nilai bidang dan rekaman anotasi yang sudah diketahui cara membacanya oleh pembungkus, menulisnya sebagai XML standar, dan membalikkan proses tersebut saat impor
Apa isi berkas XFDF?
ISO 19444-1 mendefinisikan XFDF sebagai representasi XML dari FDF, dan payload-nya terbagi menjadi dua blok tingkat atas. Elemen <fields> membawa nama bidang formulir hierarkis dan nilainya — semua yang diketik, dipilih, atau dicentang pengguna dalam AcroForm. Elemen <annots> membawa anotasi: TPdf.ExportXFDF memancarkan 18 subtipe — teks, sorotan (highlight), garis bawah (underline), coretan (strikeout), squiggly, garis, lingkaran, persegi, caret, poligon, poliline, stempel, tinta, teks bebas (freetext), lampiran berkas (fileattachment), suara, tautan, dan redaksi. Anotasi widget sengaja absen dari <annots> karena datanya berjalan di <fields>, dan subtipe internal viewer seperti Popup bukan bagian dari kosakata XFDF
Untuk membuat round-trip setia, rekaman TPdfAnnotation diperluas dengan metadata yang diharapkan XFDF: Name (pengidentifikasi unik NM), Subject, ModificationDate, CreationDate, Icon, Opacity, titik akhir garis, simpul poligon dan poliline, serta jalur gestur tinta. Setiap bidang baru dipasangkan dengan sentinel boolean Has*, sehingga kode yang membangun anotasi terhadap versi sebelumnya tetap dapat dikompilasi dan tetap menghasilkan kamus yang sama — bidang yang tidak diatur tidak pernah ditulis. Jika Anda sudah membuat markup secara terprogram, rekaman yang sama yang Anda gunakan untuk anotasi markup teks dengan titik kuadran (quad points) sekarang membawa semua yang dibutuhkan XFDF
Bagaimana cara mengekspor data formulir dan anotasi ke XFDF?
Satu panggilan menangani seluruh dokumen. Muat PDF dengan pengisian formulir diaktifkan, panggil ExportXFDF, dan komponen akan menyusuri setiap halaman, mengumpulkan nilai bidang dan anotasi, serta menulis XML. Nilai pengembalian adalah jumlah byte UTF-8 yang ditulis, yang menjadi pemeriksaan kewajaran yang hemat di log
var
Pdf: TPdf;
Bytes: Integer;
begin
Pdf := TPdf.Create(Self);
Pdf.FormFill := True; // diperlukan agar nilai bidang aktif
Pdf.FileName := 'expense-report.pdf';
Pdf.Active := True;
Bytes := Pdf.ExportXFDF('expense-report.xfdf');
ShowMessage(Format('%d bytes of XFDF written', [Bytes]));
end;
Kedua arah memiliki overload TStream, sehingga tidak ada yang memaksa penggunaan berkas sementara di disk. Mengekspor ke TMemoryStream adalah bentuk yang alami ketika XFDF ditujukan untuk respons HTTP, blob database, atau entri arsip yang ditandatangani
var
Buffer: TMemoryStream;
begin
Buffer := TMemoryStream.Create;
try
Pdf.ExportXFDF(Buffer); // XML yang sama, tidak melibatkan berkas
Buffer.Position := 0;
// serahkan stream ke respons web, kolom blob, atau entri zip
finally
Buffer.Free;
end;
end;
Bagaimana ImportXFDF menggabungkan kembali komentar ke dalam dokumen?
Sisi impor adalah tempat alur kerja peninjau ditutup. Seorang kolega memberikan anotasi pada kontrak di Acrobat, mengekspor komentar sebagai XFDF, dan mengirimi Anda beberapa kilobyte XML alih-alih salinan kedua PDF. TPdf.ImportXFDF mengurai berkas tersebut, membuat setiap anotasi pada halaman yang disebut oleh atribut page miliknya, dan menulis nilai bidang ke dalam anotasi widget yang cocok. Fungsi ini mengembalikan jumlah gabungan dari bidang ditambah anotasi yang diterapkan, sehingga UI dapat mengonfirmasi dengan tepat berapa banyak yang tiba
var
Applied: Integer;
begin
Applied := Pdf.ImportXFDF('review-comments.xfdf');
StatusBar.SimpleText :=
Format('%d fields and annotations merged', [Applied]);
end;
Parser-nya adalah pemindai tag yang ditulis secara manual yang dibuat untuk toleransi alih-alih keketatan: elemen yang tidak dikenal dilewati, instruksi pemrosesan, deklarasi DOCTYPE, dan komentar diabaikan, nama bendera yang tidak dikenali dibuang, dan nilai atribut di-unescape melalui set lengkap referensi entitas XML dan karakter numerik, termasuk pasangan pengganti (surrogate pairs) UTF-16. XFDF yang dihasilkan oleh Acrobat, oleh viewer web, atau oleh alat lain digabungkan tanpa upacara. Begitu anotasi berada di dalam dokumen, siklus peninjauan berlanjut dengan mekanisme balasan dan status yang dijelaskan dalam membangun alur kerja peninjauan anotasi dengan PDFium Component, dan nilai bidang yang diimpor berpartisipasi dalam logika urutan tab normal yang dibahas dalam navigasi bidang formulir
Mengapa pemisah desimal penting untuk XFDF?
Setiap anotasi di XFDF diposisikan oleh string koordinat — rect="70.5,540,200,560" dan sejenisnya — dan ISO 19444-1 mensyaratkan titik sebagai pemisah desimal. Pemformatan float default Delphi mengikuti lokal Windows, sehingga pada sistem Jerman atau Prancis, fungsi FloatToStr yang sederhana mengubah 70.5 menjadi 70,5, yang merusak daftar koordinat yang dipisahkan koma menjadi sampah yang ditolak atau salah dibaca oleh prosesor lain. PDFium Component menormalisasi setiap angka yang ditulisnya: pemisah desimal lokal ditulis ulang menjadi titik dan nol di akhir dipangkas, sehingga berkas yang diekspor identik secara byte baik yang dihasilkan pada mesin en-US maupun de-DE. Jika Anda pernah mendebug alat PDF yang berfungsi di kantor tetapi gagal di situs pelanggan Eropa, Anda telah menemui kelas bug yang sama persis ini — patut diketahui bahwa komponen ini menanganinya untuk Anda
Apa batasan dari round-trip?
Dua batasan patut dinyatakan dengan jelas. Pertama, XFDF mentransfer data anotasi, bukan tampilan yang dirender — aliran tampilan (appearance streams) bukan bagian dari format, sehingga viewer penerima menghasilkan kembali setiap tampilan anotasi dari propertinya. Sorotan (highlight) atau persegi akan dirender dengan benar di mana-mana; stempel dengan tampilan kustom akan diturunkan ke apa yang digambar oleh viewer target untuk nama stempel tersebut. Kedua, API PDFium yang mendasarinya memiliki penyetel (setters) untuk string tetapi tidak untuk nomor anotasi atau geometri jalur, sehingga properti seperti Opacity, titik akhir garis, simpul, dan gestur tinta hanya dapat diekspor: komponen mempertahankannya dengan setia saat menulis XFDF, tetapi tidak dapat menulisnya kembali ke PDF saat impor. Nilai bidang, konten, warna, persegi panjang (rects), titik kuadran (quad points), tanggal, dan metadata identitas semuanya round-trip di kedua arah
Untuk memulai secara langsung, sampel XfdfLab disertakan dalam rangkaian demo Delphi, C++Builder, dan Lazarus serta menghubungkan kedua panggilan tersebut ke tombol di atas PDF apa pun yang Anda buka. Dukungan XFDF disertakan dalam rilis terbaru dari PDFium Component, bersama dengan API anotasi dan formulir yang menjadi dasarnya