Vorlagen, von Brevier gesetzt

Das sind die Vorlagen, die Brevier selbst mitbringt. Jedes Bild auf dieser Seite ist eine Seite des PDFs, das Brevier 0.6.0 aus ihnen gesetzt hat. Alle Namen, Zahlen und die IBAN sind erfunden. Die letzten beiden Vorlagen wurden importiert: die Mahnung aus einer Word-Datei und der Kontoauszug aus einer JasperReports-Datei.

Rechnung mit Übertrag

Eine deutsche Rechnung auf A4, mit 70 Positionen auf 4 Seiten. Wo die Tabelle umbricht, steht die Zwischensumme unten auf der Seite und oben auf der nächsten noch einmal.

Die Vorlage braucht dafür zwei Attribute. Brevier findet die Seitenwechsel, fügt die Zeilen ein und rechnet mit exakten Dezimalzahlen.

Aus rechnung.html
<table class="positions" data-brevier-uebertrag="true">
<thead>
<tr><th>Pos.</th><th>Leistung</th><th class="num">Menge</th><th class="num">Einzelpreis</th><th class="num" data-brevier-carry="true">Gesamt</th></tr>
</thead>

Gezeigte Funktionen: Übertrag, Tabellen über mehrere Seiten

Seite 1: Übertrag 8.152,45 € schließt die Tabelle.
Seite 1: Übertrag 8.152,45 € schließt die Tabelle.
Seite 2: Dieselbe Summe eröffnet die Tabelle wieder.
Seite 2: Dieselbe Summe eröffnet die Tabelle wieder.

Kontoauszug, aus JasperReports importiert

Ein Kontoauszug mit 70 Buchungen auf 3 Seiten. Die Vorlage war eine JasperReports-Datei (.jrxml). Brevier hat daraus das HTML, das CSS und das JSON Schema geschrieben.

Jeder Parameter wurde zu einem Tag mit seinem Namen. Das Detail-Band wurde zu einer Schleife über rows, wie der Ausschnitt zeigt. Die Tabelle hat das Attribut data-brevier-uebertrag, darum läuft die Zwischensumme auf die nächste Seite.

Importiert aus der JasperReports-Datei kontoauszug.jrxml.

