Panduan PDFsharp: Membuat File PDF dengan MigraDoc dan PdfSharpCore
PDFsharp adalah pustaka .NET sumber terbuka untuk membuat dan mengedit dokumen PDF dari kode C#. Anda menggambar teks, garis, dan gambar ke halaman, memanggil fungsi Simpan, dan Anda memiliki file PDF. Tidak ada mesin peramban, tidak ada biner asli. Proyek ini sudah ada sejak tahun 2005, dan banyak faktur, laporan, dan sertifikat yang dihasilkan dari backend .NET saat ini masih melalui pustaka ini.
Saya menulis ini untuk para pengembang yang membutuhkan PDF di server dan ingin mengetahui apa yang akan mereka hadapi. Kita akan membahas bagaimana PDFsharp dan MigraDoc saling terkait, versi mana yang harus diinstal, file kerja pertama, masalah font di Linux, perubahan lisensi terbaru, dan titik di mana Anda harus memilih alternatif lain.
Apa itu PDFsharp dan apa saja yang dapat dilakukannya?
Di balik pustaka PDFsharp terdapat empira Software GmbH, sebuah perusahaan kecil asal Jerman yang telah mempertahankan keberlangsungan proyek ini selama hampir dua puluh tahun. Sebagian besar waktu Anda dihabiskan untuk satu kelas, XGraphics. Jika Anda pernah melakukan rendering WinForms dengan System.Drawing.Graphics, Anda akan merasa nyaman dalam waktu sepuluh menit: font, kuas, x dan y, mulai.
Yang Anda dapatkan saat membuka kemasan adalah:
- Buat dokumen PDF dari awal dengan teks, bentuk vektor, garis, dan gambar.
- Buka file PDF yang sudah ada dan tambahkan konten ke halamannya, seperti stempel, tanda air, atau nomor halaman.
- Gabungkan dan pisahkan dokumen dengan mengimpor halaman dari satu file ke file lainnya.
- Sematkan dan subset font agar file terlihat sama di setiap mesin.
- Tambahkan bookmark, tautan, dan metadata dokumen seperti judul, penulis, dan kata kunci.
- Lindungi file dengan kata sandi dan bendera izin.
- Menandatangani dokumen secara digital (sejak rilis versi 6.2)
Penyebarannya membosankan, dan saya mengatakannya sebagai pujian. Semuanya menggunakan kode terkelola, jadi petugas operasional Anda tidak perlu lagi memasang Chrome tanpa antarmuka grafis di server atau mencari DLL Ghostscript pada pukul 2 pagi. Anda hanya perlu merujuk satu paket NuGet, melakukan push, dan selesai.
Nah, inilah masalahnya. Anda hanya mendapatkan kanvas dan tidak lebih. Paragraf panjang mencapai margin bawah? Itu masalah Anda. Tabel melampaui halaman pertama? Itu juga masalah Anda, kecuali Anda menggunakan MigraDoc.
PDFsharp dan MigraDoc: Lapisan Mana yang Anda Butuhkan?
Vendor yang sama, jadwal rilis yang sama, tetapi pekerjaan yang sangat berbeda. MigraDoc Foundation berada satu lantai di atas PDFsharp. Alih-alih memberi tahu di mana sebuah string harus ditempatkan, Anda memberikannya bagian, paragraf, tabel, header, footer, gaya, dan beberapa bagan, dan ia akan menentukan di mana semuanya akan ditempatkan. Hasilnya adalah PDF. Atau RTF, untuk kolega yang bersikeras membuka semuanya di Word.
Singkatan saya: PDFsharp artinya "letakkan teks ini di x=40, y=120." MigraDoc artinya "ini ada tiga puluh baris dan header yang berulang, Anda urutkan halamannya sendiri."
| Tugas | Paling cocok | Mengapa |
|---|---|---|
| Sertifikat atau tiket satu halaman dengan posisi tetap. | PDFsharp | Kontrol penuh atas setiap koordinat |
| Laporan multi-halaman dengan tabel dan header yang berkesinambungan | MigraDoc | Paginasi dan gaya otomatis |
| Faktur dengan jumlah item baris yang bervariasi | MigraDoc | Tabel membesar dan terpecah di beberapa halaman. |
| Cap, tanda air, atau nomor halaman pada PDF yang sudah ada. | PDFsharp | MigraDoc hanya membuat dokumen baru. |
| Gabungkan atau pisahkan file yang sudah ada. | PDFsharp | Impor halaman adalah fitur PDFsharp. |
| Bagan bisnis di dalam laporan | MigraDoc | Dukungan grafik bawaan |
| Campuran: laporan yang dihasilkan ditambah sampul yang dirancang khusus. | Keduanya | MigraDoc dapat merender ke halaman PDFsharp |
Proyek nyata cenderung menggunakan keduanya. Teks isi melalui MigraDoc, sampul yang digambar tangan atau stempel pada PDF dari vendor tertentu melalui lapisan bawah. Anda tetap tidak dapat menghindari instalasi PDFsharp, karena paket MigraDoc menyertakannya sebagai dependensi.
Penjelasan tentang Versi PDFsharp: Versi Inti, GDI+, dan WPF
Pendatang baru biasanya akan menemui kendala di urutan berikutnya dalam daftar paket di NuGet. PDFsharp 6 hadir dalam tiga versi, masing-masing dengan kembaran MigraDoc-nya sendiri.
| Paket NuGet | Membangun | Platform | Font dan gambar |
|---|---|---|---|
| PDFsharp / PDFsharp-MigraDoc | Inti | Windows, Linux, macOS | Membutuhkan pengurai font; gambar BMP, PNG, JPEG |
| PDFsharp-GDI / PDFsharp-MigraDoc-GDI | GDI+ | Hanya untuk Windows | Menggunakan font yang terpasang melalui System.Drawing |
| PDFsharp-WPF / PDFsharp-MigraDoc-WPF | WPF | Hanya untuk Windows | Menggunakan font yang terpasang melalui WPF |
Paket-paket saat ini menargetkan .NET 8, 9, dan 10, ditambah .NET Standard 2.0 dan .NET Framework 4.6.2. Jadi, hampir semua hal yang masih dalam pengembangan tercakup, mulai dari alat WinForms yang sudah usang hingga API ASP.NET Core yang baru.
Aplikasi konsol, API web, Docker, Azure Functions, apa pun di Linux? Build inti. GDI+ atau WPF hanya masuk akal untuk aplikasi desktop Windows di mana Anda menginginkan font sistem atau pratinjau dalam kontrol asli. Seseorang di Stack Overflow pernah bertanya apakah aplikasi konsol mereka membutuhkan versi WPF. Ternyata tidak.

