-
Notifications
You must be signed in to change notification settings - Fork 207
Majorsilence.Pdf
Majorsilence.Pdf is a pure-managed, zero native-dependency PDF generation library for .NET. It is a separate, lower-level library from the RDL report engine — use it when you want to build a PDF page-by-page in code rather than designing an .rdl report. It targets netstandard2.0, net6.0, net8.0, and net10.0, and produces PDF 1.4, PDF 1.7, and PDF 2.0 output with optional PDF/A conformance.
Password protection and digital signatures are provided by the companion package Majorsilence.Pdf.Security.
<PackageReference Include="Majorsilence.Pdf" />
<PackageReference Include="Majorsilence.Pdf.Security" /> <!-- optional: passwords & signatures -->A full, runnable console app covering every feature below (fonts, shapes, tables, images, merging, PDF/A, encryption, signatures, RTL text, and more) lives in the repo at Examples/MajorsilencePdfExample.
using Majorsilence.Pdf;
PdfDocument.Create()
.WithTitle("Hello World")
.WithAuthor("Majorsilence.Pdf")
.AddPage(PageSizes.A4, canvas =>
{
var heading = TextStyle.Default.WithFamily("LiberationSans").WithSize(36).WithBold();
var body = TextStyle.Default.WithFamily("LiberationSans").WithSize(12);
canvas.DrawText("Hello, World!", 72, 100, heading);
canvas.DrawText(
"Generated with Majorsilence.Pdf — a zero-dependency PDF library.",
72, 155, body);
})
.Save("hello.pdf");DrawRectangle, DrawEllipse, DrawPolygon, and DrawLine accept a ShapeStyle or StrokeStyle for fill, border, dashing, and opacity:
canvas.DrawRectangle(410, 50, 150, 80,
ShapeStyle.Filled(PdfColor.Yellow).WithStroke(PdfColor.Orange, 2f));
canvas.DrawRectangle(50, 175, 150, 80,
ShapeStyle.Stroked(PdfColor.DarkGray, 1.5f).Dashed());
canvas.DrawEllipse(410, 300, 80, 80,
ShapeStyle.Filled(PdfColor.Green).WithStroke(PdfColor.DarkGray, 1f));
canvas.DrawLine(x1, y, x2, y,
StrokeStyle.Default.WithWidth(2f).WithColor(PdfColor.Blue).Dashed());PdfTable lays out a header row, alternating row backgrounds, borders, and per-cell text styles, with automatic word-wrapping inside cells:
var table = new PdfTable(new float[] { 180, 80, 90, 90 })
.WithHeaderBackground(new PdfColor(26, 86, 160))
.WithAlternateRowBackground(new PdfColor(240, 245, 252))
.WithBorder(new PdfColor(200, 200, 200), 0.5f)
.WithCellPadding(5f)
.WithCellTextStyle(TextStyle.Default.WithFamily("LiberationSans").WithSize(10))
.WithHeaderTextStyle(
TextStyle.Default.WithFamily("LiberationSans").WithSize(10)
.WithBold().WithColor(PdfColor.White));
table.AddRow("Product", "Qty", "Unit Price", "Total");
table.AddRow("PDF Library Pro", "3", "$400.00", "$1 200.00");
table.AddRow("Report Designer", "1", "$250.00", "$250.00");
canvas.DrawTable(table, 72, 92, out float tableBottom);DrawTextBox word-wraps text into a bounding box and returns the character index where it overflowed, so a document can continue the text on the next page:
int overflowAt = canvas.DrawTextBox(
text: longText,
x: 72,
y: 100,
width: 400,
height: 600,
style: TextStyle.Default.WithSize(11),
lineSpacing: 1.4f);
if (overflowAt < longText.Length)
{
// Continue on the next page/box
canvas.DrawTextBox(longText.Substring(overflowAt), 72, 100, 400, 120, TextStyle.Default.WithSize(11));
}Raw JPEG bytes are embedded directly; other formats are supplied as decoded raw RGB24 bytes and get FlateDecode-compressed automatically:
byte[] jpegBytes = File.ReadAllBytes("photo.jpg");
canvas.DrawImage(jpegBytes, jpegWidth, jpegHeight, isJpeg: true,
x: 72, y: 105, width: 200, height: 150);PdfMerger combines PDFs produced separately (e.g. a cover page built one way and content built another) into a single document:
byte[] sourceA = PdfDocument.Create()
.AddPage(PageSizes.A4, canvas => { /* cover page */ })
.ToBytes();
byte[] sourceB = PdfDocument.Create()
.AddPage(PageSizes.A4, canvas => { /* content page */ })
.ToBytes();
byte[] merged = new PdfMerger()
.Add(sourceA)
.Add(sourceB)
.WithTitle("Quarterly Report")
.WithAuthor("Example Corp")
.Merge();
File.WriteAllBytes("report.pdf", merged);Register TrueType fonts with a FontRegistry and set a fallback family for glyphs the primary font doesn't cover (useful for accented Latin, Greek, Cyrillic, and other scripts):
var registry = new FontRegistry()
.AddDirectory("/path/to/fonts")
.AddFallback("NotoSans");
PdfDocument.Create()
.WithFontRegistry(registry)
.AddPage(PageSizes.A4, canvas =>
{
canvas.DrawText("café résumé наизусть", 72, 72,
TextStyle.Default.WithFamily("LiberationSans").WithSize(14));
})
.Save("unicode.pdf");Right-to-left scripts (Hebrew, Arabic) are supported via TextStyle.WithRightToLeft() combined with TextAlignment.Right.
WithConformance() sets the correct PDF version, embeds an sRGB ICC output intent, and writes the required XMP conformance claim. PDF/A requires embedded TrueType fonts (standard Type1 fonts aren't permitted) and cannot be combined with encryption:
PdfDocument.Create()
.WithConformance(PdfConformance.PdfA2b) // or PdfA1b, PdfA3b
.WithFontRegistry(registry)
.AddPage(PageSizes.A4, canvas => { /* ... */ })
.Save("archive.pdf");These require the Majorsilence.Pdf.Security package:
using Majorsilence.Pdf.Security;
var security = PdfSecurity.Protect(userPassword: "open123", ownerPassword: "owner456")
.WithPermissions(PdfPermissions.Print | PdfPermissions.CopyText);
PdfDocument.Create()
.WithSecurity(security)
.AddPage(PageSizes.A4, canvas => { /* ... */ })
.Save("protected.pdf");Digital signatures (PKCS#7 detached, SHA-256) are added with WithSignature(new PdfSignatureOptions(certificate)).
PdfNative is a Native AOT-compiled C API (libpdfnative.so / .dylib / pdfnative.dll) that exposes the same document, canvas, table, merge, and security primitives as Majorsilence.Pdf to any language that can call a C ABI — Python, PHP, Ruby, Rust, or plain C — with no .NET runtime required at the call site. It ships opacity, PDF/A conformance, digital signing, and public-key encryption support, matching the managed library's feature set.
pdf_init();
void* doc = pdf_doc_create();
pdf_doc_set_title(doc, "My Report");
void* canvas = pdf_doc_add_page(doc, 595.28f, 841.89f); // A4
pdf_canvas_draw_text(canvas, "Hello, PDF!", 72, 100, NULL);
pdf_canvas_close(canvas);
pdf_doc_save_file(doc, "/tmp/output.pdf");
pdf_doc_close(doc);The header (PdfNative/pdfnative.h) documents the full C API with quick-start, table, merge, and security examples. Prebuilt platform/architecture zips (Windows/Linux/macOS, x64/arm64) are attached to each GitHub release. Like Majorsilence.Pdf, it is tri-licensed (MIT, Apache 2.0, or BSD 2-Clause).
- Examples/MajorsilencePdfExample — full example project with 23 runnable examples (shapes, invoices, dashboards, annotations, tables, merging, PDF/A, RTL text, encryption, signatures, and more), each rendered for both PDF 1.4 and PDF 2.0
-
Programmatic PDF Document Creation — the higher-level, RDL-based document API (
Majorsilence.Reporting.RdlCreator) - Programmatic Report Creation — building full RDL reports in code