Seitenübergreifende Tabellen (longtable)

Eine Tabelle in der table-Umgebung wird niemals über eine Seite gebrochen, gleich wie viele Zeilen sie hat – und wenn sie überläuft, beschwert sich nichts. Unter TeX Live 2024 ergab eine Tabelle mit 119 Zeilen in einem Float eine Seite statt drei; die übrigen Zeilen rutschten still unter den Blattrand. Das Paket longtable durchbricht diese Grenze. Die eigentliche Aufgabe von longtable ist aber nicht der Seitenumbruch, sondern gleiche Spaltenbreiten auf jeder Seite. Dafür schreibt es seine Messwerte in die .aux-Datei und verlangt mit der Warnung Table widths have changed. Rerun LaTeX. einen zweiten Durchlauf. Diese Seite verfolgt, was dieser zweite Lauf einbringt – gemessen im Vergleich mit supertabular, das ihn auslässt.

Warum eine Tabelle in einem Float nie umbricht

Weil table wie figure ein Float ist und LaTeX einen Float als unteilbaren Kasten behandelt, der auf eine Seite passt. Der Kasten wandert als Ganzes an den Seitenanfang oder das Seitenende, und was als Ganzes wandert, lässt sich nicht in der Mitte durchtrennen. Wie hoch das innere tabular also auch wird, es wird nie geteilt; passt es nicht, läuft es schlicht über den Papierrand hinaus. Das Unangenehme daran: eine Warnung gibt es nicht. Mit denselben 119 Datenzeilen ergab die Float-Variante eine Seite, die Variante ohne Float drei. Keine einzige Fehlermeldung. Ein Unfall, den man nur findet, wenn man das PDF bis zum Ende liest.

Eine „seitenübergreifende Tabelle“ ist mit dem Float-Mechanismus also grundsätzlich unvereinbar. Gebraucht wird ein Weg, die Tabelle in denselben Fluss wie den Haupttext zu stellen und sie TeXs eigenem Seitenumbruchalgorithmus zu übergeben, so wie einen Absatz. Das ist longtable. Geschrieben hat es David Carlisle, der Autor von array, tabularx und dcolumn; es gehört zum tools-Bundle jeder LaTeX-Installation, es ist also nichts zu installieren.

Ein longtable schreiben: was sich gegenüber tabular ändert

Fast alles funktioniert wie bei tabular. \usepackage{longtable} laden, mit \begin{longtable}{l l r} beginnen – die Spaltendeklaration ist ein obligatorisches Argument –, Spalten mit & trennen und Zeilen mit \\ beenden. Die Spaltentypen l, c, r, p{width} gelten ebenso wie \hline und \multicolumn. Nur drei Dinge sind anders. Erstens: niemals in eine table-Umgebung einpacken; das macht daraus wieder einen Float und holt das Einseitenproblem von oben zurück. Zweitens darf vor der Spaltendeklaration ein optionales Positionsargument [c], [r] oder [l] stehen. Drittens bringt longtable seine eigene Caption mit (siehe unten). Seitenumbrüche entstehen nur zwischen Zeilen oder an einem \hline, nie mitten in einer Zelle einer p-Spalte.

Position und umgebender Abstand hängen an Längen, die sich jederzeit nach \begin{document} ändern lassen. Unter TeX Live 2024 wurden folgende Vorgaben gemessen: \LTleft und \LTright sind beide 0pt plus 1fill – gleicher Druck von beiden Seiten, und genau das zentriert die Tabelle. Für linksbündigen Satz bleibt \setlength{\LTright}{0pt plus 1fill} bestehen und \setlength{\LTleft}{0pt} wird gesetzt. Der Abstand darüber und darunter sind \LTpre und \LTpost, beide standardmäßig 12pt plus 4pt minus 4pt.

Kopf und Fuß auf jeder Seite wiederholen: endhead und endfoot

