Scryber.Core 9.5.0

dotnet add package Scryber.Core --version 9.5.0
                    
NuGet\Install-Package Scryber.Core -Version 9.5.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="Scryber.Core" Version="9.5.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Scryber.Core" Version="9.5.0" />
                    
Directory.Packages.props
<PackageReference Include="Scryber.Core" />
                    
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 Scryber.Core --version 9.5.0
                    
#r "nuget: Scryber.Core, 9.5.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 Scryber.Core@9.5.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=Scryber.Core&version=9.5.0
                    
Install as a Cake Addin
#tool nuget:?package=Scryber.Core&version=9.5.0
                    
Install as a Cake Tool

Scryber.Core PDF Engine

Scryber makes creating beautiful, dynamic documents easy.

The scryber engine is an advanced, complete, pdf creation library for dotnet (including support for Blazor WASM)

  • Easy definition of document templates with, pages, content, shapes and images using html, and svg.
  • Bring your data in from an api or object model.
  • Bind with handlebars syntax and full complex expression support.
  • Layout with styles including calculated and relative values, and binding to your data.
  • Finally with a couple of lines of code, output the document to a stream or file.

With a styles based template layout, it is easy to create good looking, paginated and flowing documents, with dynamic content from your applications or sites.

Getting Started

The easiest way to begin is to use the Nuget Packages here

scryber.core package (Base libraries for GUI or console applications)

OR for asp.net mvc

scryber.core.mvc package (Which includes the scryber.core package).

Check out the documentation for more information on how to use the library.

  • getting started, a quick start article that gives a good overview of getting started and producing your first styles and bound template.

  • scryber.core learning guides, a full series for learning the main capabilities of the library.

  • scryber.core reference guides, a complete core library reference of all the supported elements, style and binding expressions.


Using Scryber

Content template

Use standard (x)html content to define the template with handlebar {{ }} notation for dynamic values.

<html lang='en' xmlns='http://www.w3.org/1999/xhtml' >
<head>
    
    <meta charset='utf-8' name='author' content='{{meta.author}}' />
    <title>Hello World</title>
    
    <style> 
    </style>
    
    <link href="/relative-stylesheet.css" type="text/css" />
</head>
<body class="name" style="border: solid 1pt #AAA">

<h1 style="font-size: calc(theme.titleSize);">Hello {{name ?? 'World'}}</h1>
</body>
</html>

https://paperwork.help/learning/01-getting-started/03_html_to_pdf.html


Loading the DOM

The document is parsed into a complete object graph from local file paths, streams or dynamically created content.

using Scryber.Components
    
    using var doc1 = Document.ParseDocument("xhtml-template-path.html");
    using var doc2 = Document.ParseDocument(myContentStream);
    using var doc3 = Document.ParseHtmlDocument("non-formal-html-template-path.html");
    using var doc4 = Document.ParseDocument(new StringReader("<html xmlns='http://www.w3.org/1999/xhtml' >....</html>"))

https://paperwork.help/learning/01-getting-started/02_first_document.html


Adding data for binding

Binding values are added using the documents' Params dictionary and can be set to any value, object graph, or json data.

    //simple dynamic object
    doc.Params["meta"] = new { author = "My Name", reportDate = DateTime.Now };
    
    //structured object data
    doc.Params["model"] = GetMyModelData();
    
    //json data
    doc.Params["json"] = System.Text.Json.JsonSerializer.Deserialize(remoteAPIResult);
    
    //injected templated content
    doc.Params["templates"] = new 
    {
        innerContent = "<span class='header'>{{.title}}</span><br/><span class='desc'>{{.desc}}</span>"
    };

https://paperwork.help/learning/02-data-binding/


Outputting the result

The final output can be saved either to a file or stream, synchronously or asynchronously.

//Simply save to a file
doc.SaveAsPDF("filePath.pdf");
            
