3. Tables, lists, images
Structured content: tables, ordered and unordered lists, and embedded images.
Paragraphs carry prose; this chapter covers the three block types that carry structure. Tables, lists, and images are all blocks, so they sit alongside paragraphs in a section and inherit the same styling and layout machinery. Each has a fluent helper that keeps the common case short.
using Rivoli.Pdf;using Rivoli.Pdf.Builders;using Rivoli.Pdf.Model;Tables
Section titled “Tables”A Table has an optional header row and any number of data rows. The fluent
helper is AddTable, which hands you a Table to configure:
section.AddTable(table => table .Header("Quarter", "Revenue", "Profit") .Row("Q1", "$1.2M", "$200K") .Row("Q2", "$1.5M", "$250K") .Row("Q3", "$1.8M", "$310K"));Header, Row, and Rows each return the table, so they chain. Use Rows when
you already have the data as a collection: it adds many data rows at once:
section.AddTable(table => table .Header("Name", "Role") .Rows( new[] { "Ada", "Engineer" }, new[] { "Grace", "Architect" }, new[] { "Alan", "Researcher" }));Header and Row are fluent aliases for the underlying AddHeaderRow and
AddDataRow methods on Table; reach for those directly if you prefer.
Column widths
Section titled “Column widths”By default columns size themselves to their content. To pin them, set fixed
widths (in points) on the Table:
section.AddTable(table =>{ table.SetFixedColumnWidths(120, 240); table.Header("Field", "Value") .Row("Order ID", "A-10293") .Row("Status", "Shipped");});SetColumnWidths accepts ColumnWidth values for proportional or auto widths
when you need a mix; SetFixedColumnWidths is the simple all-points form.
Lists come in two flavours, with dedicated helpers for each:
section.AddUnorderedList(list => list .Item("First finding") .Item("Second finding") .Item("Third finding"));
section.AddOrderedList(list => list .Items("Gather data", "Run analysis", "Publish report"));Item(text) adds one item and returns the list; Items(...) adds several at
once, accepting either a params string[] or an IEnumerable<string>. Both
helpers chain.
Behind the helpers, a list is a List block created by List.Unordered() or
List.Ordered(). You can build one directly and add it with section.Add(...):
useful when you want to set list properties:
var list = List.Ordered(startNumber: 5); // numbering starts at 5list.Add("Fifth step");list.Add("Sixth step");section.Add(list);List also exposes MarkerStyle (Disc, Circle, Square, or Custom with a
CustomMarker character) for unordered lists, and StartNumber for ordered ones.
Nesting
Section titled “Nesting”List items nest. A ListItem has its own Items collection and an Add method,
so you build sub-lists by adding items to an item rather than to the list:
var outline = List.Unordered();
var chapter = new ListItem("Chapter 1");chapter.Add("Section 1.1") .Add("Section 1.2");
outline.Add(chapter);outline.Add("Chapter 2");
section.Add(outline);ListItem.Add(string) appends a nested item and returns the parent item, so a
chain of Add calls builds siblings under the same parent. Nest as deeply as the
content requires: each level indents under its parent’s marker.
Images
Section titled “Images”Images appear at two scopes: as a block on their own, or inline within a line of text.
Block images
Section titled “Block images”AddImage places an image as its own block, loaded from a file path. Width and
height are optional points; omit them to use the image’s natural size:
section.AddImage("logo.png"); // natural sizesection.AddImage("chart.png", width: 360, height: 200);Under the helper this builds an ImageBlock. Build one directly for more control
: alignment, or sizing mode:
var figure = new ImageBlock("diagram.png") .WithSize(400, 260) .WithAlignment(Rivoli.Pdf.Styling.TextAlignment.Center);section.Add(figure);Inline images
Section titled “Inline images”An InlineImage flows inside a paragraph, on the text baseline, for an icon next
to a word, or a small inline glyph. Add it to a paragraph’s inlines:
var para = new Paragraph();para.Add("Build passing ");para.Inlines.Add(new InlineImage("check.png", width: 12, height: 12));para.Add(", all checks green.");section.Add(para);InlineImage carries a BaselineOffset you can set to raise or lower it relative
to the surrounding text, which is handy for fine vertical alignment against the
line.
Putting it together
Section titled “Putting it together”using Rivoli.Pdf;using Rivoli.Pdf.Builders;using Rivoli.Pdf.Model;
var doc = Document.Create("Structured Content");doc.DefaultPageSize = PageSize.A4;doc.DefaultMargin = Margin.Standard;
var section = doc.AddSection();section.H1("Results");
section.AddTable(table => table .Header("Metric", "Value") .Row("Revenue", "$5.4M") .Row("Margin", "22%"));
section.AddSpace();section.H2("Next steps");section.AddOrderedList(list => list .Items("Review with the board", "Approve budget", "Kick off Q4 plan"));
doc.SavePdf("structured.pdf");You’ve now covered the document model, styling, and structured content. From here:
- How-to guides: task-focused recipes for headers and footers, page numbers, security, and more.
- Components & reuse: packaging repeated structure into reusable building blocks.