LaTeX kennt kein echtes „Zellen verbinden“. Ein Blick in latex.ltx zeigt: Der horizontale Befehl \multicolumn beginnt mit \multispan, also mit TeX’ Primitiv \omit – einer Anweisung, die Spaltenvorlage dieser Zelle wegzuwerfen. Nichts wird zusammengeklebt; das vorgegebene Muster wird ignoriert und die Breite selbst genommen. Der vertikale Befehl \multirow geht noch weiter: Er setzt den Text schlicht in einen Kasten, der hoch genug ist, um über die darunterliegenden Zeilen zu hängen. Diese beiden Implementierungen erklären fast jeden Stolperstein dieser Seite, vom Fehler ! Misplaced \omit. bis zu Text, der über die nächste Zeile gedruckt wird. Unterwegs betrachten wir das wirklich Heikle: Linien unter einer gespannten Zelle mit \cline und \cmidrule.
Über Spalten verbinden — \multicolumn und warum es eine Zelle beginnen muss
Die Form ist das dreiargumentige \multicolumn{n}{spec}{text}: n ist die Zahl der gespannten Spalten, spec die Spaltendeklaration der einen entstehenden Zelle, text ihr Inhalt. Es gehört zu Standard-LaTeX, ein Paket ist nicht nötig. Entscheidend ist, dass spec eine verbundene Spalte beschreibt und die ursprünglichen n Deklarationen nicht erbt – deshalb steht dort genau eines von l, c oder r. Stehen zwei, wie in \multicolumn{2}{cc}{…}, bricht es mit ! Missing \endgroup inserted. und anschließend ! Extra alignment tab has been changed to \cr. ab. Umgekehrt darf spec eine vertikale Linie | oder ein @{…} enthalten und damit nur für diese verbundene Zelle Linien und Spaltenabstand überschreiben.
\multicolumn muss als Allererstes in einer Zelle stehen. Ruft man es nach etwas anderem auf, etwa X \multicolumn{1}{c}{Y} & Z, erscheint ! Misplaced \omit.. Wie eingangs erwähnt, ist \multicolumn in Wahrheit \omit, das Primitiv, das erklärt „die Vorlage dieser Zelle nicht verwenden“ – und eine solche Erklärung kann nur vor Beginn der Zelle etwas bedeuten. Deshalb kommt der Fehler unter dem Namen \omit und nicht unter \multicolumn.
\begin{tabular}{lcc}
\hline
\multicolumn{3}{c}{Sales summary} \\
\hline
Item & H1 & H2 \\
\hline
Domestic & 120 & 145 \\
Overseas & 80 & 96 \\
\hline
\end{tabular}Die erste Zeile fasst die eigentlich drei Spalten mit \multicolumn{3}{c}{Sales summary} zu einer zentrierten Zelle zusammen, die als Titel der ganzen Tabelle dient. Auch in einer verbundenen Zeile müssen die Zellen dieser Zeile insgesamt die deklarierte Spaltenzahl ergeben; hier deckt \multicolumn{3}{…} alle drei ab, ein & ist also nicht nötig. Merkenswert ist außerdem die Form mit n gleich 1. Sie spannt nichts, kann aber die Ausrichtung nur dieser Zelle überschreiben oder die vertikale Linie | an dieser Stelle entfernen. Um allein die Überschrift einer Zahlenspalte (r) zu zentrieren, schreibt man \multicolumn{1}{c}{Header}; um in einer gerahmten Tabelle die Linie für eine einzelne Zelle zu unterdrücken, lässt man | einfach aus spec weg.
Stehen in einer gerahmten Tabelle zwei \multicolumn-Zellen nebeneinander, schreibt man die vertikale Linie nur in einer von beiden. Folgt auf \multicolumn{2}{|c|}{left} ein \multicolumn{2}{|c|}{right}, werden an der Grenze zwei Linien übereinandergelegt, sodass diese eine merklich dicker wirkt als die übrigen – bei größerem \arrayrulewidth springt es sofort ins Auge. Richtig ist, beim zweiten den führenden Strich wegzulassen: \multicolumn{2}{c|}{right}. Das ist eine Nebenwirkung der schlichten Implementierung: \multicolumn zeichnet genau das Geschriebene anstelle der verworfenen Vorlage und räumt Doppelungen nicht auf.
Über Zeilen verbinden — das Paket multirow und seine Argumente
Eine über Zeilen gespannte Zelle lässt sich nicht mit einem Standardbefehl erzeugen; man lädt das Paket multirow (TeX Live 2024 liefert v2.8 vom 15. März 2021). Vergisst man es, kommt schlicht ! Undefined control sequence.. Die vollständige Form hat sechs Positionen – \multirow[vpos]{nrows}[bigstruts]{width}[vmove]{text} – von denen nur nrows, width und text Pflicht sind: die Zahl der zu spannenden Zeilen, die Zellbreite und der Inhalt. Mit * als Breite wird der Text in seiner natürlichen Breite gesetzt, weshalb \multirow{3}{*}{Label} die direkteste Form ist.
Die entscheidende Regel lautet: die Zellen darunter leer lassen. \multirow steht in der oberen Zeile, und in den folgenden Zeilen wird diese Spalte mit nichts als & übergangen. In den Worten der offiziellen Dokumentation: die übrigen Zeilen in dieser Spalte leer lassen, „otherwise the stuff created by \multirow will over-write it“. Schreibt man dort echten Inhalt, erscheint überhaupt kein Fehler – die beiden Texte werden schlicht übereinandergedruckt. nrows darf auch negativ sein: Ein positiver Wert spannt „diese Zeile und die n−1 Zeilen darunter“, ein negativer „diese Zeile und die |n|−1 Zeilen darüber“, in beiden Fällen also gleich viele Zeilen – der Unterschied liegt nur darin, ob der Befehl in der obersten oder der untersten Zeile steht. Auch Bruchwerte sind erlaubt, sodass \multirow{2.5}{*}{…} die Höhe feinjustieren kann.
\usepackage{multirow}
% ...
\begin{tabular}{|l|l|c|}
\hline
\multirow{2}{*}{Fruit} & Apple & 380 \\
& Orange & 120 \\
\hline
\multirow{2}{*}{Vegetable} & Carrot & 90 \\
& Radish & 150 \\
\hline
\end{tabular}| Argument | Rolle | Hinweise |
|---|---|---|
[vpos] | Vertikale Ausrichtung (optional, zuerst) | Vorgabe c; außerdem t / b |
nrows | Zu spannende Zeilen (Pflicht) | Positiv nach unten, negativ nach oben; Bruchwerte erlaubt |
[bigstruts] | Anzahl der gespannten bigstrut-Verwendungen (optional) | Vorgabe 0; Präfix t / b / tb für feinere Steuerung |
width | Zellbreite (Pflicht) | * natürliche Breite, = die Spaltenbreite, eine Länge ergibt eine parbox |
[vmove] | Positionsfeineinstellung (optional, vor text) | Positiv hebt, negativ senkt |
\multirowsetup | Hook, direkt vor text expandiert | Anfangs \raggedright; mit renewcommand ändern |
Übergibt man width statt * eine absolute Länge – \multirow{2}{4em}{…} –, wird der Inhalt als parbox dieser Breite gesetzt, sodass ein langes Label umbricht. In dieser Form fällt womöglich auf, dass der Text linksbündig statt im Blocksatz erscheint. Das ist kein Fehler, sondern Absicht: Der direkt vor text expandierte Hook \multirowsetup enthält anfangs \raggedright. Für zentrierten Satz schreibt man stattdessen \renewcommand{\multirowsetup}{\centering}. Und width nimmt noch einen weiteren Wert, =, mit der Bedeutung „die für diese Spalte definierte Breite verwenden“ – praktisch in einer p{}-Spalte oder einer X-Spalte von tabularx, in einer Spalte ohne definierte Breite jedoch mit merkwürdig breitem Ergebnis.
\multirow reserviert keinen Platz – wenn der Text in die nächsten Zeilen ragt
Das ist der berühmteste Unfall mit \multirow. Es lässt die Tabelle den benötigten vertikalen Raum nicht reservieren. Die Höhe des Kastens wird nur aus nrows und bigstruts geschätzt, denn die tatsächlichen Zeilenhöhen sind unbekannt. Wird der Inhalt zu einem hohen Kasten, ragt er also schlicht über die darunterliegenden Zeilen oder unten aus der Tabelle hinaus. Die offizielle Dokumentation sagt es offen und zeigt es an einer Tabelle mit Arzneimittelnebenwirkungen, in der zwei \multirow-Einträge „are too high; the first sticks out into the second entry, and the second one sticks out of the table“. Das Symptom tritt immer dann auf, wenn nrows für die Menge des Inhalts zu klein ist.
Es gibt drei Abhilfen; die ersten beiden nennt die offizielle Dokumentation. Erstens leere Zeilen ergänzen, um die Überlappung abzudecken – so viele & & \\ schreiben, wie fehlen. Das ist der sicherste Weg und verlangt nur, die Zeilen zu zählen. Zweitens die Zeilen selbst dehnen – eine Stütze ohne Breite wie \newcommand{\mystrut}{\rule[-8pt]{0pt}{20pt}} in jede Zeile setzen, um Höhe zu gewinnen. (Alternativ nimmt man \bigstrut aus dem Paket bigstrut und meldet die Anzahl in [bigstruts].) Drittens ein größeres nrows angeben, als wörtlich zutrifft, gegebenenfalls mit Bruchwert – am schnellsten, bringt aber leicht das Verhältnis zu den Linien durcheinander und bleibt daher letztes Mittel.
\usepackage{multirow}
% ...
% the label wraps to four lines but the block has only two rows,
% so raise nrows to 4 and add two empty rows to cover the overlap
\begin{tabular}{|l|c|}
\hline
\multirow{4}{4em}{A long label that wraps} & one \\
& two \\
& \\
& \\
\hline
next & row \\
\hline
\end{tabular}Dieselbe Schwäche – die Unkenntnis der Zeilenhöhen – zeigt sich auch, wenn irgendwo sonst in der Tabelle eine ungewöhnlich hohe Zeile steht. Das Beispiel der Dokumentation ist eine Tabelle, deren dritte Zeile in einer p{4cm}-Spalte umbricht, sodass \multirow{3}*{Week 38} oberhalb der optischen Mitte des Blocks landet. Sind die Zeilen nicht gleich hoch, stimmen die von \multirow geschätzte Mitte und die vom Auge gesehene nicht überein. Solche Verschiebungen korrigiert man von Hand mit einem kleinen [vmove]. Eine relative Einheit wie .1ex gibt der Korrektur eine gute Chance, eine spätere Änderung des Schriftgrads zu überstehen – auch dieser Rat stammt aus der offiziellen Dokumentation.
Wenn eine Linie auf eine gespannte Zelle trifft – \cline und \cmidrule statt \hline
Das ist die heikelste Stelle des ganzen Themas. Schreibt man \hline zwischen Zeilen, die ein \multirow spannt, wird die Linie quer durch den Text der verbundenen Zelle gezogen – das Label wirkt durchgestrichen, denn \hline legt zwischen zwei Zeilen lediglich eine \hrule über die volle Tabellenbreite und weiß nichts davon, was darüber steht. Erhöht man \arrayrulewidth, sieht man die Buchstaben deutlich von der Linie durchbohrt. Die Abhilfe ist einfach: diese Spalte von der Linie ausnehmen – mit einem Spaltenbereich, also \cline{2-3} in Standard-LaTeX oder \cmidrule{2-3} mit booktabs.
\usepackage{multirow}
% ...
% \hline here would draw straight through the word "Group";
% \cline{2-3} spares column 1
\begin{tabular}{|l|l|c|}
\hline
\multirow{2}{*}{Group} & alpha & 1 \\
\cline{2-3}
& beta & 2 \\
\hline
\end{tabular}\cline und \cmidrule nehmen beide einen Spaltenbereich, haben aber unterschiedliche Charaktere. \cline{i-j} ist \arrayrulewidth dick (Vorgabe 0,4pt) und reicht exakt von Kante zu Kante der angegebenen Spalten, sodass zwei benachbarte \cline zusammenwachsen und wie eine einzige wirken. Das \cmidrule{i-j} von booktabs ist dünner – \cmidrulewidth, Vorgabe 0,03em, bei 10pt Grundschrift rund 0,3pt – und nimmt oben und unten \aboverulesep und \belowrulesep Abstand. Praktisch noch wichtiger: Ein optionales Argument in runden Klammern kürzt die Enden. \cmidrule(lr){2-3} verkürzt links und rechts, sodass zwischen ihm und dem nächsten \cmidrule eine Lücke entsteht und beide als getrennte Linien gelesen werden – das Übliche, wenn mehrere Kopfgruppen nebeneinanderstehen.
\usepackage{booktabs}
% ...
% two \multicolumn headers, each underlined by its own trimmed rule
\begin{tabular}{lcccc}
\toprule
& \multicolumn{2}{c}{2024} & \multicolumn{2}{c}{2025} \\
\cmidrule(lr){2-3} \cmidrule(lr){4-5}
Item & Q1 & Q2 & Q1 & Q2 \\
\midrule
Apple & 1 & 2 & 3 & 4 \\
\bottomrule
\end{tabular}Das ist die übliche Arbeitsform, wenn \multicolumn und Linien zusammenkommen. \multicolumn{2}{c}{2024} erzeugt eine Überschrift über zwei Spalten, und das direkt darunterliegende \cmidrule(lr){2-3} sagt: „Diese zwei gehören zusammen.“ Lässt man das (lr) weg, wachsen die beiden Linien zusammen und die Gruppengrenze verschwindet. Sollen wirklich zwei \cmidrule über demselben Spaltenbereich übereinanderstehen, gehört \morecmidrules aus booktabs dazwischen – schlicht hintereinander geschrieben, gelten zwei als zur selben Linienzeile gehörig. In eingefärbten Tabellen kann ein \cline unter der Farbfläche verschwinden; dieses Symptom und der Ausweg über hhline stehen auf der Seite „Tabellen einfärben“.
Einen rechteckigen Block verbinden – \multirow gehört in \multicolumn
Ein rechteckiger Block, der in beide Richtungen spannt, entsteht aus der Kombination von \multirow und \multicolumn. Die Reihenfolge liegt fest: \multirow gehört in \multicolumn. Die offizielle Dokumentation führt \multicolumn{2}{c}{\multirow{3}{*}{Multi-multi}} als Beispiel an und hält fest, die umgekehrte Verschachtelung „will not work“. Merkhilfe: Das äußere \multicolumn übernimmt die waagerechte Spanne, das innere \multirow die senkrechte. Und die Regel für \multirow gilt weiter – dieselbe Position in den darunterliegenden Zeilen behält die Form des \multicolumn, bleibt aber inhaltlich leer.
\usepackage{multirow}
% ...
\begin{tabular}{|l|l|c|}
\hline
\multicolumn{2}{|c|}{\multirow{2}{*}{Region and class}} & Count \\
\multicolumn{2}{|c|}{} & \\
\hline
East & Kanto & 12 \\
\cline{1-3}
West & Kansai & 9 \\
\hline
\end{tabular}Zeilenumbruch in einer Zelle ist kein Verbinden – makecell
Eine Unterscheidung lohnt sich hier. Eine einzelne Zelle über mehrere Zeilen umbrechen zu wollen, ist kein Verbinden. Da l-, c- und r-Spalten nicht umbrechen, liegt es nahe, ein \\ direkt in die Zelle zu schreiben – doch das zerlegt die Tabelle stillschweigend, ohne Fehler: Bei A & B\\C \\ liest TeX das \\ als Zeilenende und setzt C als erste Zelle der nächsten Zeile. Gerade weil kein Fehler erscheint, ist dieser Fall der lästigere. Soll nur eine kurze Zeichenkette an gewünschter Stelle umbrechen, ist \makecell{…} aus dem Paket makecell das einfachste Werkzeug.
\makecell{line1\\line2} setzt seinen Inhalt als kleines einspaltiges tabular, und genau deshalb lässt sich \\ dort als erzwungener Zeilenumbruch verwenden. Ein optionales Argument legt die Ausrichtung fest – \makecell[l]{…} linksbündig, \makecell[t]{…} oben –, wobei je ein Buchstabe für vertikale und horizontale Ausrichtung übergeben wird; Vorgabe ist beides zentriert. Für Spaltenköpfe gibt es außerdem \thead{…} mit gemeinsamer Schrift und Abständen. Soll langer Inhalt automatisch auf eine Breite umbrechen, ist eine p{width}-Spalte der richtige Weg, für vertikale Zentrierung m{width} aus array, nicht \makecell.
\usepackage{makecell}
% ...
\begin{tabular}{lc}
\hline
\thead{Item} & \thead{Year on year\\(\%)} \\
\hline
Revenue & \makecell[r]{+8.2\\(record high)} \\
\hline
\end{tabular}Welches Werkzeug wann
Die Wahl ist einfach: Spalten spannt \multicolumn, Zeilen spannt \multirow, für ein Rechteck nimmt man beide (mit \multirow innen), und \makecell nur für Zeilenumbrüche innerhalb einer Zelle. Soll langer Text auf eine Breite umbrechen, ist keines davon die Antwort – das ist Sache einer p{width}-Spalte. Und wer eine Tabelle mit Verbindungen geschrieben hat, sollte stets ins PDF schauen und drei Dinge prüfen: ob eine Zelle unter einem \multirow leer zu lassen vergessen wurde (überdruckter Text?), ob der \multirow-Kasten unten aus dem Block ragt (nrows erhöhen oder eine leere Zeile ergänzen) und ob eine Linie durch eine verbundene Zelle schneidet (\hline durch \cline oder \cmidrule ersetzen). Diese drei decken fast alle real auftretenden Pannen ab.