# Formatting table using booktabs

I am having a bit of a trouble with a table. The code for the table looks like this:

\documentclass{report}
\usepackage{booktabs}
\usepackage{array}
\newcommand*\rotbf[1]{\rotatebox{90}{\textbf{#1}}}
\newcommand{\specialcell}[2][c]{\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}

\begin{document}
\begin{table}[hbr]
\centering
\label{tbl:heatwheel_res}
\begin{tabular}{llll}
\toprule
\textbf{Parameter} & \specialcell{Exhaust\\air} & \specialcell{Exhaust and \\ outdoor air} & \specialcell{Heat wheel\\(80~\%)} \\
\midrule
Heat recovery [\%] & 89,6 \% & 89,6 \% & 77,4 \% \\
Real heat recovery [\%] & 50,5 \% & 52,1 \% & - \\
Net energy need for VH and SH & 27,7 & 27,0 & 15,8 \\
\specialcell{Delivered energy for\\DHW, VH and SH} & 31,1 & 27,6 & 45,6 \\
\bottomrule
\end{tabular}
\end{table}
\end{document}


I'm using \specialcell in order to break the line of elements that are too long. However, I want the text in the first row to be bold. When I add \textbf{} inside \specialcell, the document will not compile. Error message is: "Missing } inserted".

Do you have any suggestions? Can I make a new specialcell (\specialcell2) that is automatically bold?

Another question: How can I force the table to be a bit wider, in order to increase the space between the first column and the second column? I think column 1 and 2 are a bit too close at row 4.

Since the whole outer cell, which contains \specialcell should be bold, \bfseries can be specified in the outer cell, right before \specialcell:

... & \bfseries\specialcell{...} & ...


This can also be put into a macro \specialcellbold, see the following example:

\documentclass{report}
\usepackage{booktabs}
\usepackage{array}
\newcommand*\rotbf[1]{\rotatebox{90}{\textbf{#1}}}
\newcommand{\specialcell}[2][c]{\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}}
\newcommand{\specialcellbold}[2][c]{%
\bfseries
\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}%
}

\begin{document}
\begin{table}[hbr]
\centering
\label{tbl:heatwheel_res}
\begin{tabular}{llll}
\toprule
\textbf{Parameter} &
\specialcellbold{Exhaust\\air} &
\specialcellbold{Exhaust and\\ outdoor air} &
\specialcellbold{Heat wheel\\(80~\%)} \\
\midrule
Heat recovery [\%] & 89,6 \% & 89,6 \% & 77,4 \% \\
Real heat recovery [\%] & 50,5 \% & 52,1 \% & - \\
Net energy need for VH and SH & 27,7 & 27,0 & 15,8 \\
\specialcell{Delivered energy for\\DHW, VH and SH} & 31,1 & 27,6 & 45,6 \\
\bottomrule
\end{tabular}
\end{table}
\end{document}


The table formatted a little different:

\documentclass{report}
\usepackage{booktabs}
% \usepackage{array}% It can also be loaded explicitly, implicitly it is
\usepackage{siunitx}
% \sisetup{output-decimal-marker={,}}% OP now wants to have the default dot
\sisetup{detect-weight, mode=text}
\newcommand*\rotbf[1]{\rotatebox{90}{\textbf{#1}}}
\newcommand{\specialcell}[2][b]{\begin{tabular}[#1]{@{}c@{}}#2\end{tabular}}
\newcommand{\specialcellbold}[2][b]{%
\bfseries
\sisetup{text-rm=\bfseries}%
\begin{tabular}[#1]{@{}c@{}}#2\end{tabular}%
}
\newcommand*{\leftspecialcell}[2][b]{%
\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}%
}

\begin{document}
\begin{table}[hbr]
\centering
\label{tbl:heatwheel_res}
\begin{tabular}{l*{3}{S[table-format=2.1]}}
\toprule
\textbf{Parameter} &
{\specialcellbold{Exhaust\\air}} &
{\specialcellbold{Exhaust and\\ outdoor air}} &
{\specialcellbold{Heat wheel\\(\SI{80}{\percent})}} \\
\midrule
Heat recovery [\si{\percent}] & 89,6 & 89,6 & 77,4 \\
Real heat recovery [\si{\percent}] & 50,5 & 52,1 & {---} \\
Net energy need for VH and SH & 27,7 & 27,0 & 15,8 \\
\leftspecialcell{Delivered energy for\\
\quad DHW, VH and SH} & 31,1 & 27,6 & 45,6 \\
\bottomrule
\end{tabular}
\end{table}
\end{document}


Remarks:

• Columns 2 to 4 are centered.
• Use of package siunitx for aligning at the decimal marker and for setting the percent signs.
• The lines after the first line in a left cell is indented. and the alignment follows the bottom line instead of vertical centering.
• Use of em dash instead of the hyphen for the missing entry.
• Redundant percent signs removed.
• Changed the output decimal marker to the default dot (see comment of ROLF).
• A little crude is \siunit{text-rm=\bfseries}. Option detect-weight did not work inside an S-column.

Update

I, Svend Tveskæg, found the code not very easy to read to I cleaned it up a bit (I hope it's okay):

\documentclass{report}

\usepackage{booktabs}
\usepackage{siunitx}

\sisetup{
%  output-decimal-marker = {,},
detect-weight,
mode = text
}
\newcommand*{\specialcell}[2][b]{%
\begin{tabular}[#1]{@{}c@{}}#2\end{tabular}%
}
\newcommand*{\specialcellbold}[2][b]{%
\bfseries
\sisetup{text-rm = \bfseries}%
\begin{tabular}[#1]{@{}c@{}}#2\end{tabular}%
}
\newcommand*{\leftspecialcell}[2][b]{%
\begin{tabular}[#1]{@{}l@{}}#2\end{tabular}%
}

\begin{document}

\begin{table}[htbp]
\centering
\label{tbl:heatwheel-res}
\begin{tabular}{l *{3}{S[table-format = 2.1]}}
\toprule
\textbf{Parameter}                                    &
{\specialcellbold{Exhaust    \\ air}}                 &
{\specialcellbold{Exhaust and\\ outdoor air}}         &
{\specialcellbold{Heat wheel \\ (\SI{80}{\percent})}}       \\
\midrule
Heat recovery [\si{\percent}]         & 89,6 & 89,6 & 77,4  \\
Real heat recovery [\si{\percent}]    & 50,5 & 52,1 & {---} \\
Net energy need for VH and SH         & 27,7 & 27,0 & 15,8  \\
\leftspecialcell{Delivered energy for                       \\
\quad DHW, VH and SH}                 & 31,1 & 27,6 & 45,6  \\
\bottomrule
\end{tabular}
\end{table}

\end{document}

• @barbarabeeton The example has three lines, which start with \bfseries\specialcell. – Heiko Oberdiek Dec 13 '14 at 21:23
• Now that you have loaded the siunitx package, you should use \si{\percent} instead of \% (in three places). Also, maybe use an em dash instead of an en dash for the empty entry. – Svend Tveskæg Dec 14 '14 at 15:10
• @HeikoOberdiek Instead of \mbox{--} you can just use {--}, because siunitx will understand from the brace that a non numeric entry has been given and will center the item. Similarly for \mbox{\specialcell{...} that can just be {\specialcell{...}}. It's faster, because no expansion to find an unexpandable token is required. – egreg Dec 14 '14 at 15:15
• @SvendTveskæg Using \SI{80}{\percent} was tricky, because option detect-weight did not work inside an S-column. Also en dash fixed to em dash. *{<n>}{...} is practical here, but it has the disadvantage, that the format of a single column cannot be easily changed. Package array is loaded by siunitx, thus it does not matter much, if is is loaded explicitly. – Heiko Oberdiek Dec 14 '14 at 16:30
• @thymaro [b] and [c] are the default values for the first parameter of \specialcell that is then passed as first optional argument for \begin{tabular} with meaning vertical alignment (b = bottom, c = centered). – Heiko Oberdiek Sep 28 '17 at 17:23

Just for comparison. How to do this table in plain TeX. But it works in LaTeX (without any loaded package) too.

\def\toprule{\noalign{\medskip\hrule height .8pt\medskip}}
\def\midrule{\noalign{\medskip\hrule\medskip}}
\let\bottomrule=\toprule
\def\specialcell#1{\vcenter{\halign{\hfil##\hfil\strut\cr#1\cr}}}
\def\x{\phantom{\%}}\def\h{\hfill\null}

\halign{&\ \hfil#\unskip\ \hfil\cr
\toprule
\bf Parameter\h & \bf\specialcell{Exhaust\cr air} &
\bf\specialcell{Exhaust and\cr outdoor air} &
\bf\specialcell{Heat wheel\cr(80~\%)} \cr
\midrule
Heat recovery [\%]\h &89,6 \% & 89,6 \% & 77,4 \% \cr
Real heat recovery [\%]\h & 50,5 \% & 52,1 \% & --- \cr
Net energy need for VH and SH & 27,7 \x & 27,0 \x & 15,8 \x \cr
\specialcell{Delivered energy for\cr DHW, VH and SH\hfill}\h& 31,1 \x & 27,6 \x & 45,6 \x\cr
\bottomrule
}

\bye


• Amazing how compact the code is. I would suggest to left-align header of the first column, though. – Christian Lindig Dec 14 '14 at 19:26
• I used this code to test if can be typeseted a table that runs across columns and pages in a memoir's two column document and found that works. Naturally, does not have continuation headers. – djnavas Oct 13 '16 at 7:47

Don't reinvent the wheel: the makecell package: its \thead and \makecell commands allows for linebreaks in cells and a common formatting. It also defines \rothead and \rotcell commands if you load the rotating package. Demo:

\documentclass{report}
\usepackage{booktabs}
\usepackage{array}
\usepackage{rotating}
\usepackage{makecell}
\renewcommand\cellalign{lc}
\setcellgapes{2pt}
\makegapedcells

\begin{document}

\begin{table}[hbr]
\centering
\label{tbl:heatwheel_res}
\begin{tabular}{lccc}
\toprule
\midrule
\makecell{Heat recovery\\{}[\%]} & 89,6 & 89,6 & 77,4 \\
\makecell{Real heat recovery\\{}[\%]} & 50,5 & 52,1 & -- \\
\makecell{Net energy need for\\VH and SH} & 27,7 & 27,0 & 15,8 \\
\makecell{Delivered energy for\\DHW, VH and SH} & \rotcell{31,1 }& 27,6 & 45,6 \\
\bottomrule
\end{tabular}
\end{table}

\end{document}


• Where is \thead defined? I solves a problem that I commonly have with table headers. BTW: code and image don't seem to fit together for the last column. – Christian Lindig Dec 14 '14 at 19:25
• @Christian Lindig: there was a typo in my answer: I wrote \head instead of \thead. It's defined in the makedell package. But I don't see what doesn't correspond to my code in the image? – Bernard Dec 14 '14 at 19:43
• Sorry, Safari hadn't shown me the horizontal scroll bar and I had missed the header for the last column in the code. – Christian Lindig Dec 14 '14 at 20:06