PDFsharp-Leitfaden: PDF-Dateien mit MigraDoc und PdfSharpCore erstellen
PDFsharp ist eine Open-Source-.NET-Bibliothek zum Erstellen und Bearbeiten von PDF-Dokumenten aus C#-Code. Man zeichnet Text, Linien und Bilder auf eine Seite, ruft „Speichern“ auf und erhält eine PDF-Datei. Keine Browser-Engine, keine native Binärdatei. Das Projekt existiert seit 2005, und viele Rechnungen, Berichte und Zertifikate, die heute noch von .NET-Backends erstellt werden, laufen über PDFsharp.
Ich habe diesen Text für Entwickler geschrieben, die PDFs auf dem Server benötigen und wissen möchten, worauf sie sich einlassen. Wir behandeln die Zusammenarbeit von PDFsharp und MigraDoc, die richtige Installationsversion, die Erstellung einer ersten funktionierenden Datei, die Schwierigkeiten mit Schriftarten unter Linux, die kürzliche Lizenzänderung und den Zeitpunkt, an dem Sie sich für eine andere Lösung entscheiden sollten.
Was ist PDFsharp und was kann es leisten?
Hinter der PDFsharp-Bibliothek steht die empira Software GmbH, ein kleines deutsches Unternehmen, das das Projekt seit fast zwanzig Jahren am Leben erhält. Die meiste Zeit verbringen Sie mit einem Kurs: XGraphics. Wenn Sie schon einmal mit System.Drawing.Graphics in WinForms gezeichnet haben, werden Sie sich innerhalb von zehn Minuten zurechtfinden: Schriftart, Pinsel, x- und y-Koordinaten – und los geht's.
Im Lieferumfang enthalten:
- Erstellen Sie PDF-Dokumente von Grund auf mit Text, Vektorformen, Linien und Bildern
- Öffnen Sie vorhandene PDF-Dateien und fügen Sie deren Seiten Inhalte hinzu, wie z. B. Stempel, Wasserzeichen oder Seitenzahlen.
- Dokumente zusammenführen und aufteilen, indem Seiten aus einer Datei in eine andere importiert werden
- Schriftarten einbetten und Teilmengen festlegen , damit die Datei auf jedem Rechner gleich aussieht.
- Fügen Sie Lesezeichen, Links und Dokumentmetadaten wie Titel, Autor und Schlüsselwörter hinzu.
- Schützen Sie Dateien mit Passwörtern und Berechtigungsflags.
- Dokumente digital signieren (seit Version 6.2)
Die Bereitstellung ist kinderleicht, und das meine ich positiv. Alles ist verwalteter Code, sodass Ihr Systemadministrator nie Headless Chrome auf einem Rechner installieren oder nachts um 2 Uhr nach einer Ghostscript-DLL suchen muss. Sie referenzieren ein NuGet-Paket, pushen es, fertig.
Und jetzt der Haken: Sie erhalten nur eine Arbeitsfläche. Ein langer Absatz reicht bis zum unteren Rand? Ihr Problem. Eine Tabelle ragt über die erste Seite hinaus? Auch Ihr Problem, es sei denn, Sie verwenden MigraDoc.
PDFsharp und MigraDoc: Welche Ebene benötigen Sie?
Derselbe Anbieter, derselbe Veröffentlichungsplan, aber völlig unterschiedliche Aufgaben. MigraDoc Foundation ist eine Stufe höher angesiedelt als PDFsharp. Anstatt die Position eines Textabschnitts anzugeben, übergibt man Abschnitte, Absätze, Tabellen, Kopf- und Fußzeilen, Formatvorlagen und gelegentlich auch Diagramme – und MigraDoc Foundation findet automatisch heraus, wo alles landet. Heraus kommt eine PDF-Datei. Oder eine RTF-Datei für den Kollegen, der unbedingt alles in Word öffnen möchte.
Meine Kurzform: PDFsharp bedeutet „diesen Text an der Position x=40, y=120 einfügen“. MigraDoc bedeutet „hier sind dreißig Zeilen und eine sich wiederholende Kopfzeile; sortieren Sie die Seiten aus“.
| Aufgabe | Optimale Passform | Warum |
|---|---|---|
| Einseitiges Zertifikat oder Ticket mit festen Positionen | PDFsharp | Volle Kontrolle über jede Koordinate |
| Mehrseitiger Bericht mit Tabellen und Kopfzeilen | MigraDoc | Automatische Seitennummerierung und Stile |
| Rechnung mit variabler Anzahl von Positionen | MigraDoc | Tabellen dehnen sich aus und brechen über mehrere Seiten hinweg. |
| Stempel, Wasserzeichen oder Seitenzahlen in bestehende PDF-Dateien einfügen | PDFsharp | MigraDoc erstellt nur neue Dokumente |
| Vorhandene Dateien zusammenführen oder aufteilen | PDFsharp | Der Seitenimport ist eine Funktion von PDFsharp. |
| Geschäftsdiagramm in einem Bericht | MigraDoc | Integrierte Diagrammunterstützung |
| Gemischt: generierter Bericht plus individuell gestaltetes Deckblatt | Beide | MigraDoc kann auf einer PDFsharp-Seite rendern |
In realen Projekten kommt meist beides zum Einsatz. Der Fließtext wird über MigraDoc eingefügt, ein handgezeichnetes Deckblatt oder ein Stempel auf einem PDF eines Anbieters über die untere Ebene. Die Installation von PDFsharp ist ohnehin unvermeidlich, da das MigraDoc-Paket es als Abhängigkeit mitbringt.
PDFsharp-Builds erklärt: Core Build, GDI+ und WPF
Neulinge landen in der Regel als nächstes in der Paketliste von NuGet. PDFsharp 6 gibt es in drei Versionen, jede mit ihrem eigenen MigraDoc-Pendant.
| NuGet-Paket | Bauen | Plattformen | Schriftarten und Bilder |
|---|---|---|---|
| PDFsharp / PDFsharp-MigraDoc | Kern | Windows, Linux, macOS | Benötigt einen Font-Resolver; BMP-, PNG- und JPEG-Bilder |
| PDFsharp-GDI / PDFsharp-MigraDoc-GDI | GDI+ | Nur für Windows | Verwendet installierte Schriftarten über System.Drawing |
| PDFsharp-WPF / PDFsharp-MigraDoc-WPF | WPF | Nur für Windows | Verwendet installierte Schriftarten über WPF |
Die aktuellen Pakete zielen auf .NET 8, 9 und 10 sowie .NET Standard 2.0 und .NET Framework 4.6.2 ab. Damit ist so gut wie alles abgedeckt, woran noch gearbeitet wird – von einem veralteten WinForms-Tool bis hin zu einer brandneuen ASP.NET Core-API.
Konsolenanwendung, Web-API, Docker, Azure Functions – alles unter Linux? Core-Build. GDI+ oder WPF sind nur für Windows-Desktopanwendungen sinnvoll, bei denen Systemschriftarten oder eine Vorschau in einem nativen Steuerelement benötigt werden. Jemand fragte einmal auf Stack Overflow, ob seine Konsolenanwendung die WPF-Version benötige. Die Antwort war: Nein.

