PdfRes 1.2.0

dotnet add package PdfRes --version 1.2.0
                    
NuGet\Install-Package PdfRes -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PdfRes" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PdfRes" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="PdfRes" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PdfRes --version 1.2.0
                    
#r "nuget: PdfRes, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PdfRes@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PdfRes&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=PdfRes&version=1.2.0
                    
Install as a Cake Tool

PdfRes

A production-ready, deterministic HTML-to-PDF generation library for .NET 8.
Pure managed code — no headless browser, no native binaries, no external process dependencies.

NuGet License: MIT


Features

Capability Detail
Deterministic layout Same HTML always produces the same PDF — no browser variance
Accurate unit conversion px / pt / mm / cm / in / em / rem / % with configurable DPI
14 standard PDF fonts Adobe AFM-accurate character widths, ascent/descent metrics
CSS cascade & inheritance Inline styles, <style> blocks, user-agent defaults
Page breaking Orphan avoidance, page-break-before/after/inside support
Table layout Multi-column tables with correct cell height equalization
Text decoration Underline, strikethrough, bold, italic
Security by default Strips <script>, event handlers, remote resources
Thread-safe & async SemaphoreSlim concurrency limiting, Task.Run offload
Batch generation GenerateBatchAsync for high-throughput backends
Extensible pipeline Every stage is behind an interface — swap any component

Installation

dotnet add package PdfRes

Quick Start

// One-liner
var result = PdfGenerator.Default.Generate("<h1>Hello World</h1><p>Generated by PdfRes.</p>");
result.SaveToFile("output.pdf");

Configured Usage

using PdfRes;
using PdfRes.Configuration;

using var generator = PdfGenerator.CreateBuilder()
    .WithPageSize(PageSize.A4)
    .WithMargins(PageMargins.Normal)
    .WithTitle("Invoice #12345")
    .WithAuthor("Acme Corp")
    .WithScreenDpi(96)
    .WithMaxConcurrency(4)
    .WithSecurity(SecurityPolicy.Relaxed)
    .Build();

var result = await generator.GenerateAsync(htmlContent);

Console.WriteLine($"Pages   : {result.PageCount}");
Console.WriteLine($"Size    : {result.FileSizeBytes} bytes");
Console.WriteLine($"Total   : {result.TotalDuration.TotalMilliseconds:F1} ms");

await result.SaveToFileAsync("invoice.pdf");

Batch Generation

var htmlDocuments = new[] { html1, html2, html3 };
var results = await generator.GenerateBatchAsync(htmlDocuments);

foreach (var r in results)
    Console.WriteLine($"Pages: {r.PageCount}, Size: {r.FileSizeBytes} bytes");

Custom Options Per Call

var landscapeOptions = new PdfOptions
{
    PageSize    = PageSize.A4.Landscape(),
    Margins     = PageMargins.Narrow,
    Title       = "Report",
    Fonts       = new FontOptions { DefaultFontFamily = "Times-Roman", DefaultFontSizePt = 11 }
};

var result = await generator.GenerateAsync(html, landscapeOptions);

Supported HTML / CSS

Elements

div, p, h1h6, span, strong, em, b, i, u, s, ul, ol, li, table, tr, td, th, thead, tbody, pre, code, blockquote, hr, br, a, section, article, header, footer

CSS Properties

color, background-color, font-family, font-size, font-weight, font-style, text-align, line-height, text-decoration, direction, white-space, opacity, margin, padding, border, width, height, min/max-width/height, display, page-break-before, page-break-after, page-break-inside

Selectors

Tag, .class, #id, tag.class, tag#id, *, multi-selector (,)


Architecture

HTML Input
   │
   ▼
[Security] HtmlSanitizer       — removes scripts, event handlers, enforces size limits
   │
   ▼
[Parsing]  HtmlParser          — lightweight HTML → DOM tree (no external deps)
           CssResolver         — cascade, specificity, inheritance, user-agent defaults
   │
   ▼
[Layout]   LayoutEngine        — deterministic CSS box model, text wrapping, table layout
           PageBreaker         — orphan-aware page splitting, page-break-* support
   │
   ▼
[Render]   PdfRenderer         — PDF 1.7 binary format, font embedding, coordinate transform
           PdfDocumentWriter   — low-level object/stream/xref writer
   │
   ▼
byte[] PDF

Security

PdfRes uses SecurityPolicy.Strict by default:

  • ❌ No JavaScript execution
  • ❌ No remote resource loading
  • ❌ No <script>, <iframe>, <form>, <object> elements
  • ❌ No event handler attributes (onclick, onload, …)
  • ✅ Configurable maximum input size (default 5 MB)
  • ✅ Maximum DOM nesting depth (default 100)

Performance Notes

  • All pipeline stages are stateless — PdfGenerator is safely shared across threads
  • CPU-bound rendering is offloaded to Task.Run to keep caller threads free
  • ConcurrencyLimiter prevents unbounded parallelism in high-load scenarios
  • MemoryStream pooling avoids large GC pressure on repeated calls

License

MIT © PdfRes Contributors

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 89 2/20/2026
1.1.0 88 2/20/2026
1.0.0 89 2/20/2026