# Multirow and rotated column headers

I want to typeset a table with rotatetd column headers (so far it works) stretching over multiple rows.

The problem seems to be that multirow does not adjust the tables row heights, thus I have to do this by hand, and I struggle with this.

Using a slightly adopted solution from Werner (https://tex.stackexchange.com/a/32687/19326), I get the rotating and can have line breaks.

I now want to calculate the height by which I have to stretch my "stretch column". The value I need to calculate is obviously the height of my rotated box, minus the heights of the rows that I am spanning.

How do I retrieve the height of a row? What is the easiest way to calculate objectheight - rowheight1 -rowheight2?

Here is the code I have so far:

\documentclass{report}
\usepackage{xparse}
\usepackage{booktabs}
\usepackage{multirow}
\usepackage{graphicx}
\usepackage{pbox}
\usepackage{rotating}
\usepackage{calc}
%\NewDocumentCommand{\rot}{O{90} O{1em} m}{\makebox[#2][l]{\rotatebox{#1}{\pbox[t]{\textwidth}{#3}}}}%
\NewDocumentCommand{\rot}{O{90} O{1em} m}{\makebox[#2][l]{\begin{turn}{#1}{\pbox[t]{\textwidth}{#3}}\end{turn}}}%
\begin{document}

\newlength{\myl}
\settowidth{\myl}{Long Long}

\the\myl

\begin{tabular}{cccc}
\toprule
& \multirow{3}{*}{\rot{Long Long\\ text}}& & \\[\the\myl] %column which I want to stretch
Sample & & \multicolumn{2}{c}{Group} \\
\rot{a} & & A & B \\
\midrule
data & data & data & data \\
\bottomrule
\end{tabular}

\widthof{test}
\end{document}


Note: I would like to use \widthof{test} since this appears easier to me than the length fiddling, however the \widthof{test} command actually typesets test in my case.

I looked at Text in rotated multirow cell crosses table border (Basically where I got the idea to adjust the row height from, however I am not sure that my rowheight will always be \normalbaselineskip) and How to rotate text in multirow table? which does not help since it is concerned about the positioning of the rotated text rather than stretching the group of rows to accomodate the text.

The makecell package has all the tools required for that. It allows for line breaks in cells, a common formatting of column heads, and multiline rotated heads. Here are threevariants of what can be done very simply:

\documentclass{report}
\usepackage{booktabs}
\usepackage{graphicx}
\usepackage{rotating, multirow}
\usepackage{makecell}

\begin{document}

\begin{tabular}[t]{cccc}
\toprule
\turnbox{90}{a} & & A & B \\
\midrule
data & data & data & data \\
\bottomrule
\end{tabular}
\begin{tabular}[t]{cccc}%
\toprule
\midrule
data & data & data & data \\
\bottomrule
\end{tabular}
\vskip1cm
\begin{tabular}[t]{cccc}%
\toprule
\midrule
data & data & data & data \\
\bottomrule
\end{tabular}
\end{document}


• I like the package but unfortunatly \multirowhead and \rothead do not seem to work together. – ted Apr 11 '15 at 22:50
• You don't need \multirowhead. Or do I miss something? Btw, the command is \multirowthead. The precise syntax should be: \multirowthead{n}{\rothead{…}}. I have no problem to compile it. – Bernard Apr 11 '15 at 23:11
• I would like Long long text, to be aligned to the \\midrule (i.e. starting in the row with a A B and going up). Basically like in your second example, but starting from the row below. If I have multiple rotated rows I would like them bottom aligned ('left aligned before rotation') – ted Apr 11 '15 at 23:14
• @ted: I hope my updated answer satisfies your requirements. I added a third variant. – Bernard Apr 11 '15 at 23:57
• thank you for the update, the second solution (top right), is what I am going for. I do not quite understand why you have -4 for rows, there is only one row before, so I end up with -2, also where do you get \\[5ex] and \\addlinespace[6.5ex] from. While I can see that they are needed to make it work, I would like to understand the reasons behind these numbers. – ted Apr 15 '15 at 12:25

\settototalheight{\myl}{\hbox{%
\begin{tabular}{cccc}
\\
Sample & & \multicolumn{2}{c}{Group} \\
\rot{a} & & A & B \\
\end{tabular}}}

\the\myl

\settototalheight{\myl}{\hbox{%
\begin{tabular}{cccc}
Sample & & \multicolumn{2}{c}{Group} \\
\rot{a} & & A & B \\
\end{tabular}}}

\the\myl


So I think you need to use \\[\dimexpr\myl-3em\relax]

I worked from @Bernards answer. However, as noted one has to guess the right value for multirow and vertical alignment in multirow is difficult. (ALl answers I found are along the lines do not use multirow and work around this way.

rant Seems like high time for a better multirow implementation. However, I do not know the mechanisms in table, so I am not sure if it is possible. /rant

I worked arround this using tikz. I mark the coordinate and add the text later. This way the text does not stretch the row it is in, therefore I have to take care of the stretching myself. However, as the example shows, I do not want to stretch the column with the text, so that is as intended.

Now finally the code:

\documentclass{report}
\usepackage{booktabs}
\usepackage{pbox}
\usepackage{rotating}
\usepackage{tikz}
\usepackage{xparse}

\NewDocumentCommand{\rot}{O{90} O{1em} m}{\makebox[#2][l]{%
\rotatebox{#1}{\pbox[t]{#2}{#3}}}%
}

\begin{document}

\begin{table*}
\centering
\begin{tabular}{llcccc}
\toprule
&&&&&\\[2.em]
\bfseries{Example} & \bfseries{Platform} & &
& \multicolumn{2}{c}{\bfseries{Peak Bandwidth}}\\
\cmidrule(l){5-6}
&
&\,\begin{tikzpicture}[remember picture, baseline=0]\coordinate (h1);\end{tikzpicture}\,
&\,\begin{tikzpicture}[remember picture, baseline=0]\coordinate (h2);\end{tikzpicture}\, & Read & Write \\
\midrule

\bottomrule
\end{tabular}

\begin{tikzpicture}[remember picture, overlay,
every node/.append style={
rotate=90, anchor=west, inner sep=0, align=left,
execute at begin node=\setlength{\baselineskip}{1.5ex}}]
\node at (h1) {Open Source};
\node at (h2) {Multi\\Row};
\end{tikzpicture}
\end{table*}
\end{document}


Note: you need to run tex twice so the positions to place the text are updated

You still need to guess the parameter for the spacer table row (or use the method from answer, but other than that it should be straight forward).