Cara Menginstal PDFsharp dari NuGet di Visual Studio
Anda masih akan menemukan postingan forum dari era WinForms yang menyuruh Anda untuk mengambil file ZIP, mencari file DLL, dan menambahkan referensi sendiri. Abaikan saja. Instal PDFsharp melalui NuGet; pengelola paket melacak versi sehingga Anda tidak perlu melakukannya sendiri.
- Buka solusi Anda di Visual Studio dan klik kanan proyek di Penjelajah Solusi.
- Pilih Kelola Paket NuGet , beralih ke tab Jelajahi , dan cari "PDFsharp".
- Pilih PDFsharp (Core build) atau PDFsharp-MigraDoc jika Anda juga memerlukan tata letak dokumen. Pastikan penerbitnya adalah empira Software GmbH.
- Klik Instal dan terima permintaan lisensi.
- Bangun proyek sekali untuk memastikan paket telah dipulihkan dengan benar.
Pengguna terminal dapat melewati proses klik:
bash dotnet add package PDFsharp dotnet add package PDFsharp-MigraDoc
Di dalam Package Manager Console, perintahnya adalah Install-Package PDFsharp. Dan tolong jangan mencampur build. Saya pernah melihat sebuah tim kehilangan waktu seharian penuh karena konflik tipe data akibat satu proyek mereferensikan PDFsharp dan proyek sebelahnya menggunakan PDFsharp-GDI.
Dokumen PDF Pertama Anda dengan PDFsharp di C
Berikut ini adalah program terkecil yang menghasilkan file PDF satu halaman. Program ini berjalan pada versi Core di sistem operasi apa pun, selama resolusi font telah diatur (bagian selanjutnya).
```csharp
menggunakan PdfSharp.Drawing;
menggunakan PdfSharp.Pdf;
// PDFsharp 6.5+ memerlukan pemilihan lisensi sebelum penggunaan pertama.
PdfSharpLicense.SetAgplLicense();
var document = new PdfDocument();
document.Info.Title = "Halo PDFsharp";
PdfPage page = document.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(page);
var font = new XFont("Arial", 20, XFontStyleEx.Bold);
gfx.DrawString("Halo, PDFsharp!", font, XBrushes.Black,
XRect baru(0, 0, page.Width.Point, page.Height.Point),
XStringFormats.Center);
dokumen.Simpan("halo.pdf");
```
Setiap program PDFsharp mengikuti struktur ini: dokumen, halaman, XGraphics, gambar, simpan. Satuannya adalah poin (1/72 inci) dan titik asalnya berada di pojok kiri atas. Pada versi 6.2.x, hapus baris lisensi. API tersebut baru muncul di versi 6.5.0.
Dan versi MigraDoc:
```csharp
menggunakan MigraDoc.DocumentObjectModel;
menggunakan MigraDoc.Rendering;
var doc = new Document();
Bagian section = doc.AddSection();
section.AddParagraph("Halo, MigraDoc!");
var renderer = PdfDocumentRenderer baru { Document = doc };
renderer.RenderDocument();
renderer.PdfDocument.Save("hello-migradoc.pdf");
```
Tidak ada koordinat di mana pun. Masukkan 500 paragraf dan Anda akan mendapatkan jumlah halaman yang dibutuhkan, tanpa kode penomoran halaman sama sekali.
Font dalam PDFsharp Core Build: Masalah Resolver
Coba tanyakan pada orang-orang, dan keluhan yang paling sering Anda dengar adalah tentang font. Build GDI+ dan WPF hanya membaca font TrueType yang terinstal dari Windows. Build Core tidak dapat berasumsi apa pun, karena kontainer Linux yang ramping seringkali tidak memiliki font yang dapat digunakan sama sekali. Jadi, penyebaran Docker pertama cenderung berakhir dengan pengecualian karena tidak ditemukan font yang sesuai.
Solusinya adalah sebuah font resolver, sebuah kelas yang mengimplementasikan IFontResolver. Kelas ini memiliki dua metode:
- ResolveTypeface memetakan keluarga dan gaya yang diminta (misalnya, "Arial", tebal) ke nama font.
- GetFont mengembalikan byte mentah dari file TTF untuk nama font tersebut.
Daftarkan sekali saat startup melalui GlobalFontSettings.FontResolver, sebelum XFont pertama dibuat.
```csharp
kelas publik AppFontResolver : IFontResolver
{
public FontResolverInfo? ResolveTypeface(string family, bool bold, bool italic)
=> new FontResolverInfo(bold ? "Inter-Bold" : "Inter-Regular");
public byte[]? GetFont(string faceName) => File.ReadAllBytes(Path.Combine(AppContext.BaseDirectory, "Fonts", faceName + ".ttf"));
}
GlobalFontSettings.FontResolver = new AppFontResolver();
```
Hal-hal penting yang perlu diketahui sebelum Anda mengalaminya sendiri:
- Simpan file TTF Anda di folder Fonts dalam proyek dan atur agar disalin ke direktori output, atau sematkan sebagai sumber daya sehingga citra kontainer selalu memilikinya.
- Rilis 6.2.0 menghapus CoreBuildFontResolver yang lama. Di Windows atau WSL2, Anda dapat mengembalikan perilaku serupa dengan GlobalFontSettings.UseWindowsFontsUnderWindows, tetapi ini tidak berpengaruh pada Linux atau macOS.
- Repositori sampel resmi menyertakan SubstitutingFontResolver yang dapat Anda salin sebagai titik awal.
- Periksa lisensi font sebelum menyematkan jenis huruf komersial ke dalam file yang dihasilkan. Font open source seperti Inter, Roboto, atau Noto sama sekali menghindari pertanyaan ini.
Dengan adanya resolver, output akan terlihat identik di Windows, Linux, dan macOS.
Menggabungkan, Menandatangani, dan Mengamankan File dengan PDFsharp 6
Banyak tim yang tidak pernah membuat dokumen dari awal. Mereka menggunakan pustaka untuk menggabungkan, memberi cap, atau mengunci file yang sudah ada. Penggabungan hanya membutuhkan beberapa baris kode: buka setiap sumber dalam mode impor dan salin halamannya.
csharp var output = new PdfDocument(); foreach (var path in new[] { "part1.pdf", "part2.pdf" }) { using var input = PdfReader.Open(path, PdfDocumentOpenMode.Import); foreach (PdfPage p in input.Pages) output.AddPage(p); } output.Save("merged.pdf");
Pemisahan adalah proses yang sama tetapi terbalik, satu file keluaran per halaman atau rentang. Untuk perlindungan, document.SecuritySettings memerlukan kata sandi pengguna, kata sandi pemilik, dan flag izin (cetak, salin teks, dan sebagainya).
Dua fitur yang sudah lama diminta akhirnya hadir di versi 6.2:
- Tanda tangan digital berbasis CMS. Penandatangan default disertakan dalam assembly PDFsharp.Cryptography terpisah, dan Anda dapat memasukkan penandatangan Anda sendiri dengan mengimplementasikan IDigitalSigner. Dukungan server stempel waktu berfungsi pada .NET modern tetapi tidak pada versi .NET Framework.
- Output PDF/A untuk pengarsipan. Dokumentasi resmi menyebutkan bahwa fitur ini berfungsi "dengan beberapa keterbatasan" dan masih dalam pengembangan, jadi validasi hasilnya dengan pemeriksa PDF/A sebelum mengandalkannya untuk kepatuhan.
Rilis tersebut juga menghadirkan glif emoji berwarna dan implementasi MD5 terkelola, yang penting jika Anda menjalankan sistem di bawah aturan FIPS atau di Blazor.
Repositori PDFsharp, Fork PDFSharpCore, dan Versi 1.x
Cari PDFsharp di GitHub dan Anda akan menemukan beberapa proyek dengan nama yang hampir sama. Salahkan sejarah.
Versi lama 1.x (1.50, 1.51) hanya berjalan di .NET Framework. Ketika .NET Core keluar, orang-orang tidak ingin menunggu, jadi mereka memportingnya sendiri. PdfSharpCore, yang dimulai oleh Stefan Steiger dan kemudian dikembangkan oleh fork lain, adalah yang paling dikenal banyak orang. PdfSharpCore menghilangkan GDI+ dan membuat kode berjalan di Linux bertahun-tahun sebelum rilis resmi.
Kemudian PDFsharp 6 hadir: penulisan ulang yang tepat pada .NET modern dengan build Core lintas platform resmi. Berbagai fork kehilangan sebagian besar alasan keberadaannya.
| Proyek | Pengelola | Platform | Status |
|---|---|---|---|
| PDFsharp 6.x (repositori empira/PDFsharp) | empira Software GmbH | .NET 8–10, .NET Standard 2.0, .NET Framework 4.6.2 | Dipelihara secara aktif |
| PDFsharp 1.5x | empira Software GmbH | Hanya .NET Framework | Kode sumber disimpan di GitHub, tetapi tidak lagi dipelihara. |
| PdfSharpCore dan turunannya | Masyarakat | .NET Core / .NET Standard 2.0 | Berbeda-beda tergantung cabang (fork), pembaruan lebih lambat. |
| PDFsharp-MigraDoc 6.x | empira Software GmbH | Sama seperti PDFsharp 6 | Dipelihara secara aktif |
Jadi, perdebatan "PdfSharp vs PdfSharpCore" yang terus muncul di Reddit? Proyek baru, paket resmi. Pertahankan fork hanya jika kode lama sudah bergantung padanya dan migrasi tidak sepadan dengan waktu pengerjaan yang dibutuhkan saat ini. Dan jika dokumentasinya terasa kurang lengkap, kunjungi repositori sampel terpisah milik Empira. Folder dan file-nya berisi contoh yang dapat dijalankan, yang jauh lebih baik daripada menebak-nebak.
Apakah PDFsharp Gratis? Perubahan Lisensi di PDFsharp 6.5
Selama sebagian besar masa hidupnya, ya. Perangkat lunak ini berlisensi MIT, yang berarti penggunaan komersial hampir tanpa ikatan. Setiap rilis hingga versi 6.2.4 masih demikian.
Versi 6.5.0 mengubah hal itu. Pustaka tersebut sekarang memiliki lisensi ganda:
- AGPL (gratis). Anda mengaktifkannya dengan memanggil PdfSharpLicense.SetAgplLicense() sebelum menggunakan pustaka. AGPL mengharuskan Anda untuk menyediakan kode sumber Anda kepada pengguna, termasuk pengguna yang berinteraksi dengan perangkat lunak Anda melalui jaringan, sehingga tidak cocok untuk SaaS sumber tertutup.
- Lisensi komersial. Anda membeli kunci lisensi dari vendor dan memuatnya dengan PdfSharpLicense.LoadLicense(...). Ini menghilangkan kewajiban AGPL.
Mulai versi 6.5.0, kode Anda harus memilih salah satunya secara eksplisit. Pratinjau versi 7.0 bekerja dengan cara yang sama.
Dalam praktiknya:
- Proyek sumber terbuka yang kompatibel dengan AGPL dapat terus menggunakan versi terbaru secara gratis.
- Produk sumber tertutup dapat memilih untuk membeli lisensi komersial atau tetap menggunakan versi 6.2.x, yang masih berada di bawah lisensi MIT. Tetap menggunakan versi tersebut berarti kehilangan perbaikan di masa mendatang, jadi pertimbangkan biaya tersebut dengan jujur.
- Apa pun pilihan Anda, bacalah teks lisensi yang sebenarnya dan mintalah persetujuan dari tim hukum Anda. Panduan ini bukan merupakan nasihat hukum.