Am Tabellenanfang stehen vier Marker, die jeweils erklären, auf welchen Seiten die Zeilen bis dorthin wiederholt werden. Ein Marker steht am Ende seiner Zeile anstelle des \\. Alle vier sind optional; genügt auf jeder Seite derselbe Kopf, reicht \endhead allein.

MarkerWo die vorangehenden Zeilen erscheinenTypischer Inhalt
\endfirstheadnur im Kopf der ersten Seite\caption{…} und die Spaltenüberschriften
\endheadKopf jeder Seite außer der ersten„(continued)“ und die Spaltenüberschriften
\endfootFuß jeder fortgesetzten Seite (alle außer der letzten)eine Zeile „Continued on next page“
\endlastfootganz am Ende der Tabelle, nur letzte Seitedie Abschlusslinie oder eine Anmerkung
\killnirgends – die Zeile wird nur vermesseneine Dummy-Zeile mit den breitesten Einträgen
document.tex
\documentclass{article}
\usepackage{longtable}
\begin{document}

\begin{longtable}{l l r}
  % head of the first page only
  \caption{Annual sales log}\\
  \hline
  Date & Item & Amount \\
  \hline
  \endfirsthead

  % head of every later page
  \multicolumn{3}{l}{\small (continued)}\\
  \hline
  Date & Item & Amount \\
  \hline
  \endhead

  % foot of every page that continues
  \hline
  \multicolumn{3}{r}{\small Continued on next page}\\
  \endfoot

  % foot of the last page
  \hline
  \endlastfoot

  % everything below the markers is real data
  2026-01-05 & Apple  & 380 \\
  2026-01-06 & Orange & 120 \\
  % ...rows continue; pages are broken automatically...
\end{longtable}

\end{document}

Die Reihenfolge zählt. Die vier Marker müssen in genau dieser Reihenfolge ganz oben in der Tabelle stehen, und alles darunter ist der eigentliche Inhalt, der über die Seiten fließt. Anders gesagt: Der Tabellenrumpf beginnt mit der ersten Zeile nach \endlastfoot. Wer die Reihenfolge durcheinanderbringt, findet eine gedachte Kopfzeile als erste Datenzeile wieder. \kill fällt aus dem Rahmen: Es erzeugt eine Zeile, die vermessen, aber nie gedruckt wird. Sind die Überschriften kurz und taucht erst auf Seite 100 ein sehr langer Wert auf, sorgt eine \kill-Zeile mit Maximalbreiten am Anfang für von vornherein breite Spalten.

Table widths have changed. Rerun LaTeX. – warum zwei Durchläufe

Damit die Spalten auf jeder Seite übereinstimmen. longtable setzt die Tabelle seitenweise, doch die breiteste Zelle einer Seite steht erst fest, wenn diese Seite gesetzt ist. Würde jede Seite unabhängig gesetzt, bekäme jede ihre eigenen Spaltenbreiten. Also schreibt longtable die gemessenen Breiten in die .aux-Datei und liest sie beim nächsten Lauf als eine gemeinsame Breite für alle Seiten zurück. Deshalb meldet der erste Durchlauf Folgendes:

log
Package longtable Warning: Column widths have changed
(longtable)                in table 1 on input line 24.


Package longtable Warning: Table widths have changed. Rerun LaTeX.

Was das Ignorieren der Warnung kostet, lässt sich messen. Liest man aus dem PDF einer dreiseitigen Tabelle die Position der rechten Spaltenüberschrift „Amount“ aus, so steht sie im ersten Lauf bei x = 320,41pt, während die Daten darunter bei x = 488,69pt stehen – Überschrift und Zahlen an verschiedenen Orten. Nach dem zweiten Lauf wandert die Überschrift auf x = 471,53pt und ist auf allen drei Seiten gleich. Die Ausgabe des ersten Laufs ist also eine Tabelle mit zu schmalen Spalten und nach links verrutschten Überschriften. Genau das meint „einmal kompiliert, und die Tabelle sieht falsch aus“.

