Ob Serienbrief oder Teilnehmerliste – mit dem richtigen Adapter befüllen Sie LaTeX-Dokumente problemlos mit den Feldinhalten einer Datenbank und erstellen so Druckerzeugnisse in perfekter Qualität.
Strukturierte Datensätze wie Adressen und Produktinformationen liegen in der Regel in Datenbanken. Zum Verarbeiten liest eine Applikation die Datensätze zunächst aus und setzt danach beispielsweise die Inhalte der einzelnen Felder an die jeweilige Position in einem Textbaustein ein. So entstehen Serienbriefe, Terminpläne, Namensschilder, Teilnehmerlisten und Veranstaltungsprogramme.
Zum Anbinden des Textsatzsystems LaTeX an eine Datenbank liegt nur vergleichsweise wenig Dokumentation vor. Häufig gerät sie erst bei einer intensiven Suche ins Blickfeld. Dabei stehen zwei gegensätzliche Verfahren und damit verbundene Vorgehensweisen zur Wahl.
Die erste Variante greift ausschließlich auf Bordmittel von LaTeX zurück und platziert die gesamte Logik zum Zugriff auf die Datenbank in der LaTeX-Datei. Bei der zweiten Variante kommt zusätzlich eine Programmiersprache wie Perl oder Python zum Einsatz. Mit dieser holen Sie die Daten und erzeugen im nächsten Schritt daraus ein LaTeX-Dokument.
Beiden Wegen gemeinsam ist der abschließende Schritt des Übersetzens des LaTeX-Codes ins gewünschte Format, sei es nun Postscript mittels latex und dvips oder PDF mittels pdflatex.
Den Ausgangspunkt für diesen Artikel bilden die drei Pakete Textmerg [1], Csvtools [2] und LaTeXDB [3]. Bei Debian und dessen Derivaten gehören Textmerg und Csvtools zum Paket texlive-latex-extra. LaTeXDB gibt es derzeit nur im CTAN [4], nicht als fertiges DEB- oder RPM-Paket. Alle Pakete binden Sie über das Kommando \usepackage{Paket} in der Präambel des Dokuments ein.
Textmerg
Textmerg ermöglicht das Einlesen von Datensätzen aus einer Textdatei. Dabei erstreckt sich ein vollständiger Datensatz über mehrere Textzeilen hinweg, jedes Feld des Datensatzes liegt in einer einzelnen Zeile. Zum Verarbeiten benötigt LaTeX noch Information zur Struktur der Textdatei und den einzelnen Feldern der Datensätze. Diesen Aufbau beschreiben Sie mit dem Kommando \Fields{Feldbezeichner}. Für drei Felder eines Beispielanschreibens kommt folgender Eintrag zum Einsatz:
\Fields{\Vorname\Name\Funktion}
LaTeX leitet daraus drei Variablen \Name, \Vorname und \Funktion ab. Bei der Wahl der Bezeichner haben Sie zwar freie Hand, sollten aber darauf achten, Kollisionen mit bestehenden Kommandos zu vermeiden.
Die Variablen dürfen Sie an beliebiger Stelle im Dokument platzieren. Noch sind sie jedoch leer – um sie mit sinnvollen Inhalten zu befüllen, teilen Sie LaTeX mit, in welcher Datei diese liegen. Dazu nutzen Sie zusätzlich das Kommando \Merge{Datei}. In Listing 1 heißt die Datei empfaengerliste.
Listing 1
...
\Fields{\Vorname\Name\Funktion}
...
\Merge{empfaengerliste}{%
An
\Vorname \Name \\
\Funktion \\
}
...
Sobald Sie das Dokument übersetzen, öffnet LaTeX in Zeile 4 die Datei empfaengerliste und befüllt bei jedem Durchlauf die Zeilen 6 und 7 entsprechend. Dabei arbeitet die Software die Datei mit den Datensätzen bis zum Ende durch. Alle Einträge landen in einem Dokument.
Listing 2 zeigt ein vollständiges Beispiel, eine Liste mit Besuchern für ein Konzert in der Stadt Stenkelfeld [5]. Jeder der fünf Einträge besteht aus dem Vornamen, dem Namen und der Funktion der Person aus der bekannten norddeutschen Hörspielserie. Abbildung 1 zeigt das Ergebnis nach dem Übersetzen des LaTeX-Codes aus Listing 3 mit Pdflatex.

