JetsonPDF.Fluent
1.1.0
dotnet add package JetsonPDF.Fluent --version 1.1.0
NuGet\Install-Package JetsonPDF.Fluent -Version 1.1.0
<PackageReference Include="JetsonPDF.Fluent" Version="1.1.0" />
<PackageVersion Include="JetsonPDF.Fluent" Version="1.1.0" />
<PackageReference Include="JetsonPDF.Fluent" />
paket add JetsonPDF.Fluent --version 1.1.0
#r "nuget: JetsonPDF.Fluent, 1.1.0"
#:package JetsonPDF.Fluent@1.1.0
#addin nuget:?package=JetsonPDF.Fluent&version=1.1.0
#tool nuget:?package=JetsonPDF.Fluent&version=1.1.0
JetsonPDF.Fluent
Headless, code-first fluent API for building PDFs on top of JetsonPDF. The shape
follows QuestPDF's idiom — FluentDocument.Create(d => d.Page(p => ...)) with a
chain of decorators and layout containers — but the implementation is
self-contained, has no WPF dependency, and emits PDFs through JetsonPDF.Writer.
using JetsonPDF.Fluent;
FluentDocument.Create(d =>
{
d.Page(p =>
{
p.Size(JetsonPDF.PageSize.Letter);
p.Margin(50);
p.Content().Column(col =>
{
col.Item().Text("Hello, JetsonPDF.Fluent!", s =>
{
s.FontSize = 24;
s.FontStyle = JetsonPDF.FontStyle.Bold;
});
col.Item().PaddingTop(8).Text("A code-first PDF API for .NET.");
});
});
}).GeneratePdf("hello.pdf");
Contents
- Overview
- Quick start
- Core concepts
- Page setup
- Layout containers
- Decorators
- Content leaves
- Shapes and shadows
- Rich text and page numbers
- Forms
- Links and named destinations
- Dynamic components
- Fonts
- Colors
- Document-level config
- Limitations
Overview
JetsonPDF.Fluent is the second high-level wrapper around the low-level
JetsonPDF.Writer API. The first wrapper, JetsonPDF.Wpf.Authoring, drives PDF
generation from a XAML tree and a live WPF layout pass — useful for
designer-friendly workflows but tied to STA threads and net8.0-windows.
JetsonPDF.Fluent covers the headless / server / console scenario: pure
net8.0, no WPF, no STA constraint.
The layout engine is a two-pass Measure → Draw model. Each element
reports a SpacePlan of FullRender, PartialRender, Wrap, or Empty;
the renderer's pagination loop uses those signals to split content across
pages. Stateful containers (Column, Table, multi-line Text) carry a
resume cursor that advances on Draw, so a paragraph that overflows page 1
finishes on page 2 from the next unrendered line.
A second whole-document counting pass runs first when the document contains
IDynamicComponent instances or page-number placeholders, so Page X of Y
labels and dynamic components see the final page count rather than a
running estimate.
Quick start
Add a project reference to JetsonPDF.Fluent and a using JetsonPDF.Fluent;.
Build a document by calling FluentDocument.Create with a configuration callback,
then GeneratePdf(path), GeneratePdf(stream), or the parameterless
byte[] GeneratePdf() for in-memory serialization:
using JetsonPDF.Fluent;
FluentDocument.Create(d =>
{
d.Page(p =>
{
p.Size(JetsonPDF.PageSize.A4);
p.Margin(40);
p.Content().Text("Hello, A4 world!");
});
})
.WithMetadata(title: "First Document", author: "You")
.GeneratePdf("first.pdf");
Core concepts
| Type | Role |
|---|---|
Document |
Top-level builder; carries metadata and the Page blocks. |
IDocumentContainer |
What the FluentDocument.Create callback receives. Has .Page(...). |
IPageDescriptor |
What each .Page(...) callback receives. Configures size/margin and the five page slots (Background, Header, Content, Footer, Foreground). |
IContainer |
The chain anchor. Returned by every decorator method and by descriptor slots (Header(), Content(), Footer(), ColumnDescriptor.Item(), etc.). |
TextStyle |
Family / weight / size / color / line height for text leaves. |
FontRegistry |
Per-document custom font registrations + standard-14 fallback. |
Colors |
Material-style named-color palette plus FromHex. |
IDrawingSurface |
Public escape-hatch handed to Canvas(...). Top-left origin, y-down, points. |
IDynamicComponent |
Per-page user-supplied content with access to IDynamicContext.CurrentPage / TotalPagesEstimate. |
The chain idiom: every decorator method returns the next IContainer slot
to chain into; every leaf (Text, Image, Column, …) terminates the chain.
container
.Padding(8) // returns the inner slot
.Border(1, Colors.Grey400)
.Background(Colors.White)
.Column(col => // leaf — chain ends here
{
col.Item().Text("inside the box");
});
Page setup
d.Page(p =>
{
p.Size(JetsonPDF.PageSize.Letter); // or .Size(width, height)
p.Margin(50); // .Margin(h, v) for asymmetric
p.DefaultTextStyle(s => s.FontSize = 11);
p.Background().Background(Colors.Grey50); // behind everything
p.Header() .Row(r => { /* repeats per page */ });
p.Content() .Column(c => { /* auto-paginates */ });
p.Footer() .Text("Confidential"); // repeats per page
p.Foreground().Text("WATERMARK"); // on top of everything
});
Slots are drawn in this z-order on every page: Background → Header → Content → Footer → Foreground. Background and Foreground span the full inner page (margin-aware). Header sits at the top, Footer at the bottom; Content fills the remaining vertical slot and auto-paginates on overflow.
A document can have multiple .Page(...) blocks — each is an independent
pagination unit with its own size/margins/slots. Page-number placeholders
count across all blocks (a 3-page block followed by a 2-page block sees
TotalPages = 5).
Layout containers
Column
Stacks children vertically. Auto-paginates at child boundaries.
container.Column(col =>
{
col.Spacing(8); // gap between items, in points
col.Item().Text("First");
col.Item().Padding(4).Border(1).Text("Boxed");
col.Item().Image(image);
});
Row
Lays out children horizontally with mixed constant- and relative-width slots.
container.Row(row =>
{
row.Spacing(10);
row.ConstantItem(80).AlignRight().Text("Date:");
row.RelativeItem().Text("2026-04-29"); // takes remainder
row.RelativeItem(weight: 2).Text("Wider half");
});
Row does not paginate — if a child reports Partial or Wrap, the entire row reports Wrap and is pushed to the next page by the surrounding Column.
Stack
Z-stack: children draw on top of each other, all anchored at the slot origin. Reported size is the max of the children's measured sizes.
container.Width(200).Height(100).Stack(s =>
{
s.Item().Background(Colors.YellowLight);
s.Item().AlignCenter().AlignMiddle().Text("ON TOP");
});
Inlined
Horizontal flow with row-wrap. Items pack left-to-right at their intrinsic width; when the next item would exceed the slot width, the layout wraps to a new row. Paginates at row boundaries.
container.Inlined(i =>
{
i.Spacing(6); // horizontal gap between items in a row
i.VerticalSpacing(4); // vertical gap between rows
foreach (var tag in tags)
{
i.Item()
.Background(Colors.GreenLight)
.PaddingHorizontal(6).PaddingVertical(2)
.Text(tag);
}
});
Grid
Fixed-column flow. Items distribute across N equal-width columns and wrap
to the next row.
container.Grid(g =>
{
g.Columns(3);
g.Spacing(8);
g.VerticalSpacing(8);
foreach (var card in cards)
g.Item().Border(1).Padding(8).Text(card.Name);
});
Table
Auto-paginating multi-column table with optional header (repeats on each page) and footer (renders only on the last page). Supports column span and row span.
container.Table(t =>
{
t.ColumnsDefinition(c =>
{
c.RelativeColumn(3); // proportional, weight 3
c.ConstantColumn(80); // fixed 80 points
c.ConstantColumn(60);
});
t.Header(h =>
{
h.Cell().Text("Item");
h.Cell().AlignRight().Text("Qty");
h.Cell().AlignRight().Text("Price");
});
foreach (var line in lines)
{
t.Cell().Text(line.Name);
t.Cell().AlignRight().Text(line.Qty.ToString());
t.Cell().AlignRight().Text($"${line.Price:F2}");
}
t.Footer(f =>
{
f.Cell(columnSpan: 2).AlignRight().Text("Total");
f.Cell().AlignRight().Text($"${total:F2}");
});
});
Column span: t.Cell(columnSpan: 3).Text("banner") widens a cell to
cover three columns.
Row span: t.Cell(rowSpan: 2).Text("group label") makes a cell occupy
two rows. Auto-flow honours occupancy: subsequent Cell() calls skip the
cells reserved by the row-span. Pagination is by atomic blocks — a
row-span never splits across pages; if the block doesn't fit on the current
page, the entire row-span pushes to the next page.
Decorators
Each decorator wraps the slot's content in a layout transformation. They
chain — each returns the new inner IContainer for further chaining.
Padding
container.Padding(10); // all sides
container.Padding(horizontal: 12, vertical: 4);
container.PaddingLeft(8); // single sides
container.PaddingTop(4).PaddingBottom(4);
container.PaddingHorizontal(12).PaddingVertical(8);
Sizing
container.Width(200).Height(50);
container.MinWidth(100).MaxWidth(300);
container.MinHeight(20).MaxHeight(120);
Width/Height pin the dimension exactly. MinWidth/MinHeight widen the
reported size to the floor; MaxWidth/MaxHeight clamp the slot before the
child measures.
Alignment
container.AlignLeft(); // FillHorizontal — chooses x within full slot width
container.AlignCenter();
container.AlignRight();
container.AlignTop(); // FillVertical — chooses y within full slot height
container.AlignMiddle();
container.AlignBottom();
A horizontal alignment fills only the horizontal axis (reported width = slot
width; height = child height); vertical alignment fills only the vertical
axis. Combine by chaining (.AlignRight().AlignMiddle()).
When the slot is unbounded in a dimension (e.g. inside a Table cell measured at unbounded height), the fill flag falls back to the child's natural size — "no slot to fill" rather than "infinite size".
Visual
container.Border(width: 1);
container.Border(width: 2, color: Colors.RedDark);
container.Background(Colors.Grey100);
container.AspectRatio(16.0 / 9.0); // FitWidth (default)
container.AspectRatio(1.0, AspectRatioMode.FitArea); // pick the dim that fits both
Border strokes a rectangle at the slot edge after the child draws.
Background fills the slot before the child draws.
Transform
container.Translate(dx: 10, dy: -5);
container.TranslateX(10).TranslateY(-5);
container.Rotate(degrees: 45); // clockwise about slot center
Translate is a pure draw-time offset — measurement is unaffected, so a
translated child's pixels can spill outside the slot. Rotate pivots about
the slot's center using PDF CTM; same caveat — the axis-aligned slot stays
the same, drawn pixels may extend outside.
Pagination control
col.Item().ShowOnce().Text("Title — only on the first page");
col.Item().SkipOnce().Text("Page numbers, blank on first");
col.Item().ShowEntire().Column(c => { /* never split across pages */ });
col.Item().EnsureSpace(40).Text("Won't render in <40pt of remaining space");
| Decorator | Behaviour |
|---|---|
ShowOnce |
Renders on the first page where it would render, then Empty thereafter. |
SkipOnce |
Empty on the first page, normal on every page after. |
ShowEntire |
If the child returns Partial, promote to Wrap so the renderer pushes the whole element to the next page. |
EnsureSpace(min) |
If less than min height is available, return Wrap so the element doesn't get orphaned at page bottom. |
Content leaves
Leaves terminate the chain (their methods return void).
Text
container.Text("hi");
container.Text("hi", s =>
{
s.FontFamily = "Helvetica"; // string family — see Fonts
s.FontSize = 16;
s.FontStyle = JetsonPDF.FontStyle.Bold;
s.FontColor = Colors.RedDark;
s.LineHeight = 1.4;
});
Single-style text. Wraps at word boundaries, paginates at line boundaries.
For multi-style runs (mixed bold/italic, inline page numbers), use the rich text descriptor — see Rich text and page numbers.
Image
container.Image(myImage); // fills slot at natural aspect
container.Image(myImage, width: 200, height: 100); // explicit size
myImage is an JetsonPDF.Image (load via Image.FromPng(...) /
Image.FromJpeg(...) from JetsonPDF.Writer).
Lines, Placeholders, Canvas
container.LineHorizontal(thickness: 1, color: Colors.Grey300);
container.LineVertical(thickness: 0.5);
container.Placeholder(width: 100, height: 50); // empty slot — for scaffolding
container.Canvas((surface, w, h) =>
{
surface.DrawRectangle(0, 0, w, h, fill: Colors.YellowLight);
surface.DrawText("custom",
new JetsonPDF.Font(JetsonPDF.FontFamily.Helvetica, 12),
x: 8, y: 20, color: Colors.Black);
});
Canvas is the escape hatch — if the layout primitives don't cover what you
need, draw it directly. Coordinates inside the callback are top-left origin,
y-down, in points. The slot's width/height are passed as the second/third
parameter.
Shapes and shadows
container.Width(80).Height(40)
.Ellipse(stroke: Colors.Black, fill: Colors.Yellow);
container.Width(120).Height(60).Polygon(
points: new (double, double)[] { (60, 0), (120, 60), (0, 60) },
stroke: Colors.RedDark, fill: Colors.RedLight);
container.Shadow(2, 2, Colors.Grey400)
.Background(Colors.White).Border(0.5)
.Padding(10).Text("card with shadow");
.Ellipse(...) inscribes an ellipse in the slot's bounding box. .Polygon(...)
takes engine-coord points relative to the slot's top-left; close: true
joins the last point back to the first. Both are leaves.
.Shadow(dx, dy, color) paints a flat offset rectangle behind the child
(the "card shadow" idiom). Not a Gaussian blur — PDF's blurred-shadow
support requires /ExtGState alpha plus a soft-mask form XObject which
isn't in the fluent surface. For higher visual polish drop down to
JetsonPDF.Writer and emit a soft mask manually.
The IDrawingSurface escape hatch (.Canvas((surface, w, h) => ...)) also
gained surface.DrawLine(x1, y1, x2, y2, color),
surface.DrawEllipse(cx, cy, rx, ry, ...), and
surface.DrawPolygon(points, ...) so custom drawing has the same primitives
as the chain leaves.
Rich text and page numbers
Rich text supports multiple styled runs in a single paragraph, with optional inline page-number placeholders. Lines wrap automatically at word boundaries preserving per-run styles.
container.Text(t =>
{
t.AlignCenter();
t.Span("Page ");
t.CurrentPageNumber().Bold();
t.Span(" of ");
t.TotalPages().Bold();
});
Per-run styling chains on the descriptor returned by Span/CurrentPageNumber/TotalPages:
container.Text(t =>
{
t.Span("Hello, ");
t.Span("world").Bold().FontColor(Colors.RedDark);
t.Span("!").FontSize(18);
});
Standalone shorthands when you only want a number with no surrounding text:
container.PageNumber(); // 1-based page index
container.TotalPages(); // final document page count
Both placeholders go through the deferred-text mechanism: at measure time they reserve worst-case 6-digit width; the actual digits are stamped after the document has finished laying out so wrapping doesn't shift between pages.
Forms
Form widgets are leaves — they consume the entire slot they land in.
container.Width(200).Height(20).AsTextField("name", tf =>
{
tf.MaxLength = 50;
tf.Value = "default";
tf.IsMultiline = false;
});
container.Width(15).Height(15).AsCheckBox("agree", cb => cb.IsChecked = true);
container.Width(160).Height(18).AsComboBox("region",
new[] { "NA", "EMEA", "APAC" },
cb => cb.SelectedValue = "NA");
container.Width(160).Height(60).AsListBox("size",
new[] { "S", "M", "L" });
container.Width(120).Height(24).AsPushButton("submit", "Send",
btn => btn.Caption = "Send");
Acrobat / a PDF reader renders the default chrome inside the slot rect. Use
.Padding(...) on the parent if you want spacing around the widget.
Links and named destinations
// External link — wraps content in a clickable region.
container.Link("https://example.com").Text("Visit example.com");
// Internal navigation — declare a destination, then jump to it.
container.Section("intro").Text("Introduction"); // anywhere in the doc
container.SectionLink("intro").Text("Jump to intro"); // clickable rect
Section registers a named destination at the element's top-left position
on the page where it draws. SectionLink adds a link annotation that jumps
to that destination. Link adds a URL link annotation.
All three can wrap any content — they're decorators, not leaves.
Dynamic components
Per-page custom content with access to the current page number and the final total page count.
public sealed class PageStamp : IDynamicComponent
{
public void Compose(IDynamicContext ctx)
{
ctx.Container.Row(r =>
{
r.RelativeItem().Text($"Section {ctx.CurrentPage % 3 + 1}");
r.RelativeItem().AlignRight()
.Text($"page {ctx.CurrentPage} of {ctx.TotalPagesEstimate}");
});
}
}
// Use it:
p.Footer().Component(new PageStamp());
The component's Compose is invoked once per page. The renderer does a
first counting pass through a no-op canvas to learn the final page count,
then a second emitting pass with IDynamicContext.TotalPagesEstimate
stamped to the final total. So a "Page X of Y" footer rendered via a
dynamic component shows the correct Y.
For most "Page X of Y" cases, prefer the rich-text descriptor — it goes through the deferred-text mechanism without rebuilding the content tree per page.
Fonts
TextStyle.FontFamily is a string. The default FontRegistry recognises
the standard 14 PDF fonts plus common aliases:
| Family string | Resolves to |
|---|---|
"Helvetica", "Arial" |
Helvetica |
"Times-Roman", "Times Roman", "Times", "Times New Roman" |
Times Roman |
"Courier", "Courier New" |
Courier |
"Symbol" |
Symbol |
"ZapfDingbats", "Zapf Dingbats" |
ZapfDingbats |
Custom TrueType fonts:
FluentDocument.Create(d =>
{
d.Page(p =>
{
p.DefaultTextStyle(s => s.FontFamily = "Inter");
p.Content().Text("Inter Regular");
});
})
.WithFonts(reg =>
{
reg.RegisterFromFile("Inter", JetsonPDF.FontStyle.Regular,
@"C:\fonts\Inter-Regular.ttf");
reg.RegisterFromFile("Inter", JetsonPDF.FontStyle.Bold,
@"C:\fonts\Inter-Bold.ttf");
})
.GeneratePdf("inter.pdf");
If a styled face isn't registered but the Regular face is, the Regular face
is used as a fallback (so users can register one weight and keep working).
Unknown family names throw by default; swap OnUnknownFamily for a lenient
host:
.WithFonts(reg =>
{
reg.OnUnknownFamily = (family, style) => { /* log + fall back to Helvetica */ };
})
Colors
Colors.Black // Color.Black (DeviceGray 0)
Colors.White // Color.White (DeviceGray 1)
Colors.Red // Material 500
Colors.RedLight // Material 200
Colors.RedDark // Material 700
Colors.BlueGrey, Colors.Teal, Colors.Indigo, Colors.Amber, ...
Colors.Grey100, Colors.Grey200, ..., Colors.Grey900
Colors.FromHex("#FF0000");
Colors.FromHex("#80FF0000"); // alpha discarded — PDF has no per-color alpha
Colors.FromHex("888"); // expanded to #888888
For colours not in the named palette, use FromHex. For non-RGB spaces
(CMYK, CIE-based, Lab, Separation, DeviceN), drop down to
JetsonPDF.Color.Cmyk(...) / JetsonPDF.Color.InSpace(...).
Document-level config
Four builders feed catalog entries the layout engine doesn't see directly:
Outline / bookmarks
FluentDocument.Create(d => { /* ... use .Section("intro"), .Section("ch1") etc. */ })
.WithOutline(o =>
{
o.Item("Introduction", "intro").Bold().Expanded();
o.Item("Chapter 1", "ch1", inner =>
{
inner.Item("Section 1.1", "ch1-1");
inner.Item("Section 1.2", "ch1-2").Italic();
});
o.Item("Chapter 2", "ch2");
})
.GeneratePdf("out.pdf");
Outline entries reference named destinations registered via .Section(anchor)
on a slot. Bold() / Italic() set the entry's display font; Expanded()
opens the entry's children when the document opens.
Conformance
doc.WithConformance(JetsonPDF.Conformance.PdfA1b)
.WithLanguage("en-US")
.WithOutputIntent(/* OutputIntent for PDF/A */);
PDF/A-1b, PDF/A-2/3 (a/u/b variants), PDF/UA-1, PDF/UA-2 are all available
flags. The fluent layer just sets the catalog flag and hands off to
JetsonPDF.Writer, which emits the right XMP namespaces and viewer prefs.
Conformance is declarative — the writer doesn't refuse non-conforming
content; pair with doc.Validate() (on the underlying Document) for
checking, or trust your generation code.
Page labels
doc.WithPageLabels(pl =>
{
// Front matter: i, ii, iii, iv
pl.Range(0, JetsonPDF.PageLabelStyle.LowerRoman);
// Body: 1, 2, 3, ...
pl.Range(4, JetsonPDF.PageLabelStyle.DecimalArabic);
// Appendix: A-1, A-2, ...
pl.Range(48, JetsonPDF.PageLabelStyle.DecimalArabic, prefix: "A-");
});
Each .Range(startPageIndex, style, prefix?, startNumber?) overrides viewer
display from that page onwards. Page labels are independent of physical
page-tree order — they're a viewer-facing string scheme.
Optional content layers (OCG)
var doc = FluentDocument.Create(d =>
{
d.Page(p =>
{
// ...
p.Content().Layer(designLayer).Text("Visible by default");
p.Content().Layer(notesLayer).Text("Hidden by default");
});
});
var designLayer = doc.WithLayer("Design", visibleByDefault: true);
var notesLayer = doc.WithLayer("Notes", visibleByDefault: false);
doc.GeneratePdf("out.pdf");
.WithLayer(name [, visibleByDefault, intent]) returns a LayerHandle that
slot-chain .Layer(handle) calls reference. Viewers (Acrobat, Foxit, etc.)
expose the layers panel so end-users can toggle visibility without
regenerating the document. Layers are registered on the Document
instance, not via the FluentDocument.Create callback — assign before calling
GeneratePdf so the body's .Layer(handle) references resolve.
Limitations
- Standard 14 fonts use WinAnsi (Windows-1252) encoding. That covers
Latin-1 plus the CP1252 extras (
€,™, smart quotes, etc.) but not Unicode arrows (↑↓→←›‹), em dashes outside CP1252, or any non-Latin script. Characters outside WinAnsi render as?(the WinAnsinotdefglyph). If your text needs them, register a TrueType font with full Unicode coverage:
Embedded TrueType fonts go through Identity-H composite encoding and carry their ownFluentDocument.Create(d => { /* ... */ }) .WithFonts(reg => { reg.RegisterFromFile("Inter", JetsonPDF.FontStyle.Regular, "Inter-Regular.ttf"); }) .WithDefaultTextStyle(s => s.FontFamily = "Inter") .GeneratePdf("out.pdf");cmap, so any glyph the font supplies is renderable. - Rich text rotation: wrapped multi-style paragraphs preserve per-run styles per line, but baseline alignment uses the line's max ascent across styles. Mixed font sizes within a single line align on the larger baseline; substantially different sizes may look top-heavy.
- Stack and Row don't paginate. A child returning Partial inside a Stack
or Row causes the whole container to report Wrap. Wrap your content in
Columnif you need pagination. - Two-pass renderer assumes single-iteration convergence. A dynamic
component whose composed size depends on
TotalPagesEstimatecould in principle produce a different final page count in pass 2 than pass 1. In practice "Page X of Y" components produce identical-shape content, so the count is stable. If you hit a divergence case, route page-number text through the rich text descriptor instead — it uses deferred-text resolution that doesn't re-layout. - Form widget appearance uses the PDF reader's default chrome (Acrobat
draws its own). Custom appearance streams are an
JetsonPDF.Writerfeature, not exposed via fluent yet. - PDF native alpha isn't surfaced in
Colors—Colorcarries no alpha channel. Translucency requires an/ExtGStateon the underlying page (drop down toJetsonPDF.Writer).
Targets
net8.0netstandard2.0net462
License
MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- JetsonPDF.Common (>= 1.1.0)
- JetsonPDF.Writer (>= 1.1.0)
- Microsoft.Bcl.HashCode (>= 6.0.0)
- System.Buffers (>= 4.5.1)
- System.Memory (>= 4.5.5)
- System.ValueTuple (>= 4.5.0)
-
.NETStandard 2.0
- JetsonPDF.Common (>= 1.1.0)
- JetsonPDF.Writer (>= 1.1.0)
- Microsoft.Bcl.HashCode (>= 6.0.0)
- System.Buffers (>= 4.5.1)
- System.Memory (>= 4.5.5)
-
net8.0
- JetsonPDF.Common (>= 1.1.0)
- JetsonPDF.Writer (>= 1.1.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on JetsonPDF.Fluent:
| Package | Downloads |
|---|---|
|
JetsonPDF.Flow
Word-like retained-mode DOM (Section / Paragraph / Run / Table) with auto-pagination, layered on JetsonPDF.Fluent. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0 | 31 | 6/6/2026 |
| 1.0.0 | 134 | 5/23/2026 |
| 0.2.0-preview | 131 | 5/23/2026 |
| 0.1.0-preview | 132 | 5/17/2026 |