So installieren Sie PDFsharp über NuGet in Visual Studio
Sie werden immer noch Forenbeiträge aus der WinForms-Ära finden, die Ihnen raten, eine ZIP-Datei herunterzuladen, eine DLL-Datei herauszusuchen und die Referenz selbst hinzuzufügen. Ignorieren Sie diese. Installieren Sie PDFsharp über NuGet; der Paketmanager verwaltet die Versionen, sodass Sie sich darum nicht kümmern müssen.
- Öffnen Sie Ihre Projektmappe in Visual Studio und klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt.
- Wählen Sie „NuGet-Pakete verwalten“ , wechseln Sie zur Registerkarte „Durchsuchen “ und suchen Sie nach „PDFsharp“.
- Wählen Sie PDFsharp (Core-Version) oder PDFsharp-MigraDoc, falls Sie auch ein Dokumentlayout benötigen. Prüfen Sie, ob der Herausgeber empira Software GmbH ist.
- Klicken Sie auf „Installieren“ und akzeptieren Sie die Lizenzanfrage.
- Erstellen Sie das Projekt einmal, um zu bestätigen, dass das Paket korrekt wiederhergestellt wurde.
Terminalnutzer können das Klicken überspringen:
bash dotnet add package PDFsharp dotnet add package PDFsharp-MigraDoc
In der Paket-Manager-Konsole heißt der Befehl „Install-Package PDFsharp“. Bitte mischen Sie keine Builds. Ich habe schon erlebt, wie ein Team einen ganzen Nachmittag mit Typkonflikten verbracht hat, weil ein Projekt auf PDFsharp verwies und das Nachbarprojekt PDFsharp-GDI einband.
Ihr erstes PDF-Dokument mit PDFsharp in C
Im Folgenden wird das kleinste Programm beschrieben, das eine einseitige PDF-Datei erzeugt. Es läuft auf der Core-Version unter jedem Betriebssystem, sofern ein Font-Resolver eingerichtet ist (nächster Abschnitt).
```csharp
mit PdfSharp.Drawing;
Verwendung von PdfSharp.Pdf;
// PDFsharp 6.5+ erfordert die Auswahl einer Lizenz vor der ersten Verwendung
PdfSharpLicense.SetAgplLicense();
var document = new PdfDocument();
document.Info.Title = "Hallo PDFsharp";
PdfPage page = document.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(page);
var font = new XFont("Arial", 20, XFontStyleEx.Bold);
gfx.DrawString("Hallo, PDFsharp!", font, XBrushes.Black,
new XRect(0, 0, page.Width.Point, page.Height.Point),
XStringFormats.Center);
document.Save("hello.pdf");
```
Jedes PDFsharp-Programm folgt diesem Schema: Dokument, Seite, XGraphics, Zeichnen, Speichern. Die Einheiten sind Punkte (1/72 Zoll), und der Ursprung befindet sich in der oberen linken Ecke. In Version 6.2.x muss die Lizenzzeile entfernt werden. Diese API wurde erst in Version 6.5.0 eingeführt.
Und die MigraDoc-Version:
```csharp
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
var doc = new Document();
Abschnitt Abschnitt = doc.AddSection();
section.AddParagraph("Hallo, MigraDoc!");
var renderer = new PdfDocumentRenderer { Document = doc };
renderer.RenderDocument();
renderer.PdfDocument.Save("hello-migradoc.pdf");
```
Keine Koordinaten. Füge 500 Absätze hinzu, und du erhältst die benötigte Seitenzahl – ganz ohne Paginierungscode.
Schriftarten in der PDFsharp Core-Version: Das Resolver-Problem
Fragt man herum, hört man am häufigsten Beschwerden über Schriftarten. GDI+- und WPF-Builds lesen einfach die installierten TrueType-Schriftarten von Windows. Der Core-Build kann nichts voraussetzen, da ein schlanker Linux-Container oft gar keine verwendbaren Schriftarten enthält. Daher endet der erste Docker-Deployment meist mit einer Ausnahme, dass keine passende Schriftart gefunden wurde.
Die Lösung ist ein Font-Resolver, eine Klasse, die IFontResolver implementiert. Sie verfügt über zwei Methoden:
- ResolveTypeface ordnet eine angeforderte Schriftfamilie und einen Schriftschnitt (z. B. „Arial“, fett) einem Schriftschnittnamen zu.
- GetFont gibt die Rohbytes der TTF-Datei für diesen Schriftartnamen zurück.
Registrieren Sie es einmalig beim Start über GlobalFontSettings.FontResolver, bevor die erste XFont erstellt wird.
```csharp
public class 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();
```
Dinge, die man wissen sollte, bevor man selbst darauf trifft:
- Speichern Sie Ihre TTF-Dateien in einem Fonts-Ordner im Projekt und legen Sie fest, dass sie in das Ausgabeverzeichnis kopiert werden, oder betten Sie sie als Ressourcen ein, damit das Container-Image sie immer enthält.
- Mit Version 6.2.0 wurde der alte CoreBuildFontResolver entfernt. Unter Windows oder WSL2 lässt sich ein ähnliches Verhalten mit GlobalFontSettings.UseWindowsFontsUnderWindows wiederherstellen, unter Linux oder macOS hat dies jedoch keine Auswirkung.
- Das offizielle Beispiel-Repository enthält einen SubstitutingFontResolver, den Sie als Ausgangspunkt kopieren können.
- Prüfen Sie die Schriftlizenz, bevor Sie eine kommerzielle Schriftart in generierte Dateien einbetten. Offene Schriftarten wie Inter, Roboto oder Noto umgehen dieses Problem von vornherein.
Mit dem Resolver ist die Ausgabe unter Windows, Linux und macOS identisch.
Zusammenführen, Signieren und Sichern von Dateien mit PDFsharp 6
Viele Teams erstellen Dokumente nie von Grund auf neu. Sie nutzen die Bibliothek, um bereits vorhandene Dateien zusammenzuführen, zu kennzeichnen oder zu sperren. Das Zusammenführen ist mit wenigen Zeilen Code erledigt: Jede Quelle im Importmodus öffnen und die Seiten kopieren.
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");
Die Aufteilung erfolgt im umgekehrten Ablauf, wobei pro Seite oder Bereich eine Ausgabedatei erstellt wird. Zum Schutz benötigt document.SecuritySettings ein Benutzerpasswort, ein Besitzerpasswort und Berechtigungsflags (Drucken, Text kopieren usw.).
Zwei lang ersehnte Funktionen haben es endlich in die Version 6.2 geschafft:
- Digitale Signaturen basieren auf CMS. Ein Standardsignaturprogramm ist in der separaten Assembly PDFsharp.Cryptography enthalten; Sie können Ihr eigenes Programm durch Implementierung von IDigitalSigner einbinden. Die Unterstützung für Zeitstempelserver funktioniert unter modernen .NET-Versionen, jedoch nicht unter der .NET Framework-Version.
- PDF/A-Ausgabe für die Archivierung. Die offizielle Dokumentation beschreibt die Funktion als „mit einigen Einschränkungen“ funktionierend und noch in der Entwicklung. Überprüfen Sie daher das Ergebnis mit einem PDF/A-Prüfprogramm, bevor Sie sich im Hinblick auf die Konformität darauf verlassen.
Mit dieser Version wurden auch farbige Emoji-Glyphen und eine verwaltete MD5-Implementierung eingeführt, was wichtig ist, wenn Sie unter FIPS-Regeln oder in Blazor arbeiten.
PDFsharp-Repository, PdfSharpCore-Forks und Versionen 1.x
Sucht man auf GitHub nach PDFsharp, findet man eine ganze Reihe von Projekten mit fast demselben Namen. Schuld daran ist die Geschichte.
Die alte 1.x-Reihe (1.50, 1.51) lief nur unter .NET Framework. Als .NET Core erschien, wollten die Entwickler nicht warten und portierten die Software daher selbst. PdfSharpCore, ein Projekt von Stefan Steiger, das später von anderen Forks weiterentwickelt wurde, ist die bekannteste Version. Sie entfernte GDI+ und ermöglichte die Ausführung des Codes unter Linux Jahre vor der offiziellen Veröffentlichung.
Dann erschien PDFsharp 6: eine vollständige Neuentwicklung auf Basis des modernen .NET mit einem offiziellen plattformübergreifenden Core-Build. Die Forks verloren damit weitgehend ihre Daseinsberechtigung.
| Projekt | Instandhalter | Plattformen | Status |
|---|---|---|---|
| PDFsharp 6.x (empira/PDFsharp-Repository) | empira Software GmbH | .NET 8–10, .NET Standard 2.0, .NET Framework 4.6.2 | Aktiv gepflegt |
| PDFsharp 1.5x | empira Software GmbH | Nur .NET Framework | Der Quellcode befindet sich weiterhin auf GitHub, wird aber nicht mehr gepflegt. |
| PdfSharpCore und seine Abspaltungen | Gemeinschaft | .NET Core / .NET Standard 2.0 | Variiert je nach Fork, langsamere Updates |
| PDFsharp-MigraDoc 6.x | empira Software GmbH | Dasselbe wie PDFsharp 6 | Aktiv gepflegt |
Also, der Thread „PdfSharp vs. PdfSharpCore“, der immer wieder auf Reddit auftaucht? Neues Projekt, offizielle Pakete. Behaltet nur dann einen Fork, wenn alter Code bereits darauf basiert und eine Migration sich aktuell nicht lohnt. Und wenn die Dokumentation dürftig ist, schaut euch das separate Beispiel-Repository von Empira an. Die Ordner und Dateien dort enthalten lauffähige Beispiele – viel besser als Rätselraten.
Ist PDFsharp kostenlos? Lizenzänderungen in PDFsharp 6.5
Die meiste Zeit über ja. Es war unter der MIT-Lizenz veröffentlicht, was die kommerzielle Nutzung nahezu uneingeschränkt erlaubt. Jede Version bis einschließlich 6.2.4 ist weiterhin unter dieser Lizenz veröffentlicht.
Version 6.5.0 änderte dies. Die Bibliothek ist nun dual lizenziert:
- AGPL (kostenlos). Sie aktivieren die Lizenz, indem Sie vor der Verwendung der Bibliothek `PdfSharpLicense.SetAgplLicense()` aufrufen. Die AGPL verpflichtet Sie, Ihren Quellcode allen Nutzern zugänglich zu machen, auch solchen, die über ein Netzwerk mit Ihrer Software interagieren. Daher eignet sie sich weniger für proprietäre SaaS-Anwendungen.
- Kommerzielle Lizenz. Sie erwerben einen Lizenzschlüssel vom Anbieter und laden ihn mit PdfSharpLicense.LoadLicense(...). Dadurch werden die AGPL-Verpflichtungen aufgehoben.
Ab Version 6.5.0 muss Ihr Code eine Option explizit auswählen. Die Vorschauversionen von 7.0 funktionieren genauso.
In der Praxis:
- Open-Source-Projekte, die mit der AGPL kompatibel sind, können weiterhin kostenlos die neueste Version verwenden.
- Für proprietäre Produkte kann entweder eine kommerzielle Lizenz erworben werden oder man bleibt bei Version 6.2.x, die weiterhin unter der MIT-Lizenz steht. Wer bei der aktuellen Version bleibt, verpasst zukünftige Fehlerbehebungen; wägen Sie diese Kosten daher sorgfältig ab.
- Ganz gleich, wofür Sie sich entscheiden, lesen Sie den Lizenztext sorgfältig durch und lassen Sie ihn von Ihrem Rechtsteam unterzeichnen. Dieser Leitfaden stellt keine Rechtsberatung dar.