Abbildung 1: Bei Bedarf generieren Sie mit LaTeX eine Teilnehmerliste für eine Veranstaltung aus den Daten einer Textdatei.
Listing 2
Friedhelm Pötter Leiter der Jürgen-Koppelin-Bildungsstätte Dr. Walter Broermeyer Wim-Thoelke-Universität Stenkelfeld Friedemann von Klöhnen Geriatriedekan, Heimleiter des Seniorenstifts am Höcklager Industrieweg Helmut Sönkel-Pörthagen Geschäftsführer der Großküche Stenkelfeld Dr. Bernwart Ölvermöhlen Direktor der Volksgenossenbank von 1936
Listing 3
\documentclass[10pt]{article}
\usepackage{german}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{palatino}
\usepackage{textmerg}
\begin{document}
\Fields{\Vorname\Name\Funktion}
\begin{center}
\huge{Teilnehmerliste zum Neujahrskonzert im Gasthof Knollmeyer}
\end{center}
~\\
\begin{itemize}
\Merge{teilnehmer}{%
\item \textbf{\Vorname ~\Name} \\ \Funktion \\
}
\end{itemize}
\end{document}
Csvtools
Csvtools von Dr. Nicola Talbot verhält sich ähnlich zu dem bereits vorgestellten Paket Textmerg. Die Daten befinden sich in einer Textdatei im CSV-Format. Jede Zeile darin entspricht einem Datensatz, ein Komma trennt jeweils die einzelnen Felder eines Datensatzes voneinander.
TIPP
Üblicherweise fungiert in CSV-Dateien ein Komma als Trennzeichen. Mit dem Kommando \setcsvseparator{Trennzeichen} legen Sie bei Bedarf ein anderes Symbol fest. Tritt das Trennzeichen in einem Eintrag auf, schreiben Sie den Inhalt des Feldes in Anführungszeichen.
Listing 4 demonstriert am Beispiel einer Einladung den Einsatz des Pakets Csvtools. In der Präambel laden Sie nach der Dokumentenklasse und den Spracheinstellungen das Paket Csvtools (Zeile 5). Mit dem Kommando in Zeile 10 öffnen Sie zunächst die in Klammern angegebene CSV-Datei. Alle nachfolgenden Kommandos zwischen der nächsten öffnenden und der passenden schließenden Klammer (Zeile 34) kommen bei jedem Datensatz zum Tragen.
Die Variablen in den Zeilen 18 und 19 leiten sich von der ersten Zeile in der CSV-Datei ab. Das Kommando aus Zeile 10 interpretiert diese Einträge als Überschriften der Felder oder Spalten. Deren Namen richtet sich nach den Gepflogenheiten unter LaTeX: Sie enthalten also weder Umlaute noch Leer- oder Sonderzeichen.
Listing 4
\documentclass[10pt]{article}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{csvtools}
\usepackage{palatino}
\setcsvseparator{;}
\begin{document}
\applyCSVfile{teilnehmer.csv}{%
\begin{center}
Rathaus der Stadt Stenkelfeld -- Rathausgasse 12f -- 00101 Stenkelfeld
\end{center}
~ \\
An Herrn \\
\insertVorname ~\insertName \\
\insertFunktion \\
~ \\
\textbf{Einladung zum Neujahrskonzert} \\
~ \\
Sehr geehrter Herr \insertName, \\
~ \\
am Sonnabend, dem 5. Januar 2013, findet um 11:00 Uhr im großen
Festsaal des Gasthofs Knollmeyer das diesjährige Neujahrskonzert
statt. Wir möchten Sie gern zu dieser herausragenden Veranstaltung
einladen und freuen uns sehr auf ihre Teilnahme. \\
~ \\
Mit freundlichen Grüßen, \\
~\\
Wilhelm Oelgemöller, Bürgermeister
33
\newpage }
\end{document}
Alternativ fügen Sie die Daten aus der gewünschten Spalte über \insertbyname{Spaltenname} ein. Verfügt die CSV-Datei in der ersten Zeile über keine Felder- oder Spaltenüberschriften, verwenden Sie zum Einlesen stattdessen das Kommando \applyCSVfile*{Datei} und referenzieren die Spalten über das Kommando \field mit der Spaltennummer als Parameter. Abbildung 2 zeigt das Ergebnis aus Listing 4, wobei das Schreiben für jeden Adressaten auf einer separaten Seite erscheint.

