QuestPDF - my open-source C# library for creating PDF documents with Fluent API needs your help
Today I would like to share with you a library that I am developing for over a year so far. QuestPDF, as the name suggests, is a tool that is created to help you with PDF document generation in any of your .NET projects. It offers a new way of describing documents content by combining simple LEGO-like structures into complex layouts, all of it with type safety, discoverable and predictable Fluent API.
Yesterday I deployed a new version of QuestPDF 2021.08 that comes with a couple of great additions. All of them making it even more stable and production-ready than ever before. The library is fully open-source, has a friendly MIT license and is available for free. But let me start from the very beginning.
How all have started
It all started with frustration when I had been assigned to a task related to generating reports by converting an HTML webpage into a PDF document. This markup language has a lot of eventual complexity, styling it and describing layout is surprisingly difficult and paging support is quite limited. Of course, HTML and CSS were not created for generating PDFs and require additional engines to accomplish the task.
And then, I have found a library called SkiaSharp (a Skia port for .NET) which is commonly used for rendering graphics in Chrome, Android and Xamarin. It also has support for PDF rendering - mind you, really simple and low-level support. So I decided to write a layouting engine designed with PDF file generation in mind.
Fundamental concepts
I have decided to follow a couple of core concepts. The library consists of many simple elements responsible for generating content (e.g. text, images, links) or arranging other elements in layouts (e.g. centering, footer/header support, table). Those elements are independent of each other and highly composable. That means, by combining simple to understand and predict behaviours, you can build complex and sophisticated layouts. The current version of the library comes with over 40 elements and I have plans to add even more!
Additionally, the code that describes the document's content should be short, easy to write and analyze, as well as simple to predict. To achieve this goal, I have created a DSL (domain-specific language) by providing a special Fluent API, fully created in C# and offering type safety. This gives you confidence in the code and (thanks to IntelliSense) allows you to easily discover all possible use-cases within a given context. And of course, all C# goodies (like conditions, loops, methods, etc.) are always available. You are not limited by any custom pseudo-language.
Just take a look at this simple example:
.Background(Colors.White)
.Padding(10)
.Decoration(decoration =>
{
var headerFontStyle = TextStyle
.Default
.Size(20)
.Color(Colors.Blue.Darken2)
.SemiBold();
decoration
.Header()
.PaddingBottom(10)
.Text("Example: scale component", headerFontStyle);
decoration
.Content()
.Stack(stack =>
{
var scales = new[] { 0.8f, 0.9f, 1.1f, 1.2f };
foreach (var scale in scales)
{
var backgroundColor = scale <= 1f
? Colors.Red.Lighten4
: Colors.Green.Lighten4;
var fontStyle = TextStyle.Default.Size(16);
stack
.Item()
.Border(1)
.Background(backgroundColor)
.Scale(scale)
.Padding(5)
.Text($"Content with {scale} scale.", fontStyle);
}
});
});
And its result:
Documentation
I did my best to not only create a high-quality library but also invested time in writing good documentation. You can start with a short Getting started tutorial that shows how to implement a simple invoice document under 200 lines of code. A working project with the entire code is available on a separate GitHub repository.
Then I suggest learning fundamentals about each of the available elements and components in the API reference section. You will find there detailed descriptions of applied rules, behaviours, layouting constraints, as well as many useful examples.
My plan for the future
I would like to spend more time on this project. Create even more useful elements, improve the debugging experience, add better support for text-related capabilities, increase performance and finally redesign documentation. Everything takes time and I need your help.
I am mostly thinking about creating a community that can make the library useful by simply using it, can provide feedback, drive future development and be the reason for the fundamental question "why?".
I truly believe that this library is positively different from any other alternative in the C# ecosystem, can fill the niche and someday be the no-brainer when comes to generating PDF documents.
How you can help
- Give the official QuestPDF repository a star ⭐ so more people will know about it,
- Give this post an upvote 👍,
- Observe 🤩 the library to know about each new release,
- Try out the sample project to see how easy it is to create an invoice 📊,
- Share your thoughts 💬 with me and your colleagues,
- Simply use the library in your projects 👨💻 and suggest new features,
- Contribute your own ideas 🆕 and be our hero.
Useful links
Nuget webpage - the webpage where the library is listed on the Nuget platform.
Getting started tutorial - a short and easy to follow tutorial showing how to design an invoice document under 200 lines of code.
API Reference - a detailed description of the behaviour of all available components and how to use them with the C# Fluent API.
Release notes and roadmap - everything that is planned for future library iterations, description of new features and information about potential breaking changes.
Patterns and practices - everything that may help you designing great reports and reusable code that is easy to maintain.