Kelemahan PDFsharp dan Kombinasi yang Tepat Untuknya
Pustaka tersebut menjalankan tugasnya dengan baik. Hanya saja cakupan tugasnya sempit, dan celah yang sama muncul di setiap utas forum.
- Tidak ada konversi HTML ke PDF. PDFsharp tidak merender HTML atau CSS. Add-on komunitas, HtmlRenderer.PdfSharp, memang ada tetapi hanya mendukung HTML 4.01 dan CSS level 2, sehingga tata letak modern dengan flexbox atau grid tidak akan berfungsi. Tim yang membutuhkan template HTML biasanya menggunakan renderer headless-browser sebagai gantinya.
- Tidak ada JavaScript. Grafik atau konten yang dibuat di sisi klien tidak dapat ditangkap.
- Tidak ada rendering ke gambar. PDFsharp tidak dapat mengubah halaman PDF menjadi PNG untuk thumbnail atau pratinjau. Anda memerlukan rasterizer terpisah untuk itu.
- Ekstraksi teks terbatas. Anda dapat menelusuri aliran konten, tetapi tidak ada API tingkat tinggi yang mengembalikan teks bersih dengan posisi. PdfPig, sebuah pustaka sumber terbuka terpisah, dibangun khusus untuk membaca dan mengekstrak teks.
- Dukungan formulir sebagian. Pengisian AcroForm sederhana berfungsi; formulir kompleks dengan skrip adalah cerita lain.
- Tabel memerlukan MigraDoc. Dengan PDFsharp biasa, Anda menghitung sendiri tinggi setiap baris.
Itu bukan berarti pilihan yang buruk. Dokumen berbasis data seperti faktur, laporan, label, dan sertifikat adalah keunggulan utamanya, dan ukurannya sangat kecil. Salinan halaman web yang sempurna hingga ke tingkat piksel bukanlah hal yang mudah.
PDFsharp untuk Faktur Kripto dan Tanda Terima Pembayaran
Struk pembayaran mungkin adalah hal paling umum yang dibuat orang dengan PDFsharp. Struk pembayaran kripto sedikit lebih rumit daripada struk pembayaran kartu. Kabar baiknya: begitu gateway mencapai webhook Anda (panggilan balik HTTP yang dikirim saat status pembayaran berubah), Anda sudah mendapatkan semua data. Tidak perlu mencari data tambahan.
Apa yang akan saya tulis di salah satunya:
- ID pesanan atau faktur dan detail pedagang.
- Jumlah dalam mata uang kripto dan nilai setara dalam mata uang fiat pada saat pembayaran.
- Koin dan jaringan (misalnya, USDT di TRON versus USDT di Ethereum)
- Hash transaksi, sehingga pelanggan dapat memverifikasinya di penjelajah blok.
- Alamat dompet penerima yang dipersingkat dan waktu konfirmasi
- Kode QR yang mengarah ke halaman transaksi atau faktur.
Gunakan font Monospace untuk hash dan alamat. Pelanggan akan menyipitkan mata saat membacanya satu karakter demi satu karakter, dan dalam font Arial, angka nol dan huruf O kapital terlihat seperti kembar. Jika hash terlalu lebar, bungkus teksnya; teks 6pt tidak membantu siapa pun. Sematkan font, simpan file bersama pesanan, dan tanda tangani jika akuntan Anda meminta tanda terima.
Semua itu belum mencakup proses pengambilan uang. Untuk bagian itu, Anda bisa menggunakan gateway seperti Plisio . Gateway ini menerima BTC, USDT, dan banyak koin lainnya, membuat faktur, dan memanggil endpoint Anda setiap kali status berubah. Handler Anda meneruskan payload ke MigraDoc dan pembeli akan mendapatkan tanda terima dengan logo Anda saat mereka masih berada di halaman terima kasih.
Kesimpulan
Saya terus kembali menggunakan PDFsharp karena satu alasan: ukurannya kecil dan tidak mengganggu. Versi Core berjalan di mana pun .NET berjalan, dan MigraDoc mengambil alih pekerjaan tata letak ketika kanvas tidak cukup. Tiga hal yang perlu diputuskan sejak awal: versi mana yang digunakan, bagaimana font dimuat, dan lisensi mana yang Anda gunakan sekarang setelah versi 6.5 beralih ke AGPL. Cetak data, bukan halaman web, dan perangkat lunak ini akan bertahan selama bertahun-tahun.