//A standard IO stream
using var memory = new System.IO.MemoryStream();
doc.SaveAsPDF(memory);

//Or your own custom Stream
using var sourceStream = GetDataStream();
doc.SaveAsPDF(sourceStream);

//Also supports asyncromous operation
await doc.SaveAsPDFAsync("asyncfilepath.pdf");
   

https://paperwork.help/learning/01-getting-started/07_output_options.html

Using the Scryber.Components.MVC package extensions

public async IActionResult GetDocument()
{
    .
    .
    return await this.PDFAsync(doc)
}

Other features

Binding to complex content

Handlebar support for dynamic content binding, and expressions


<div id="contentWrapper" class="wrapper">
{{#each model.items}}
    <div>Item {{@index}}: {{.name}}
    
    {{#if count(.nested)}}
        
        <ul>{{#each .nested}}<li data-content="{{templates.innerContent}}"></li></ul>
    {{#else}}<div class="muted">No inner items</div>
    {{/if}}
    </div>
{{/each}}
</div>

Add standard external templates using the embed element

<div class="tsCs" >
    <embed src="./includes/termsAndConditions.html" />
</div>

Or create and inject compoments directly into the DOM

var table = this.BuildTableGrid(loadedData);
var container = doc.FindAComponentById("contentWrapper") as Div;
container.Contents.Add(table);

Page Sizes, headers and footers

The default page size is A4, but this can be changed to US specific letter or any standard size (or explicit). Inner pages can also have their own sizing.

<html lang='en' xmlns='http://www.w3.org/1999/xhtml' >
<head>
    <style> 
        
        @page{
            size: letter;
        }
        
        @page landscape{
            size: letter landscape;
        }
        
        .wide{
            page: landscape;
        }
        
    </style>
</head>
<body class="col2 landscape" style="border: solid 1pt #AAA">
    <h1>Main page in letter sizing</h1>
    <section class="wide">
        Content is by default on a new page with a 'section', and this will use the 'letter landscape' size based on the 'wide' class
    </section>
</body>
</html>

Column layout.

The engine fully supports columnar layout both at the page level and also within blocks.

<html lang='en' xmlns='http://www.w3.org/1999/xhtml' >
<head>
    <style> 
        @page landscape{
            size: A4 landscape;
        }
        
        @media print {
            /* force a landscape page with 2 column layout on the body *only* when printing */
            body {
                page: landscape;
            }
            
            .col2{
                column-count: 2;
                column-rule: 1pt solid silver;
            }
             
        }
    </style>
</head>
<body class="col2 landscape" style="border: solid 1pt #AAA">
    <h1>Main page flow in 2 columns</h1>
    <article class="col2">
        Content will flow in the inner columns, then onto the next side of the page
    </article>
</body>
</html>

Columns can also be used in footers, and a new column forced with break-before.

<footer style="column-count: 3">
    <time datetime="{{meta.reportDate}}" data-format="dd MMM yyyy" />
    <page data-format="Page {0} of {1}" style="break-before: column; text-align: center" />
    <span style="break-before: column; text-align: right">{{meta.author}}</span>
</footer>

Graphic Support

Images are supported for png, jpeg, tiff, gif, svg and webP (v9.5+)

<img src="https://fullremoteurl.com/images/myimage.png" />
<img src="./relativeUrlFromTemplateBasePath/OrWorkingDirectory/myImage.jpg" />
<img src="./mySvgImage.svg" />
<img src="data:image/png;base64,iVBORw0KGgoAAAANS..." />

https://paperwork.help/learning/06-content/01_images.html

Images can also be used as backgrounds and patterns

.patterned{
    background-repeat: repeat-x;
    background-image: url("./localpath/diamond.png)";
}

https://paperwork.help/reference/cssproperties/properties/css_prop_background-image.html

SVG's can be included inline within the document or using the embed element, that allows the content to use dynamic binding.

<div class="logo" >
    <svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100pt' preserveAspectRatio="xMidYMid">
        <rect x='10' y='10' width='{{length(meta.title) * 20' height='10' fill="#AAA" />
        <text fill="#AA0" text-anchor="middle">{{meta.title}}</text>
    </svg>
</div>

https://paperwork.help/learning/06-content/02_svg_basics.html


Font Support

The library includes 16 standard fonts that can be embedded. THe system fonts, and custom fonts can be configured and loaded at initial execution time

https://paperwork.help/configuration/font-configuration.html

Other fonts can also be defined through links or the @font-face rule


<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&amp;display=swap" rel="stylesheet"/>

<style>
    @font-face {
        font-family: 'Roboto';
        src: url('../fonts/Roboto-Regular.ttf') format('truetype');
        font-weight: 400;
        font-style: normal;
    }
    
    body{
        font-family: 'Roboto', sans-serif;
    }
</style>

https://paperwork.help/learning/05-typography/03_web_fonts.html


Modifying existing files

Scryber supports modification of existing pdfs using framesets for page insertion, overlays, or contractions.

<frameset xmlns='http://www.w3.org/1999/xhtml'>
    
    <frame src="summary.html"></frame>
    
    <frame src="large-document.pdf" data-page-start="0" data-page-count="3">
        
        <h1 hidden="{{model.isProof ? '' : 'hidden'}}" 
            style="transform: rotate(45deg); opacity: 0.5; color: #444;">PROOF CONTENT</h1>
    </frame>
</frameset>

https://www.paperwork.help/reference/htmltags/elements/html_frameset_frame_element.html


Adding security

Add restrictions and encryption mechanism to the document either through a template meta tag, or the documents RenderOptions.Permissions property.

<head>
    <meta name="print-restrictions" content="printing, accessibility" />
    <meta name="print-encryption" content="128bit"
</head>
doc.RenderOptions.Permissions.AllowCopying = true;
doc.RenderOptions.Permissions.AllowPrinting = true;
doc.RenderOptions.Permissions.AllowAccessiblity = true;

When using restrictions it is advisable that an owner password be set on the document output (in lax mode, a random value will be assigned)

using SecureString owner = CollectOwnerPassword();
doc.RenderOptions.PasswordProvider = new DocumentPasswordProvider(owner);

To force a password to be required to open a document, then set a user password (this can be the same as the owner password).

using SecureString owner = CollectOwnerPassword();
using SecureString user = CollectUserPassword();

doc.RenderOptions.PasswordProvider = new DocumentPasswordProvider(owner);
doc.RenderOptions.PasswordProvider = new DocumentPasswordProvider(owner, user);

https://paperwork.help/learning/07-configuration/05_security.html


Checking the output

To check the results, and what is happening underneath use the trace log support - either with the scryber/paperwork processing instructions at the very top of the template. This will add the processing log to the end of the resultant document, along with execution timing and any resources (fonts, images, etc) included.

<?scryber append-log=true log-level=messages ?>

or use code on the document itself.

doc.AppendTraceLog = true;
doc.TraceLog.SetRecordLevel(TraceRecordLevel.Verbose);

https://paperwork.help/configuration/processing-instructions.html


The engine also supports:


Getting Involved

We would love to hear your feedback. Feel free to get in touch. Issues, ideas, includes are all welcome.

If you would like to help with building, extending then happy to get contributions

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 is compatible.  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 is compatible.  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.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Scryber.Core:

Package Downloads
Scryber.Core.Mvc

The Mvc extensions for the Scryber.Core PDF creation engine - change the way you make documents. Scryber is an advanced PDF generation engine based around HTML templates with CSS styles and SVG drawing. It includes full flowing pages, dynamic template binding on your object model and referenced external files, images, css and fonts. Easily create documents from your Apps, MVC sites, or Javascipt ajax calls. This framework is built entirely in .NET supporting Blazor WASM and is released under the LGPL licence so you can use to it in commercial applications.

Paperwork.Core

Core PDF generation library for Paperwork — fluent builder API over the Scryber rendering engine.

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on Scryber.Core:

Repository Stars
grandnode/grandnode2
E-commerce platform built with ASP.NET Core using MongoDB for NoSQL storage
Version Downloads Last Updated
9.5.0 327 5/6/2026
9.5.0-alpha 95 5/1/2026
9.3.1 703 4/26/2026
9.3.0 135 4/21/2026
9.2.0.3 12,984 1/22/2026
9.2.0.2 3,146 11/13/2025
9.2.0 2,480 11/6/2025
9.1.2-rc.6 190 11/5/2025
9.1.2-rc.5 180 11/4/2025
9.1.2-rc.4 183 11/3/2025
9.1.1-rc.4 187 11/3/2025
9.1.0.7-beta 4,545 9/22/2025
9.1.0.6-beta 262 9/22/2025
9.1.0.5-beta 244 9/20/2025
9.1.0.3-alpha 302 9/15/2025
9.1.0.2-alpha 320 9/15/2025
9.1.0.1-alpha 1,648 9/7/2025
9.1.0-alpha 221 9/7/2025
9.0.0.1-rc.3 4,070 5/26/2025
9.0.0.1-rc.2 199 5/22/2025
Loading failed

9.5.0.0
BREAKING RELEASE
Removed support for Net Standard 2.0, and Image Sharp updated to 3.1.2
All libraries updated to include dotnet 8/9/10
Added support image format webP
Clean up codebase to remove compiler warnings

9.3.1.0
Fixes for break-before/after to take proiority over page-break-before
Fixes for @page to support margins, along with :first, :left and :right pseudo classes

9.3.0.0
CSS updates for rowspan on table cells, column-rules, contain on background images, border-radius on individual corners and CSS variables can now be modified in document properties.
Fixed page sizing in groups with fallback on following pages, whitespace hadling in soft returns, and SVG img placement and sizing.
Added *initial* implementation for flex-box, flex-grid, and table-xxx display
Configuration improvements incuding cusom image factories and custom expression functions.
       
9.2.0.3
Fixed styling issue when components are hidden using css.

9.2.0.2
Fixed repeating raster background images with cover size

9.2.0.1
Added support for repeating SVG background images from Data urls
       
9.2.0.0
Public release will all added features from the betas. Too many to list, but consult the documentation here https://www.paperworkday.info/learning/ and the refererence section here https://www.paperworkday.info/reference/
       
9.1.2-rc.5/6
Couple of fixes for overflowing tables in a kept together parent, and svg font-weight bold and light are now supported and fixed an issue with the reverse function.
       
9.1.2-rc.4
Working modification of PDFs and templates using framesets and frames and support for SVG background images with opacity.

9.1.0.7-beta
First release of framesets for trimming and merging documents. Also hiding variables that do not have any content.

9.0.0.1-rc.3
Added extra html entity values to match available sources.

9.0.0.1-rc.2
Fixes for template parsing and added data-content to the template element, plus minor fixes and unit test updates. Second release candidate.

9.0.0.1-rc.1
Minor fixes for layout. First release candidate.
       
9.0.0.1-beta
Fixed a minor layout issue with multiple footer elementnamed components being applite to a page footer, and also header.
       
9.0.0.0-beta
Completely updated version for .NET 9.0 with support for html, css, svg and binding in a WASM compatible package with remote asset and content requests.
NOTE: If upgrading, PLEASE CHECK THE OUTPUT of your documents before releasing.
       
8.0.0.2-beta
Added a fix for the rounding of expression results on decimal and double values when the results are very small.

8.0.0.1-beta
Updated to net8.0 sdk and dependancies updated to the latest stable versions.
       
6.0.5.0-beta
Updated to net8.0 sdk and dependencies updated to latest version.

6.0.4.0-beta
Big updates to whitespace handling, support for &nbsp; and hyphens in line breaks.

6.0.3.2-beta
Fix for prioritising parsing unit values in invariant culture on OS's set to non-invariant culture.

6.0.3.1-beta
Minor fix for transforming svg components (that do not have explict position values).

6.0.3.0-beta
Added fixes for parsing (x)html content on systems not running the english culture. All numeric values are expected to be in english decimal notation - e.g. 1,0234.56 for values in CSS, styles, svg etc.
Unit testing works for non-english. May be a couple of values / options missed but hoping not.
Added the AddRange option to top level component wrapping lists - (Rows, Cells, Items, etc.) that accepts an IEnumerable<InnerType> instance.

6.0.2.1-beta
Added fix for large inline images. Tested SaveAsPDFAsync.

6.0.1.1-alfa
Support for SaveAsPDFTimer, to check for asyncronous execution in a single threaded
application - blazor (or windows forms?), using asyncronous loading of http requests for css images, fonts etc).

6.0.1.0-beta

We now support html - in many of its flavours, through the HTMLAgilityPack

Added parsing non-formal html documents and components from local and remote files (using the ParseHtml and ParseHtmlDocument on the Document class)
Added the data-content and data-content-type attributes to visual components so that html and xhtml content can be data bound into pages.
Added support for the hyphens css property and it's use in hypenating long text.

6.0.0.16-beta

Some Big additions and fixes

Added support for the css counters (reset, increment and the counter(s) functions)
Added support for css content properties
Added support for css ::before and ::after selectors
Added support for relative units in styles e.g. 30% and 0.5em - not supported in calc() with multiple units e.g calc(50% - 5px) will not work.

A lot of layout tests to get everything working - precisely.


6.0.0.14-beta

Added support for transformations including css transform property.

6.0.0.12-beta

Changed the reference for ImageSharp to the 2.1.3 Nuget package, rather than the dll.
Checks added for support on thread culture in dates and numbers.

6.0.0.10-beta

Added support for Netwtonsoft.Json and the System.Text.Json objects in binding expressions and templates too.
Along with adding SoryBy, MaxOf, EachOf, SelectWhere collection functions.

6.0.0.5-beta

Updated to the .net 6.0 sdk, now with support for running as a web assembly with asyncronous loads of stylesheets, images and fonts.
Some TTC and TTF font files do not render glyfs correctly, but working for many fonts.

5.1.0.2-beta

A major update that now fully supports expressions in attributes, css var and clac along with text, using the handlebars notation - {{...}}
This includes support for simple mathematical expressions from the document variables as welll as functions such as 'concat', 'if(value, 'true', 'false')' or 'index() + model.property'

5.0.7

Adding support for the float left and right within blocks along with css linear and radial gradients

5.0.6.3

Fixes an issue with some TTF fonts on Windows (specifically azure) to look for the best character mapping table, and multi-span text not flowing well due to some changes to try and get float working.

5.0.6

The April release is a bit of a catch up and fix with updates for:

Supporting parsed JSON objects in binding - along with std types and dynamic objects.
margin:value is applied to all margins even if explicit left, right etc. has been previously applied.
Conformance is now carried through to templates, so errors are not indavertantly raised inside the template.
Missing background images will not raise an error.
Support for data images (src='data:image/..') within content - thanks Dan Rusu!
Images are not duplicated within the output for the same source.


5.0.5

Multiple enhancements including

Embed and iFrame support.
Binding speed improvements for longer documents.
Support for border-left, border-right, etc
Support for encryption and restrictions
Support for base href in template files.
Classes and styles on templates are supported.
Added em, strong, strike, del, ins elements
Html column width and break inside
CSS and HTML Logging
Fixed application of multiple styles with the same word inside
Allow missing images on the document is now supported.
Contain fill style for background images.

See: https://scrybercore.readthedocs.io/en/latest/version_history.html for a full break down.