Create PDF with QuestPDF open source and easy to use

Tohid haghighi
3 min readNov 3, 2023

--

In this article we show how to create PDF documents using the QuestPDF library.

Portable Document Format (PDF) is a versatile file format created by Adobe that gives people an easy, reliable way to present and exchange documents.

QuestPDF is an open-source .NET library for PDF generation. The library uses Skia to do the rendering. QuestPDF uses Fluent API.

Pdf sample

C# QuestPDF simple example

The following example creates a simple PDF file.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

var doc = Document.Create(container => container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);
page.DefaultTextStyle(x => x.FontSize(12));

page.Content()
.Column(x => x.Item().Text(Placeholders.Paragraph()));
}));

doc.GeneratePdf("simple.pdf");

The PDF document contains one paragraph of text.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

We import the QuestPDF types.

var doc = Document.Create(container => container.Page(page =>

The document is created with Document.Create. A new page is added with Page.

page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);
page.DefaultTextStyle(x => x.FontSize(12));

We set some basic properties of a page: the page size, margines, and default font size.

page.Content()
.Column(x => x.Item().Text(Placeholders.Paragraph()));

The content is added with Content. It consists of one column of text. Into the column, we add one text item. The Placeholders.Paragraph creates a lorem impsum paragraph of text.

doc.GeneratePdf("simple.pdf");

C# QuestPDF text

In the next example, we work with various text attributes.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

var doc = Document.Create(container => container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

page.Content()
.Column(x =>
{
x.Item().Text(Placeholders.Sentence());
x.Spacing(10);
x.Item().Text(Placeholders.Sentence()).FontSize(15);
x.Spacing(10);
x.Item().Text(Placeholders.LoremIpsum());
x.Spacing(10);
x.Item().Text(Placeholders.Paragraph()).FontFamily("Georgia");
x.Spacing(10);
x.Item().Text(Placeholders.Sentence()).FontColor(Colors.Blue.Darken3);
x.Spacing(10);
x.Item().Text(txt =>
{
txt.Span("C# ").Italic();
txt.Span("is a modern, object-oriented, and type-safe programming language.");
});

});
}));

doc.GeneratePdf("text.pdf");

In the program, we utilize the Sentence, Paragraph, LoremIpsum helper methods to generate some filler text.

x.Item().Text(Placeholders.Sentence());
x.Spacing(10);
x.Item().Text(Placeholders.Sentence()).FontSize(15);

We add two sentences. A spacing is added between them with Spacing. The FontSize sets the size of the font for the sentence.

x.Item().Text(Placeholders.Paragraph()).FontFamily("Georgia");

For this paragraph, we choose the Georgia font.

x.Item().Text(Placeholders.Sentence()).FontColor(Colors.Blue.Darken3);

C# QuestPDF header & footer

For the next document, we add a header and a footer.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

var doc = Document.Create(container => container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

page.Header()
.Text("My header")
.SemiBold().FontSize(24).FontColor(Colors.Blue.Medium);

page.Content()
.PaddingVertical(1, Unit.Centimetre)
.Column(x =>
{

x.Item().Text(Placeholders.LoremIpsum());
x.Spacing(20);
x.Item().Text(Placeholders.LoremIpsum());
});

page.Footer()
.Text(x =>
{
x.Span("Page ");
x.CurrentPageNumber();
});
}));

doc.GeneratePdf("headfoot.pdf");

The document has three parts: header, content, and footer.

page.Header()
.Text("My header")
.SemiBold().FontSize(24).FontColor(Colors.Blue.Medium);

A header is added with Header. We change the font weight with SemiBold, font size with FontSize and font colour with FontColor.

page.Content()
.PaddingVertical(1, Unit.Centimetre)
.Column(x =>
{
x.Item().Text(Placeholders.LoremIpsum());
x.Spacing(20);
x.Item().Text(Placeholders.LoremIpsum());
});

The page content is added with Content. We add two paragraphs and a spacing between them.

page.Footer()
.Text(x =>
{
x.Span("Page ");
x.CurrentPageNumber();
});

C# QuestPDF lines

In the next example, we add some horizontal lines to the page.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

var doc = Document.Create(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

page.Content()
.Column(x =>
{
x.Item().Text(Placeholders.Paragraph());
x.Item().PaddingVertical(5).LineHorizontal(1);
x.Item().Text(Placeholders.Paragraph());
x.Item().PaddingVertical(5).LineHorizontal(1).LineColor(Colors.LightBlue.Darken3);
x.Item().Text(Placeholders.Paragraph());
x.Item().PaddingVertical(5).LineHorizontal(2);
x.Item().Text(Placeholders.Paragraph());
});
});
});

doc.GeneratePdf("lines.pdf");

C# QuestPDF borders

In the next example, we add some borders.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

Action<IDocumentContainer> container = (container) => container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

page.Content()
.Column(x =>
{
x.Item().Border(1).Padding(5).Text(Placeholders.Paragraph());
x.Item().Border(1).Padding(5).Text(Placeholders.Paragraph());
x.Item().Border(1).Padding(5).Text(Placeholders.Paragraph());
});
});


var doc = Document.Create(container);
doc.GeneratePdf("borders.pdf");

We have three paragraphs of text. We place some borders around these paragraphs.

x.Item().Border(1).Padding(5).Text(Placeholders.Paragraph());

We add a border with Border and some padding with Padding.

C# QuestPDF table

The next example generate a table inside the PDF document.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

var fonts = new[]
{
Fonts.Calibri,
Fonts.Georgia,
Fonts.Arial,
Fonts.TimesNewRoman,
Fonts.Consolas,
Fonts.Tahoma,
Fonts.Verdana,
Fonts.Trebuchet,
Fonts.ComicSans
};

var doc = Document.Create(container => container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

page.Content()
.Column(x => x.Item().Table(table =>
{
table.ColumnsDefinition(cols =>
{
cols.ConstantColumn(150);
cols.ConstantColumn(150);
});

table.ExtendLastCellsToTableBottom();

foreach (var font in fonts)
{
table.Cell().MinWidth(120).Border(1).Padding(5).Text(font).FontFamily(font);
}
}));
}));

doc.GeneratePdf("table.pdf");

The table has two columns and displayes text in various font families.

page.Content()
.Column(x => x.Item().Table(table =>
{

A table is added with Table.

table.ColumnsDefinition(cols =>
{
cols.ConstantColumn(150);
cols.ConstantColumn(150);
});

We define two table columns of fixed width.

table.ExtendLastCellsToTableBottom();

The last cell is enlarged to the bottom of the table if the cells are not even.

--

--

Tohid haghighi
Tohid haghighi

Written by Tohid haghighi

Full-Stack Developer | C# | .NET Core | Vuejs | TDD | Javascript

No responses yet