In diese .aux-Datei kann man hineinsehen. So sieht der Rückstand eines dreispaltigen longtable aus. \LT@i bedeutet „das erste longtable in diesem Dokument“; das zweite heißt \LT@ii. Das zweite Argument jedes Eintrags ist die gemessene Breite einer Spalte, und der nächste Lauf verwendet genau diese Zahlen.

document.aux
\gdef \LT@i {\LT@entry
    {2}{58.6668pt}\LT@entry
    {2}{274.36153pt}\LT@entry
    {1}{47.55566pt}}

Gemessen wird nicht in einem Zug, sondern in Blöcken, deren Größe der Zähler LTchunksize festlegt (Vorgabe 200 Zeilen). Sprengt eine sehr lange Tabelle den Speicher von TeX, hilft \setcounter{LTchunksize}{10}; ein größerer Wert verringert die .aux-Umläufe und kann schneller konvergieren. In der Praxis nimmt einem latexmk diese Sorge ab – es läuft so oft, bis die Warnung verschwindet.

Captions und Nummerierung: LTcapwidth ist standardmäßig 4 Zoll

longtable ist kein Float und hat dennoch eine eigene \caption{…}. Sie erhöht den Standardzähler table, wird also automatisch als „Tabelle N“ nummeriert und erscheint in \listoftables. Weil die Caption Teil des Tabellenlayouts ist, gehört sie in den Kopfblock vor \endfirsthead, mit \\ abgeschlossen, also \caption{…}\\. Bei der Breite lauert eine Überraschung: \LTcapwidth beträgt standardmäßig 4 Zoll, also 289,08pt. Da \textwidth in article bei 345pt liegt, ist die Caption ab Werk 56pt schmaler als der Text. Für gleiche Breite genügt \setlength{\LTcapwidth}{\textwidth}.

Der Rest sind kleine Konventionen. Soll keine Nummer erscheinen, nimmt man \caption*{…} – weder Nummer noch Eintrag im Tabellenverzeichnis. Eine untergeordnete Caption wie „(continued)“ auf Folgeseiten schreibt man mit leerem optionalem Argument, \caption[]{…}, damit sie nicht doppelt gelistet wird. Und ein Querverweis \label{…} darf niemals in den wiederholten \endhead: Dieselbe Marke würde einmal pro Seite definiert. Setzen Sie ihn in \endfirsthead oder in die erste Zeile des Tabellenrumpfs.

Was mit booktabs-Linien am Seitenumbruch geschieht

\toprule, \midrule und \bottomrule funktionieren unverändert im longtable: booktabs hat mit der Ausgabe von 2000 longtable-Kompatibilität ergänzt, und booktabs.sty trägt dafür bis heute einen \ifx\longtable\undefined-Zweig. Eine Asymmetrie bleibt jedoch. longtable verdoppelt ein \hline am Umbruch automatisch, zieht also je eine Linie über und unter der Nahtstelle, während booktabs-Linien nicht verdoppelt werden. Landet eine Linie genau auf einem Seitenumbruch, rät das booktabs-Handbuch selbst zur Korrektur von Hand – meist heißt das, die störende Linie zu löschen. Praktisch löst man es durch Gestaltung: Linien gehören in \endfoot und \endhead, damit nie eine auf der Naht sitzt.

Es gibt eine Zugabe. Das Argument zum Kürzen links und rechts, das sonst allein \cmidrule gehört, wirkt auch auf \toprule, \midrule und \bottomrule – aber nur innerhalb eines longtable. \toprule(r) zieht das rechte Ende ein, \midrule(lr) beide Enden. Unter TeX Live 2024 mit gemeinsam geladenem longtable und booktabs übersetzt das fehlerfrei. Umgekehrt geht dasselbe in einem gewöhnlichen tabular nicht; der Autor von booktabs bemerkt halb im Scherz, wer unbedingt gekürzte Linien wolle, solle eben alle Tabellen zu longtables machen.

