Serien-PDFs mit Inkscape erstellen

Gelegentlich komme ich in Situationen, in denen ich automatisch PDF-Dokumente erzeugen lassen möchte, die sich nur an bestimmten Stellen unterscheiden.

Das können Namensschilder mit Design sein, bei denen lediglich die Namen von Schild zu Schild unterschiedlich sind, oder Preisschildchen, oder Bauchbinden1 und so weiter…

Oft greife ich dann zu einer Kombination aus Inkscape und einer Skriptsprache, um ans Ziel zu kommen. Die Idee funktioniert folgendermaßen:

  • Zunächst wird ein Template mit Platzhaltern erstellt
  • Die Platzhalter werden mit einer Skriptsprache durch die echten Werte ersetzt und dann in einer separaten SVG-Datei gespeichert
  • Diese SVG-Dateien werden schließlich in PDF-Dateien umgewandelt

Warum das Ganze? Nun, PDF-Dateien lassen sich so schwer bearbeiten. SVG-Dateien hingegen bestehen nur aus Text. Buchstaben, Zahlen und Klammern. Darin lässt es sich ganz leicht herumeditieren.

Für alle, die mehr auf grafische Darstellungen stehen:

pdfpipeline

Wir beginnen mit unseren Daten, die wir ins Template einfügen möchten. Als Beispiel nehmen wir hier Deckblätter für Bekanntmachungen in der AKUT extra2. Die benötigen ein Veröffentlichungsdatum, eine laufende Nummer und natürlich einen Titel.

datum;nummer;titel
17. Juli 2016;6/2016;Satzung der Fachschaft … Bonn
11. Juli 2016;5/2016;Wahlordnung für die Wahl …
31. Juni 2016;3/2016;Änderung der Satzung …

Zu Demonstrationszwecken speichern wir diese Daten in einer Datei namens data.csv.

Als nächstes erstellen wir mit Inkscape das SVG-Template, in das die Werte eingefügt werden.

Dort, wo aktuell VARDATUM, VARNUMMER und VARTITEL steht, werden später die echten Werte eingesetzt. Der Rest ist Zierde.

Comic Saaaaaaanns!3

Dort, wo aktuell VARDATUM, VARNUMMER und VARTITEL steht, werden später die echten Werte eingesetzt. Der Rest ist Zierde. Da der Titel auch mal länger als eine Zeile werden kann, nutzen wir einen Textkasten, in dem der Text automatisch umgebrochen wird.

Das Template speichern wir als template.svg.

Als letztes Puzzlestück fehlt nur noch ein Skript, das die Werte aus der CSV-Datei nimmt und sie ins Template einfügt. Ich habe mich hier als Beispiel für Python entschieden, das Prinzip lässt sich aber mit so gut wie jeder anderen Skript- und Programmiersprache umsetzen.

(Hinweis: Zeilen mit # am Anfang sind Kommentare, die den Programmfluss nicht beeinflussen.)

#! /usr/bin/env python3

import csv
import subprocess

# csv-Datei einlesen
data = []
with open("data.csv", "r") as csvfile:
    reader = csv.DictReader(csvfile, delimiter=";")
    for row in reader:
        data.append(row)


# Für jede Zeile aus der csv-Datei: 
# - Template laden
# - Variablen ersetzen
# - als neue SVG-Datei output-i.svg speichern

i = 0
for row in data:
    with open("template.svg", "r") as t, open("output-{0}.svg".format(i), "w") as output:
        
        # In jeder Zeile wird die Variable (falls vorhanden) durch den
        # entsprechenden Wert ersetzt
        for line in t:
            line = line.replace("VARDATUM", row["datum"])
            line = line.replace("VARNUMMER", row["nummer"])
            line = line.replace("VARTITEL", row["titel"])
            
            # modifizierte Zeile in output schreiben
            print(line, file=output, end="")
    i += 1


# SVG-Dateien mit Inkscape in PDF-Dateien umwandeln

for k in range(i):
    subprocess.call(["inkscape", 
          "--export-pdf=output-{0}.pdf".format(k), 
          "output-{0}.svg".format(k)])

Oben wird data.csv eingelesen. In der Mitte wird immer wieder template.svg geöffnet und die oben verwendeten Variablen (VAR…) werden durch die echten Werte ersetzt. Natürlich können diese Namen beliebig angepasst werden.

Ganz am Ende konvertiert das Skript alle erzeugten SVG-Dateien mit Inkscape automatisiert in PDF-Dateien.

screenshot-result-svgpdf

Juhu! Drei neue PDF-Dateien!

Und das Ergebnis kann sich sehen lassen:

resultat-svgpdf

Falls die Inhalte komische Sonderzeichen wie z. B. &, ” oder < enthalten, muss das Skript noch so angepasst werden, dass diese durch ihre XML-Repräsentation ersetzt werden. Wie das in Python geht, steht z.B. hier.

  1. Wobei die als png exportiert wurden, nicht als PDF. Funktioniert aber auf die gleiche Art und Weise.
  2. Das hat ja überhaupt gar nichts damit zu tun, dass ich so etwas ähnliches heute implementiert habe.
  3. http://explosm.net/comics/2301/