Brevier The full-stack PDF library
Brevier generates PDF documents from the plainest web tools: HTML, CSS, JSON and Handlebars. Templates can be Markdown.
pip install brevierrechnung/rechnung.html
<!DOCTYPE html>
<html lang="de">
<head>
<title>Rechnung</title>
</head>
<body>
<p>{{ firma.name }}</p>
<h1>Rechnung</h1>
<table>
<tr><th>Text</th><th>Betrag</th></tr>
{{#each rechnung.positionen}}
<tr>
<td>{{ text }}</td>
<td>{{ betrag | money }}</td>
</tr>
{{/each}}
</table>
</body>
</html>rechnung/rechnung.css
@page {
size: A4;
margin: 20mm;
}
body {
font: 10pt sans-serif;
color: #16181c;
}
.absender { font-size: 7pt; }
address { margin: 2mm 0 15mm; }
h1 { font-size: 14pt; }
table { width: 100%; }
th, td { padding: 1.5mm 0; }
td:last-child {
text-align: right;
}rechnung/rechnung.json
{
"firma": {
"name": "Muster AG",
"ort": "Berlin"
},
"kunde": {
"name": "Erika M.",
"ort": "Köln"
},
"rechnung": {
"nr": "R-2026-01",
"positionen": [
{
"text": "Beratung",
"betrag": 84.2
}
]
}
}rechnung/rechnung.schema.json
{
"type": "object",
"properties": {
"firma": {
"type": "object"
},
"kunde": {
"type": "object"
},
"rechnung": {
"type": "object",
"properties": {
"nr": {
"type": "string"
},
"positionen": {
"type": "array",
"items": {
"type": "object",
"properties": {
"text": {
"type": "string"
},
"betrag": {
"type": "number"
}
}
}
}
}
}
}
}rechnung/rechnung.pdf

rechnung/rechnung.md
---
style: rechnung.css
---
{{ firma.name }}
An: {{ kunde.name }}
# Rechnung
| Text | Betrag |
| --- | ---: |
{{#each rechnung.positionen}}
| {{ text }} | {{ betrag | money }} |
{{/each}}rechnung/rechnung.css
@page {
size: A4;
margin: 20mm;
}
body {
font: 10pt sans-serif;
color: #16181c;
}
.absender { font-size: 7pt; }
address { margin: 2mm 0 15mm; }
h1 { font-size: 14pt; }
table { width: 100%; }
th, td { padding: 1.5mm 0; }
td:last-child {
text-align: right;
}rechnung/rechnung.json
{
"firma": {
"name": "Muster AG",
"ort": "Berlin"
},
"kunde": {
"name": "Erika M.",
"ort": "Köln"
},
"rechnung": {
"nr": "R-2026-01",
"positionen": [
{
"text": "Beratung",
"betrag": 84.2
}
]
}
}src/main/java/RechnungService.java
import dev.brevier.Brevier;
public class RechnungService {
public byte[] pdf(
Firma f,
Rechnung r,
Kunde k
) {
return Brevier
.template("rechnung")
.render(f, r, k);
}
}app/rechnung.py
import brevier
def pdf(
firma, rechnung, kunde
) -> bytes:
return brevier.template("rechnung").render(
firma, rechnung, kunde
)Everything a business document needs
Brevier handles the print rules, so you can focus on your data.
HTML and CSS templates
Write the page in plain HTML and CSS.
Markdown for static content documents
Turn a Markdown file into a PDF.
Data binding
Fill the HTML with your JSON data.
Validate HTML templates against a JSON schema
Find a misspelt field before anything prints.
Start from your classes
Get a first template from your own classes.
Import JasperReports and BIRT
Convert JasperReports and BIRT reports.
Import Word
Convert .docx files with merge fields.
Replace your render call
Swap your old render call for Brevier's.
The visible middle
See the exact HTML and CSS the engine got.
German and English hyphenation
Correct hyphenation in German and English.
Tables that span pages
Tables that repeat their header on every page.
Übertrag - Running totals
Running totals carried from page to page.
Headers, footers and page counters
Headers, footers and page numbers on every page.
Contracts and fine print
Numbered clauses and a table of contents.
Every feature, with its status
Open the feature list
A breviary is a prayer book — the German word for it is Brevier. Brevier is built to be your go-to library for generating PDFs programmatically, but also to easily integrate the PDF rendering in your web apps. Having fought clunky PDF tools for years, I built it to make document generation intuitive, simple, and seamless within your existing code.
Liviu IonesiDeveloper of BrevierBuilt on what you already know
HTML, CSS, JSON and your own code. Nothing new to learn.
HTML for the page
The template is an HTML page. Handlebars binds it with your data: values, loops and conditions.
developer.mozilla.orgCSS for the styling
CSS sets the fonts and colours, and the page layout too: size, margins, headers, footers and page numbers.
CSS @pageJSON for the data
Your objects are serialized as JSON. A JSON Schema validates every field before rendering.
json-schema.orgYour own code
Pass the objects you already have in Java, Python, .NET and TypeScript. Brevier writes them to JSON the same way in every language. From Java and Python classes, it also writes a JSON Schema and a starting template.
JavaPythonC#TypeScript
Install anywhere
Install Brevier with pip, a one-line script or Docker. It runs on Linux, macOS and Windows.
Call it from your language- pip
- Linux and macOS
- Windows
- Docker