supertabular und xtab: ein Lauf, dafür springende Spalten

longtable ist nicht der einzige Weg zu seitenübergreifenden Tabellen. supertabular von Johannes Braams und Theo Jurriens sowie der Abkömmling xtab von Peter Wilson gehen einen ganz anderen Weg. Während longtable die ganze Tabelle setzt und dem Seitenumbruch von TeX überlässt, messen diese beiden den auf der Seite verbliebenen Platz und erzeugen ein neues tabular, das hineinpasst – also je Seite ein eigenständiges tabular. Sie brauchen daher keinen .aux-Umlauf und sind nach einem Durchlauf fertig.

Der Preis zeigt sich unmittelbar im Satz. Mit denselben 119 Zeilen und einem extrem langen Eintrag in Zeile 90 verhalten sich beide sehr verschieden. Unter supertabular steht die Spaltenüberschrift „Amount“ auf Seite 1 und 2 bei x = 249,16pt und auf Seite 3, die den langen Eintrag trägt, bei x = 471,53pt – beim Umblättern ändert die Tabelle ihre Breite. Dieselben Daten unter longtable setzten die Überschrift nach dem zweiten Lauf auf allen drei Seiten bei x = 471,53pt. Zweimal zu übersetzen kauft genau diese Einheitlichkeit. Auch die Syntax unterscheidet sich: supertabular deklariert Kopf und Fuß außerhalb der Umgebung als \tablefirsthead, \tablehead, \tabletail und \tablelasttail, Captions über \topcaption und \bottomcaption. xtab baut darauf auf und ergänzt etwa eine Mindestzeilenzahl, damit ein Umbruch nicht zerfranst wirkt.

Umbrechende X-Spalten, die auch Seiten überspannen: xltabular und ltxtable

longtable verwendet dieselbe Spaltendeklaration wie tabular; längerer Text landet daher in einer festen p{width}-Spalte. Für eine Spalte, die sich automatisch in die Restbreite ausdehnt, braucht man die X-Spalte von tabularx – doch die Umgebung tabularx selbst kann nicht umbrechen. Zwei Brücken schließen die Lücke. xltabular von Rolf Niepraschk und Herbert Voß ist ein longtable mit X-Spalten: \begin{xltabular}{\linewidth}{l X r} nimmt Gesamtbreite und Spaltendeklaration, und die Marker um \endfirsthead funktionieren weiterhin. Intern wird ltablex geladen, die bestehende tabularx-Umgebung bleibt aber unangetastet.

document.tex
\documentclass{article}
\usepackage{xltabular}
\begin{document}

\begin{xltabular}{\linewidth}{l X r}
  \caption{Glossary}\\
  \hline
  Term & Description & Page \\
  \hline
  \endfirsthead
  \hline
  Term & Description & Page \\
  \hline
  \endhead

  longtable  & Breaks across pages; sits in the text flow, not in a float. & 12 \\
  xltabular  & A longtable whose X column takes the leftover width.       & 34 \\
\end{xltabular}

\end{document}

Die andere Brücke ist ltxtable, ebenfalls von David Carlisle. Hier steht der Tabellenrumpf in einer eigenen Datei und wird mit \LTXtable{\textwidth}{Dateiname} geholt. Die Datei enthält ein longtable mit X-Spalten; ltxtable lässt die Breitenrechnung von tabularx einmal laufen und übergibt das Ergebnis dann an longtable. Die Dateitrennung ist lästig, verhindert aber, dass die wiederholte Expansion von tabularx mit dem .aux-Umlauf von longtable kollidiert – bei langen Tabellen deutlich stabiler. Die Wahl ist einfach: xltabular der Bequemlichkeit halber, ltxtable, wenn eine große, verwickelte Tabelle merkwürdig wird. Ein kleines Detail noch: xltabular verbraucht nur dann eine table-Nummer, wenn tatsächlich eine \caption geschrieben wird.