Abbildung 2: Die Daten für die einzelnen Adressaten stammen bei diesem Anschreiben aus einer separaten CSV-Datei.
Das LaTeX-Paket bietet noch wesentlich mehr Möglichkeiten, wie etwa die vereinfachte Ausgabe in Tabellen. Die Dokumentation zu Csvtools liegt zwar nur auf Englisch vor, umfasst aber erfreulich viele Beispiele. Der Autor von Cvstools hat auch das Datatool-Paket [6] entwickelt, das in Teilen auf den Csvtools aufbaut und das Erstellen von Torten- und Balkendiagrammen vereinfacht.
Bestimmte Datensätze auslesen
Sowohl Textmerg als auch Csvtools verarbeiten alle Datensätze auf einmal. Benötigen Sie aus den Datensätzen nur eine Teilmenge, etwa für einen bestimmten Anlass, gilt es die Liste zu modifizieren. Kommt das nicht infrage oder gestaltet sich zu aufwendig bleibt nur die Möglichkeit, LaTeX trickreich unter die Arme zu greifen.
Dazu erweitern Sie die Datensätze um ein zusätzliches Feld mit der Nummer des Datensatzes. Darüber lassen sich die Datensätze dann eindeutig referenzieren. Im Falle von Textmerg sieht ein erweiterter Datensatz wie in Listing 5 gezeigt aus.
Listing 5
1 Friedhelm Pötter Leiter der Jürgen-Koppelin-Bildungsstätte
Als nächstes passen Sie die Definition der Felder im LaTeX-Dokument an und ergänzen diese um ein weiteres Feld – hier \Nr genannt:
:\Fields{\Nr\Vorname\Name\Funktion}
Verwenden Sie hingegen Csvtools, genügt es, am Anfang jeder Zeile zu jedem Datensatz eine neue Spalte mit einer Nummer hinzufügen:
:1, Friedhelm, Pötter, Leiter der Jürgen-Koppelin-Bildungsstätte
Zur Auswahl eines spezifischen Datensatzes kommen die zusätzliche Variable \datensatznummer und das LaTeX-Paket Ifthen [7] ins Spiel. Über Erstere steuern Sie die Auswahl des Datensatzes – wie sie zustande kommt, erfahren Sie weiter unten. Die Befehle zum Vergleichen stellt das Paket Ifthen bereit. Dieses laden Sie in der Präambel des Dokuments über das Kommando \usepackage{ifthen}.
Listing 6 beinhaltet den erweiterten Programmcode am Beispiel für Textmerg (die Änderungen für Csvtools sehen ganz ähnlich aus). Zeile 3 prüft, ob die Variable \datensatznummer definiert ist – falls ja, durchläuft die Software den nachfolgenden Block (Zeile 4 bis 8). Zeile 9 enthält den Alternativ-Zweig, der hier leer bleibt. Zeile 10 schließt den Block ab.
In Zeile 4 erfolgt der Vergleich zwischen der Nummer des Datensatzes und dem Feld \Nr aus dem aktuell gelesenen Datensatz. Die Befehlsfolge \ifthenelse{\equal{...}} überprüft beide Werte auf Gleichheit. Liegt diese vor, kommen die Zeilen 5 bis 7 zum Zug.
Listing 6
...
\Merge{empfaengerliste}{%
\ifdefined\datensatznummer
\ifthenelse{\equal{\datensatznummer}{\Nr}}{%
An
\Vorname \Name \\
\Funktion \\
}{}
\else
\fi
}
...
Umsetzen in Pdflatex
Mit diesen Schritten wäre das Verarbeiten durch LaTeX ohne Hilfsmittel soweit komplett. Offen blieb bislang der Aufruf von Pdflatex mit den korrekten Parametern. Das erfordert einen Kniff, wie das folgende Beispiel zeigt:
$ pdflatex "\def \datensatznummer{2} \input{Datei.tex}"
Pdflatex akzeptiert beim Aufruf als Parameter entweder eine LaTeX-Datei oder eine Folge von einzelnen LaTeX-Kommandos. Hier nutzen Sie Letzteres und verwenden das Kommando \def, gefolgt von \input. Der Befehl \def legt eine neue Variable an – hier heißt sie datensatznummer – mit dem Wert 2. Das Kommando \input liest den Inhalt der Datei ein, die Sie als Parameter in den Klammern spezifizieren.
Mit diesem Aufruf erzeugen Sie ein valides LaTeX-Dokument. Pdflatex erkennt anhand der Variablen \datensatznummer, welchen Datensatz es auszugeben gilt. Möchten Sie einen anderen Datensatz verarbeiten, ändern Sie den Wert der Variable im Aufruf von Pdflatex entsprechend. Existiert der Datensatz mit der fraglichen Nummer nicht, erzeugt die Software ein leeres Dokument.
Aus Gründen der Flexibilität beinhalten viele Schleifen ein Kommando für einen expliziten Abbruch, wie break bei Python. Das kommt zum Einsatz, sobald das Programm eine bestimmte Bedingung erreicht. LaTeX bietet so etwas nicht, daher durchläuft das Programm bei dem Aufruf von Textmerge oder Csvtools stets alle Datensätze.
Den Namen der Ausgabedatei leitet Pdflatex vom Namen der Eingabedatei ab. Als Ergebnis des obigen Aufrufs entsteht Datei.pdf im aktuellen Verzeichnis. Mit der zusätzlichen Option -jobname Name definieren Sie den Namen der Ausgabedatei und erzeugen eine entsprechend benannte PDF-Datei Name.pdf. Das Suffix .pdf fügt die Software automatisch hinzu.
Diesen Kniff nutzen Sie aus, um ausgewählte Datensätze zu verarbeiten und die Ausgabe jeweils in ein separates PDF-Dokument zu speichern. Mögliche Einsatzbereiche wären etwa ein Dankschreiben an ausgewählte Kunden oder eine schicke Einladung zu einer Veranstaltung.
Um die Kommandos nicht ständig wieder neu eingeben zu müssen, speichern Sie das Ganze am besten als handliches Shell-Skript (Listing 7). Es akzeptiert eine beliebige Anzahl von Nummern als Parameter und ermöglicht daher volle Flexibilität bei der Auswahl.
Listing 7
#!/bin/bash
if [ "$#" == "0" ]; then
echo "Aufruf: skript.sh kdnr1 kdnr2 ... kdnrN"
exit 1
fi
while (( "$#" )); do
datensatznummer=$1
pdflatex -jobname "einladung-$datensatznummer" "\def \datensatznummer{$datensatznummer} \input{vorlage.tex}"
shift
done
In Zeile 3 prüft das Skript zunächst, ob Sie beim Aufruf mindestens einen Parameter angegeben haben. Falls nicht, beendet es sich mit dem Fehlercode 1 (Zeile 5). In den Zeilen 8 bis 11 arbeitet eine While-Schleife alle Parameter der Reihe nach ab.
Als Datensatznummer, die das Skript verarbeitet, fungiert der erste Parameter des Skripts, der in der Variable $1 liegt (Zeile 9). In Zeile 10 erfolgt der Aufruf von Pdflatex, wobei die Namen aller erzeugten PDF-Dateien mit dem Präfix einladung- beginnen, gefolgt von der Nummer des Datensatzes und mit dem automatisch ergänzten Suffix .pdf.
Als Grundlage für das Dokument dient eine Datei vorlage.tex aus dem zweiten Parameter. Das Kommando shift in Zeile 11 verändert die Inhalte der Parameter $1 bis $9. Es kopiert den Inhalt von $2 nach $1, von $3 nach $2 und so weiter. Das schafft die Voraussetzungen für die Zeilen 8 und 9.
Weitere Details zu shift erklärt Jürgen Wolf ausführlich in seinem Buch zur Shell-Programmierung [8].
Aus der SQL-Datenbank
Bereits 2006 präsentierte Hans-Georg Eßer der Öffentlichkeit sein Projekt LaTeXDB. Es kombiniert LaTeX mit der Structured Query Language (SQL) und eröffnet Ihnen damit die Möglichkeit, direkt aus einem LaTeX-Dokument heraus auf eine SQL-Datenbank wie MySQL oder PostgreSQL zuzugreifen.
Streng genommen handelt es sich bei LaTeXDB nicht um ein Paket für LaTeX im klassischen Sinn, sondern eine Kombination aus LaTeX und der Programmiersprache Python. Das Skript übernimmt das Abfragen der Datenbank und ersetzt die betreffenden Stellen im Dokument durch die Felder aus dem Ergebnis.
Mit dem Auszug in Listing 8 greifen Sie auf eine lokale MySQL-Datenbank zu und lesen die Inhalte der Tabelle Benutzer aus. Das Übersetzen erfolgt mit dem Aufruf pdflatexdb Datei.tex> und erzeugt in einem mehrstufigen Prozess das entsprechende PDF-Dokument.
Listing 8
...
\texdbconnection{MySQL, localhost, user, passwd, datenbank}
\texdbdef{##benutzer}{select vorname,name,funktion from Benutzer}{##Vorname,##Name, ##Funktion}
\texdbfor{##benutzer}{
\Vorname ~\Name: \Funktion
}
...
Das aktuelle Paket LaTeXDB stammt aus dem Jahr 2006 und liegt im CTAN. Ein DEB- oder RPM-Paket gibt es nicht, eine Weiterentwicklung ist bislang nicht vorgesehen. Das Paket funktioniert laut Entwickler zuverlässig und erfüllt sein gestecktes Ziel vollständig. Eine ausführliche Beschreibung bietet ein Artikel aus älteren Ausgabe von LinuxUser [9]. Aus LaTeXDB entstanden durch Robin Höns mittlerweile zwei weitere Projekte – Ratexdb [10] (geschrieben in Ruby) und Nlatexdb (in .NET) [11].
Beachten Sie, dass die vollständige SQL-Anweisung und alle Zugangsdaten zur Datenbank (Rechner, Nutzername und Passwort) im Klartext im LaTeX-Dokument stehen. Das erweist sich unter Umständen als ein Sicherheitsrisiko. Ob Sie diese Schwachstelle akzeptieren, hängt vom Einsatzbereich ab.
Fazit
LaTeX zielt auf das Erstellen eines einzelnen Dokuments ab. Die hier vorgestellten LaTeX-Pakete bieten eine brauchbare Schnittstelle zum Verarbeiten großer Datenmengen und helfen, nicht nur Serienbriefe (Rechnungen, Einladungen, Mitteilungen), sondern auch andere Druckerzeugnisse zu erstellen, wie Tür- oder Namensschilder. Das vereinfacht beispielsweise das Organisieren einer Veranstaltung.
Als weitere Anregungen zu diesem Thema empfehlen wir Ihnen das Paket ticket von Thomas Emmel [12] sowie den Vortrag “Konferenzmanagement mit LaTeX” von Uwe Ziegenhagen [13]. Kommt es auf Geschwindigkeit und Effizienz an, lohnt es sich, die Prozesskette etwas zu optimieren.
Glossar
-
CSV-Format
-
Das CSV-Format hat sich als Austauschformat zwischen Applikationen und als einfache Datensammlung bewährt. Es setzt kaum Technologie voraus und ermöglicht bei Bedarf sogar ein Bearbeiten mit einem Texteditor.
Infos
[1] Textmerg: http://www.ctan.org/pkg/textmerg
[2] Csvtools: http://www.ctan.org/pkg/csvtools
[3] LaTeXDB: http://privat.hgesser.com/software/latexdb/
[4] CTAN: http://www.ctan.org
[5] Stenkelfeld Online: http://www.stenkelfeld.de
[6] Datatools: http://www.ctan.org/pkg/datatools
[7] Ifthen: http://www.ctan.org/pkg/ifthen
[8] Bash-Funktion Shift: Jürgen Wolf, “Shell-Programmierung”, Galileo Computing 2007, ISBN 978-3836211574, http://openbook.galileocomputing.de/shell_programmierung/shell_005_003.htm
[9] LaTeXDB: Hans-Georg Eßer, “Relationaler Textsatz”, LinuxUser 06/2006, S. 62, https://www.linux-community.de/10779
[10] Ratexdb: http://www.ctan.org/pkg/ratexdb
[11] Nlatexdb: http://sourceforge.net/projects/nlatexdb/
[12] Ticket: http://www.ctan.org/pkg/ticket
[13] Konferenzmanagement mit LaTeX: http://uweziegenhagen.de/?p=141
[] Der Autor bedankt sich bei Hans-Georg Eßer, Wolfram Eifler, Lars Lingner und Thomas Winde für deren kritische Anmerkungen und Kommentare im Vorfeld dieses Artikels.
[] Frank Hofmann (http://www.efho.de) hat Informatik an der Technischen Universität Chemnitz studiert. Derzeit arbeitet er in Berlin im Büro 2.0, einem Netzwerk von Open-Source-Experten. Er zählt zu den Gründern des Schulungsunternehmens Wizards of FOSS. Seit 2008 koordiniert er das Regionaltreffen der Linux-User-Groups aus der Region Berlin-Brandenburg.