Import-Befehl
brevier import kontoauszug.jrxml -o templates/kontoauszug
Aus kontoauszug.html
<table class="report-table" data-brevier-uebertrag="true">
{{#each rows}}
<tr><td>{{buchungstag}}</td><td>{{valuta}}</td><td>{{vorgang}}</td><td>{{buchungstext}}</td><td class="amount">{{betrag}}</td></tr>

Gezeigte Funktionen: Import aus JasperReports und BIRT, Aufruf ersetzen, Übertrag

Seite 1: der Seitenkopf, und Übertrag 9.873,45 € schließt die Tabelle.
Seite 1: der Seitenkopf, und Übertrag 9.873,45 € schließt die Tabelle.
Seite 3: derselbe Kopf und Tabellenkopf, und Übertrag 20.255,20 € eröffnet die Tabelle.
Seite 3: derselbe Kopf und Tabellenkopf, und Übertrag 20.255,20 € eröffnet die Tabelle.

Der Aufruf vorher und nachher

Ein Dienst, der einen JasperReports-Bericht füllt, ruft Jasper oder einen JasperReports Server auf, der das PDF erzeugt. Mit Brevier macht derselbe Dienst einen einzigen Aufruf, und das PDF hat denselben Text. Der Code stammt aus einem Beispiel, das die Tests von Brevier ausführen.

Sprache des Aufrufs
// Vorher: JasperReports
try (InputStream stream = Files.newInputStream(Paths.get("kontoauszug", "java", "before-jasper", "kontoauszug.jrxml"))) {
    JasperReport report = JasperCompileManager.compileReport(stream);
    JasperPrint print = JasperFillManager.fillReport(report, params, new JRBeanCollectionDataSource(buchungen));
    return JasperExportManager.exportReportToPdf(print);
}

// Nachher: Brevier
return Brevier.template("kontoauszug").render(konto, kunde, buchungen);

Client hinzufügen

Gradle
implementation 'dev.brevier:brevier'
Maven
<artifactId>brevier</artifactId>
# Vorher: pyreportjasper
report = PyReportJasper()
report.config(
    str(JRXML),
    str(output),
    ["pdf"],
    parameters=_parameters(konto, kunde),
    db_connection=source,
)
report.process_report()
return output.with_suffix(".pdf").read_bytes()

# Nachher: Brevier
return brevier.template("kontoauszug", templates=TEMPLATES).render(konto, kunde, buchungen)

Client hinzufügen

pip
pip install brevier
// Vorher: JasperReports Server
const started = await fetch(`${server.baseUrl}/rest_v2/reportExecutions`, {
    method: "POST",
    headers: { ...headers, "Content-Type": "application/json", Accept: "application/json" },
    body: JSON.stringify({
        reportUnitUri: "/reports/kontoauszug",
        async: false,
        outputFormat: "pdf",
        parameters: { reportParameter: reportParameters(konto, kunde, buchungen) },
    }),
});

// Nachher: Brevier
return await Brevier.template("kontoauszug").render({ konto, kunde, buchungen });

Client hinzufügen

npm
npm install brevier
// Vorher: JasperReports Server
var request = new
{
    reportUnitUri = "/reports/kontoauszug",
    @async = false,
    outputFormat = "pdf",
    parameters = new { reportParameter = ReportParameters(konto, kunde, buchungen) },
};
using HttpResponseMessage started =
    await client.PostAsJsonAsync($"{root}/rest_v2/reportExecutions", request);

// Nachher: Brevier
return Brevier.Template("kontoauszug").Render(konto, kunde, buchungen);

Client hinzufügen

.NET CLI
dotnet add package Brevier

Versicherungsbrief mit Kleingedrucktem

Ein Brief nach DIN 5008, mit den neuen Bedingungen als Anlage, kleingedruckt in zwei schmalen Spalten. Lange Komposita wie Obliegenheitsverletzung brauchen dort viele Trennstriche.

Der deutsche Satz erlaubt höchstens 3 getrennte Zeilen hintereinander und keinen Trennstrich vor einem Seitenwechsel. Ohne Hilfe bricht dieser Brief beide Regeln. Brevier findet diese Zeilen nach dem Satz und setzt sie neu. Die Vorlage sagt nur, dass der Text deutsch ist.

Aus versicherungsbrief.css
.columns {
  columns: 2;
  column-gap: 8mm;
  font-size: 9.65pt;
  line-height: 1.3;
}

Gezeigte Funktionen: Deutsche und englische Silbentrennung

Seite 1: der Brief, dann die Bedingungen. Die letzte Zeile vor dem Seitenwechsel endet ohne Trennstrich.
Seite 1: der Brief, dann die Bedingungen. Die letzte Zeile vor dem Seitenwechsel endet ohne Trennstrich.
Seite 2: nie mehr als 3 getrennte Zeilen hintereinander.
Seite 2: nie mehr als 3 getrennte Zeilen hintereinander.

Silbentrennung zum Nachschlagen

Ein deutsches Merkblatt mit 2 Seiten. Es zeigt, wie Komposita an ihren Fugen brechen, wie Sie Brevier eigene Wörter beibringen und wie Markennamen und Webadressen ganz bleiben.

Zwei CSS-Zeilen auf :root legen die Sprache und die gelehrten Trennstellen fest. Eine dritte Zeile nennt die Wörter, die nie getrennt werden. Schmale Spalten auf Seite 2 zeigen das Ergebnis.

Aus silbentrennung.css
--brevier-hyphenate-language: "de";
--brevier-hyphenate-teach: "Donaudampf=schiff=fahrt, Kredit=karten=abrechnung, Umsatz=steuer=voranmeldung";

Gezeigte Funktionen: Deutsche und englische Silbentrennung

Seite 1: falsche Trennungen neben den Trennungen von Brevier, dann die CSS-Einstellungen.
Seite 1: falsche Trennungen neben den Trennungen von Brevier, dann die CSS-Einstellungen.
Seite 2: geschützte Webadressen, geschützte Leerzeichen und die schmalen Spalten.
Seite 2: geschützte Webadressen, geschützte Leerzeichen und die schmalen Spalten.

Rechnung mit Factur-X (ZUGFeRD)

Eine deutsche Rechnung auf A4 mit 3 Positionen zu 19 % und 7 % Umsatzsteuer. Das PDF enthält die Rechnung zusätzlich als Daten, in der Datei factur-x.xml, damit die Software des Empfängers sie ohne Abtippen verbuchen kann.

Die Seite und das XML kommen aus demselben JSON. Mit --einvoice prüft Brevier, ob die Beträge stimmen, bevor es die Datei schreibt. Das PDF ist PDF/A-3b.

Aus sample.json
"lineNet": 3039.00,
"tax": 571.53,
"gross": 3610.53,

Gezeigte Funktionen: E-Rechnungen mit ZUGFeRD und Factur-X, PDF/A-3b für die Archivierung, Briefe und Rechnungen nach DIN 5008

Seite 1: die Rechnung, brutto 3.610,53 €. Das XML steckt im PDF.
Seite 1: die Rechnung, brutto 3.610,53 €. Das XML steckt im PDF.

Geschäftsbrief nach DIN 5008, Form B

Ein deutscher Geschäftsbrief auf A4 für den Fensterumschlag. Anschrift, Infoblock, Falzmarken und Fußzeile stehen dort, wo DIN 5008 sie vorsieht.

Sie geben Rohwerte an. Brevier schreibt jeden Wert nach DIN: Die Telefonnummer +49 (0)5444 347687-350 steht als +49 5444 347687-350 im Brief, und die IBAN steht in Vierergruppen.

Aus sample.json
"telefon": "+49 (0)5444 347687-350",
"iban": "de89370400440532013000",
"bic": "erfbde8e759"

Gezeigte Funktionen: Briefe und Rechnungen nach DIN 5008, Beträge, Datum und Zahlen, HTML-Vorlagen gegen ein JSON-Schema validieren

Seite 1: die Anschrift im Fenster, der Infoblock und die Fußzeile mit IBAN und BIC.
Seite 1: die Anschrift im Fenster, der Infoblock und die Fußzeile mit IBAN und BIC.

Zahlungserinnerung, aus Word importiert

Eine deutsche Zahlungserinnerung (Mahnung) auf 1 Seite, mit einer Tabelle von 2 Positionen. Die Vorlage war eine Word-Datei mit Serienbrieffeldern. Brevier hat daraus das HTML, das CSS und das JSON Schema geschrieben.

Jedes Serienbrieffeld wurde zu einem Tag in doppelten geschweiften Klammern, und die Tabellenzeile in der Schleife wurde zu einem each-Block, wie der Ausschnitt zeigt. Kopf- und Fußzeile von Word wurden zu laufender Kopf- und Fußzeile. Nach dem Import wurden die Dateien von Hand bearbeitet.

Importiert aus der Word-Datei mahnung.docx.

Import-Befehl
brevier import mahnung.docx -o templates/mahnung
Aus mahnung.html
<h1 class="Heading1">Zahlungserinnerung Nr. {{ mahnung.nummer }}</h1>
{{#each mahnung.posten}}<tr><td><p>{{ bezeichnung }}</p></td><td><p>{{ menge }}</p></td><td><p>{{ betrag }}</p></td></tr>{{/each}}

Gezeigte Funktionen: Import aus Word, Aufruf ersetzen

Seite 1: der Brief. Kopf- und Fußzeile von Word stehen auf der Seite.
Seite 1: der Brief. Kopf- und Fußzeile von Word stehen auf der Seite.

Der Aufruf vorher und nachher

Ein Dienst, der eine Word-Datei mit Serienbrieffeldern füllt, ruft eine Bibliothek auf, die das PDF erzeugt. Mit Brevier macht derselbe Dienst einen einzigen Aufruf. Der Code stammt aus einem Beispiel, das die Tests von Brevier ausführen.

Sprache des Aufrufs
// Vorher: XDocReport
try (InputStream template = Files.newInputStream(Paths.get("mahnung", "mahnung.docx"))) {
    IXDocReport report = XDocReportRegistry.getRegistry()
        .loadReport(template, TemplateEngineKind.Velocity);
    IContext context = report.createContext();
    context.putMap(data);
    ByteArrayOutputStream pdf = new ByteArrayOutputStream();
    Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF);
    report.convert(context, options, pdf);
    return pdf.toByteArray();
}

// Nachher: Brevier
return Brevier.template("mahnung").render(mahnung, kunde);

Client hinzufügen

Gradle
implementation 'dev.brevier:brevier'
Maven
<artifactId>brevier</artifactId>
# Vorher: docxtpl
doc = DocxTemplate(TEMPLATE)
context = {"kunde": kunde, "mahnung": mahnung}
doc.render(context)
stream = BytesIO()
doc.save(stream)
return stream.getvalue()

# Nachher: Brevier
return brevier.template("mahnung", templates=TEMPLATES).render(mahnung, kunde)

Client hinzufügen

pip
pip install brevier
// Vorher: docxtemplater
const content = fs.readFileSync(TEMPLATE_PATH);
const zip = new PizZip(content);
const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, parser });
const data = { kunde, mahnung };
doc.render(data);
return doc.getZip().generate({ type: "nodebuffer", compression: "DEFLATE" });

// Nachher: Brevier
return await Brevier.template("mahnung").render({ kunde, mahnung });

Client hinzufügen

npm
npm install brevier
// Vorher: DocxTemplater
byte[] content = File.ReadAllBytes(TemplatePath);
using var inputStream = new MemoryStream(content);
using var template = new DocxTemplate(inputStream);
template.BindModel("kunde", kunde);
template.BindModel("mahnung", mahnung);

using var outputStream = new MemoryStream();
template.Save(outputStream);
return outputStream.ToArray();

// Nachher: Brevier
return Brevier.Template("mahnung").Render(mahnung, kunde);

Client hinzufügen

.NET CLI
dotnet add package Brevier