All formats

PDFsharp

LanguageC# (.NET 8+, .NET Standard 2.0, .NET Framework 4.6.2+)
LicenseAGPL-3.0 or commercial since 6.5.0; versions up to 6.2.4 are MIT
Repositorygithub.com/empira/PDFsharp
Documentationdocs.pdfsharp.net
Depends onnothing for the Core build; GDI+ or WPF for the PDFsharp-gdi and PDFsharp-wpf builds
Read / writeyes / yes: create, import pages, merge, split, rotate, metadata, encryption, AcroForms; no text extraction or rendering

PDFsharp creates PDF documents with XGraphics, a drawing API modeled on GDI+ (strings, lines, shapes, images, transformations), and opens existing PDFs to modify them: import pages from other files, change page rotation and metadata, add content on top of existing pages, and encrypt with RC4 or AES-256. Version 6 is fully managed and cross-platform. MigraDoc, in the same repository, adds a document model with paragraphs, tables and automatic page breaks on top of PDFsharp.

License change: PDFsharp 6.5.0 moved from MIT to a dual AGPL-3.0 / commercial license, and your code must select the license at startup (PdfSharpLicense.SetAgplLicense() or PdfSharpLicense.LoadLicense(key)); otherwise PDFsharp throws a PdfSharpLicenseException. If you need a permissive license, stay on 6.2.4 (MIT), which has the same API as the examples below minus the license call.

PDFsharp can’t extract text or render pages. In the cross-platform Core build, fonts aren’t found automatically: on Windows set GlobalFontSettings.UseWindowsFontsUnderWindows = true, elsewhere implement an IFontResolver that returns font files.

Installation#

Shell
dotnet add package PDFsharp
# last MIT-licensed version
dotnet add package PDFsharp --version 6.2.4
# with MigraDoc for documents with paragraphs and tables
dotnet add package PDFsharp-MigraDoc

Basic usage: create a PDF with text#

C#
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Fonts;
using PdfSharp.Pdf;

PdfSharpLicense.SetAgplLicense();  // 6.5+: or PdfSharpLicense.LoadLicense(key) for a commercial license

// Core build: tell PDFsharp where fonts are (Windows only; use an IFontResolver elsewhere)
GlobalFontSettings.UseWindowsFontsUnderWindows = true;

var document = new PdfDocument();
document.Info.Title = "Hello";
PdfPage page = document.AddPage();  // A4 by default
XGraphics gfx = XGraphics.FromPdfPage(page);

var font = new XFont("Arial", 24, XFontStyleEx.Bold);
gfx.DrawString("Hello, PDF!", font, XBrushes.Black,
    new XRect(0, 0, page.Width.Point, page.Height.Point), XStringFormats.Center);
gfx.DrawLine(XPens.DarkBlue, 72, 100, 300, 100);  // origin is top-left, units are points

document.Save("hello.pdf");

How to merge PDF files#

Open the sources in Import mode and add their pages to a new document:

C#
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;

using var output = new PdfDocument();
foreach (string path in new[] { "a.pdf", "b.pdf" })
{
    using PdfDocument input = PdfReader.Open(path, PdfDocumentOpenMode.Import);
    foreach (PdfPage page in input.Pages)
        output.AddPage(page);
}
output.Save("merged.pdf");

How to split a PDF into pages#

C#
using PdfDocument input = PdfReader.Open("in.pdf", PdfDocumentOpenMode.Import);
for (int i = 0; i < input.PageCount; i++)
{
    using var single = new PdfDocument();
    single.AddPage(input.Pages[i]);
    single.Save($"page-{i + 1}.pdf");
}

How to rotate pages#

C#
using PdfDocument doc = PdfReader.Open("in.pdf", PdfDocumentOpenMode.Modify);
foreach (PdfPage page in doc.Pages)
    page.Rotate = (page.Rotate + 90) % 360;
doc.Save("rotated.pdf");

How to read PDF metadata#

C#
using PdfDocument doc = PdfReader.Open("in.pdf", PdfDocumentOpenMode.Import);
Console.WriteLine($"Pages: {doc.PageCount}, PDF {doc.Version / 10.0:F1}");
Console.WriteLine($"Title: {doc.Info.Title}");
Console.WriteLine($"Author: {doc.Info.Author}");
Console.WriteLine($"Producer: {doc.Info.Producer}");
Console.WriteLine($"Created: {doc.Info.CreationDate}");

How to encrypt and decrypt a PDF#

C#
using PdfDocument doc = PdfReader.Open("in.pdf", PdfDocumentOpenMode.Modify);
doc.SecuritySettings.UserPassword = "user";
doc.SecuritySettings.OwnerPassword = "owner";
doc.SecuritySettings.PermitModifyDocument = false;
doc.SecurityHandler.SetEncryptionToV5();  // AES-256
doc.Save("encrypted.pdf");

// decrypt: open with the owner password and save without passwords
using PdfDocument secret = PdfReader.Open("encrypted.pdf", "owner", PdfDocumentOpenMode.Modify);
secret.SecurityHandler.SetEncryptionToNoneAndResetPasswords();
secret.Save("decrypted.pdf");

Tips#