Wo PDFsharp seine Grenzen hat und womit man es kombinieren sollte
Die Bibliothek erfüllt ihre Aufgabe gut. Ihr Aufgabenbereich ist nur eng gefasst, und in jedem Forumthread tauchen dieselben Lücken auf.
- Keine HTML-zu-PDF-Konvertierung. PDFsharp rendert weder HTML noch CSS. Zwar existiert das Community-Add-on HtmlRenderer.PdfSharp, dieses unterstützt jedoch nur HTML 4.01 und CSS Level 2, weshalb moderne Layouts mit Flexbox oder Grid nicht unterstützt werden. Teams, die HTML-Vorlagen benötigen, greifen daher üblicherweise auf einen Headless-Browser-Renderer zurück.
- Kein JavaScript. Diagramme oder clientseitig erstellte Inhalte können nicht erfasst werden.
- Keine Bildwiedergabe. PDFsharp kann keine PDF-Seite in eine PNG-Datei für Miniaturansichten oder Vorschauen umwandeln. Dafür benötigen Sie einen separaten Rasterizer.
- Die Textextraktion ist eingeschränkt. Zwar lässt sich der Inhaltsstrom durchlaufen, es gibt jedoch keine übergeordnete API, die sauberen Text mit Positionsangaben zurückgibt. PdfPig, eine separate Open-Source-Bibliothek, wurde speziell zum Lesen und Extrahieren von Text entwickelt.
- Teilweise Formularunterstützung. Einfaches Ausfüllen von AcroForms funktioniert; komplexe Formulare mit Skripten sind eine andere Sache.
- Für Tabellen wird MigraDoc benötigt. Mit dem einfachen PDFsharp muss die Zeilenhöhe manuell berechnet werden.
Das macht es aber nicht zu einer schlechten Wahl. Datenbasierte Dokumente wie Rechnungen, Kontoauszüge, Etiketten und Zertifikate sind genau das Richtige dafür, und der Speicherplatzbedarf ist minimal. Pixelgenaue Kopien von Webseiten hingegen nicht.
PDFsharp für Krypto-Rechnungen und Zahlungsbelege
Belege sind wahrscheinlich das, was am häufigsten mit PDFsharp erstellt wird. Krypto-Belege sind etwas komplexer als Kartenbelege. Die gute Nachricht: Sobald das Gateway Ihren Webhook (ein HTTP-Callback, der beim Statuswechsel der Zahlung gesendet wird) erreicht, stehen Ihnen alle Daten zur Verfügung. Sie müssen nichts zusätzlich nachschlagen.
Was ich darauf drucken würde:
- Bestell- oder Rechnungsnummer und Händlerdaten
- Betrag in Kryptowährung und sein Gegenwert in Fiatwährung zum Zeitpunkt der Zahlung
- Coin und Netzwerk (zum Beispiel USDT auf TRON im Vergleich zu USDT auf Ethereum)
- Transaktions-Hash, damit der Kunde ihn in einem Block-Explorer überprüfen kann.
- Eine verkürzte Empfangs-Wallet-Adresse und die Bestätigungszeit
- Ein QR-Code, der zur Transaktions- oder Rechnungsseite verlinkt.
Verwenden Sie eine nichtproportionale Schriftart für Hashes und Adressen. Kunden müssen sie Zeichen für Zeichen entziffern, und in Arial sehen eine Null und ein großes O fast identisch aus. Ist der Hash zu breit, brechen Sie ihn um; 6-Punkt-Schrift ist nicht hilfreich. Binden Sie die Schriftarten ein, speichern Sie die Datei mit der Bestellung und unterschreiben Sie sie, falls Ihr Buchhalter jemals Belege verlangt.
Das alles beinhaltet noch nicht die eigentliche Zahlungsabwicklung. Dafür benötigen Sie ein Zahlungsgateway wie Plisio . Dieses akzeptiert BTC, USDT und viele andere Kryptowährungen, erstellt die Rechnung und ruft Ihren Endpunkt bei jeder Statusänderung auf. Ihr Handler leitet die Daten an MigraDoc weiter, und der Käufer erhält eine Quittung mit Ihrem Logo, während er sich noch auf der Dankesseite befindet.
Abschluss
Ich greife immer wieder auf PDFsharp zurück, und zwar aus einem einzigen Grund: Es ist klein und unauffällig. Die Core-Version läuft überall dort, wo .NET läuft, und MigraDoc übernimmt das Layout, wenn eine Canvas-Oberfläche nicht ausreicht. Drei Dinge sollten Sie frühzeitig klären: Welche Version Sie verwenden, wie Schriftarten geladen werden und welche Lizenz Sie nutzen, seit Version 6.5 unter der AGPL steht. Drucken Sie Daten, keine Webseiten, dann wird es Ihnen jahrelang gute Dienste leisten.