# Spanning a table horizontally over pages without rotation or using landscape

I have a very wide table, which I like it to span horizontally through pages.

  \documentclass[runnngheads]{book}
\usepackage{longtable}
\begin{document}
\begin{longtable}{*{25}c}
\hline
$a_1$ & $a_2$ & $a_3$ & $b_1$ & $b_2$ & $c_1$ & $c_2$ & $c_3$ & $d_1$ & $d_2$ & $i_1$ & $i_2$ & $e_1$ & $e_2$ & $h_1$ & $h_2$ &test&test 2&test 3 &test 4 & test 5 & test 6 & test 7 & test 8 & test 9\\
\hline
\end{longtable}
\end{document}


Any idea how to do it? There are plenty of examples for vertical spanning but I could not find any for my case. And I do not want to use landscape mode as well.

• Well you can rotate a wide table, it can be useful for a table like this one. Deppending of the data you need to put inside, you can use the siunitx package for format columns with numbers in a easy way. The longtablepackage is useful when you need to create a table across two or more pages. Feb 5 '16 at 8:41
• Feb 5 '16 at 10:35
• A quick but ugly solution is to put a very large minipage into a \savebox and crop it into page sized chunks. Feb 5 '16 at 14:54
• this is a duplicate of tex.stackexchange.com/questions/93808/… (but can not be voted as dup due to the bounty) Jun 3 '16 at 0:31
• Did you try @JohnKormylo 's suggestion? If you don't want to turn it and you don't want to use landscape and neither the minipage nor the \somecolumns trick appeal, then I think you need to consider a format other than LaTeX and maybe re-engineering TeX's output routine. So good luck with that ;). You are asking for something which cannot be done automatically and elegantly in current LaTeX. You either change your desiderata or you have to accept one of the ingenious hacks put forward. Boxes, coffins, hidden columns, rotate the table, use landscape, one of David's tricks ....
– cfr
Jun 3 '16 at 0:31

Here's a quickly hacked-up solution. As noted by @DavidCarlisle, the \widesplit command from this answer is probably a better solution.

\documentclass[draft,runnngheads]{book}
\usepackage{mptab}
\begin{document}
\mptab{\the\columnsep}{\textwidth}{
{$a_1$, $a_2$, $a_3$, $b_1$,                    $b_2$, $c_1$, $c_2$, $c_3$, $d_1$, $d_2$, $i_1$, $i_2$, $e_1$, $e_2$, $h_1$, $h_2$, test,  test22, test33, test 4, test 5, test 6, test 7, test 8, test 9},
{$x_1$, $x_2$, $x_3$, $y_1$,                    $y_2$, $z_1$, $z_2$, $z_3$, $t_1$, $t_2$, $w_1$, $w_2$, $f_1$, $f_2$, $g_1$, $g_2$, hello, world,  bye,    bye,    lots,   of,     data,   beep,   boop},
{$x_1$, $x_2$, $x_3$, $y_1$,                    $y_2$, $z_1$, $z_2$, $z_3$, $t_1$, $t_2$, $w_1$, $w_2$, $f_1$, $f_2$, $g_1$, $g_2$, hello, world,  bye,    bye,    lots,   of,     data,   beep,   boop},
{1,     2,     3,    a rather very long cell,  5,     6,     7,     8,     9,     10,    11,    12,    13,    14,    15,    16,    17,    18,     19,     20,     21,     22,     23,     24,     25},
}
\end{document}


Which gives the following 3-pages PDF:

And here's mptab.sty:

It likely contains a nutritive amount of bugs and needless complexity, uses a comma instead of & and braces instead of \\. It does not support \hline, and I haven't made it so that you can specify the format (e.g. vertical lines with | are not possible). All these should be rather simple to add to the code, and I've included some amount of comments. The only hard thing for me would be to make it accept the & and \\ syntax, as I'm not familiar with hooking up into such low-level catcode-ridden features of TeX. It also uses up a \newlength when it probably could get away with using \bgroup…\egroup and an existing temporary dimension, and it overuses \global in a lot of places.

But it works, for simple cases at least.

Any improvement is welcome, and this dirty code is in the public domain (CC0, WTFPL, you choose). I'll try to add an alternative to \hline, format specification, and the possibility to mix chunks of the table and text, if I find the time (no promises!).

\usepackage{tikz}
\newlength{\mylen}
%
\newif\iffirstcolumn%
\newif\iffirstline%
\xdef\i{0}% Initialize column counter before first iteration.
\def\mptab#1#2#3{%
\bgroup%
\setlength\columnsep{#1}%
% row counter:
\xdef\j{0}%
% Loop over lines:
\global\firstlinetrue%
\foreach \y in {#3}{%
% Increment row counter
\xdef\oldj{\j}%
\pgfmathtruncatemacro{\j}{\j+1}%
\xdef\j{\j}%
% Column counter:
\xdef\oldi{\i}%
\xdef\i{0}%
\foreach \x in \y{%
% Increment column counter:
\pgfmathtruncatemacro{\i}{\i+1}%
\xdef\i{\i}%
% Compute width of current column
\settowidth{\mylen}{\x}%
\iffirstline%
\expandafter\xdef\csname column\i maxwidth\endcsname{\the\mylen}%
\else%
% Make an alias for the currently computed column max width, for convenient access:
\expandafter\let\expandafter\currentcolumnmaxwidth\csname column\i maxwidth\endcsname%
% Compare this cell's width:
\ifdim\mylen>\currentcolumnmaxwidth\relax%
% And update the column's max width when the current cell is wider:
\expandafter\xdef\csname column\i maxwidth\endcsname{\the\mylen}%
\fi%
\fi%
% Remember the contents of this cell:
\global\expandafter\let\csname cell\i x\j\endcsname\x%
}%
\global\firstlinefalse%
}
%
% Remember last column number:
% For some reason, the foreach loop from tikz gives the line with an extra
% pair of braces (which breaks the inner loop, as it sees only one value)
% when there's no trailing comma after the last line, but gives an empty
% line when there is a trailing comma. We detect this idiosyncrasy here and
% revert the last column number and last line:
\ifnum\i=0\relax%
\xdef\lastcolumn{\oldi}%
\xdef\lastline{\oldj}%
\else%
% We still keep the "reasonnable" behaviour here, just in case.
\xdef\lastcolumn{\i}%
\xdef\lastline{\j}%
\fi%
% \message{Last line: \lastline, Last column: \lastcolumn}%
%
%
% Initialization for the loop which aggregates all cells per page:
\expandafter\xdef\csname tablepage1\endcsname{}%
\expandafter\xdef\csname tableformat1\endcsname{}%
\global\firstlinetrue%
% Counter for the last page:
\xdef\maxtablepage{1}%
%
% Loop over lines, aggregating each cell in its page.
\foreach \y in {1,...,\lastline}{%
\global\setlength{\mylen}{0pt}%
\xdef\curtablepage{1}
\global\firstcolumntrue%
% Loop over the columns, aggregating each cell in its page.
\foreach \x in {1,...,\lastcolumn}{%
\ifdim\mylen>#2\relax%
% Push to next page
% Reset loop variables:
\global\setlength{\mylen}{0pt}%
% Bump table page number:
\pgfmathtruncatemacro{\curtablepage}{\curtablepage+1}%
\xdef\curtablepage{\curtablepage}
% Initialize new empty page and format:
\iffirstline
\expandafter\xdef\csname tablepage\curtablepage\endcsname{}%
\expandafter\xdef\csname tableformat\curtablepage\endcsname{}%
% Bump the counter for the last page
\xdef\maxtablepage{\curtablepage}%
\fi
% We're back on the first column:
\global\firstcolumntrue%
\fi%
% Still fits on this page (or we just created a brand new page):
% Create convenient aliases for the current page, format and cell:
\expandafter\let\expandafter\thiscell\csname cell\x x\y\endcsname%
\expandafter\let\expandafter\thistablepage\csname tablepage\curtablepage\endcsname%
\expandafter\let\expandafter\thistableformat\csname tableformat\curtablepage\endcsname%
% If we're on the first line, add a new column to the format
% Write back to \csname tableformat\curtablepage\endcsname:
\global\expandafter\let\csname tableformat\curtablepage\endcsname\thistableformat%
%
% The \expandafter and \noexpand tricks
% are from https://tex.stackexchange.com/a/60976/5699
% and from https://tex.stackexchange.com/a/67368/5699
\iffirstcolumn%
\global\firstcolumnfalse%
\edef\doit{%
% \noexpand\hspace{\noexpand\columnsep}%
\expandafter\noexpand\thiscell%
% \noexpand\hspace{\noexpand\columnsep}%
}%
}%
\else%
\edef\doit{%
% \noexpand\hspace{\noexpand\columnsep}%
& \expandafter\noexpand\thiscell%
% \noexpand\hspace{\noexpand\columnsep}%
}%
}%
\fi%
\doit%
% Write back to \csname tablepage\curtablepage\endcsname:
\global\expandafter\let\csname tablepage\curtablepage\endcsname\thistablepage%
}%
%Add a \\ at the end of the line on each page:
\foreach \curtablepage in {1,...,\maxtablepage}{%
% Make an alias
\expandafter\let\expandafter\thistablepage\csname tablepage\curtablepage\endcsname%
\edef\doit{%
\noexpand\\%
}%
}%
\doit%
% Write back to \csname tablepage\curtablepage\endcsname:
\global\expandafter\let\csname tablepage\curtablepage\endcsname\thistablepage%
}
%Finished handling the line:
\global\firstlinefalse
}%
%
%
\foreach \i in {1,...,\curtablepage}{%
\noindent\begin{tabular}{\csname tableformat\i\endcsname|}%
\csname tablepage\i\endcsname%
\end{tabular}%
\clearpage%
}%
%
\egroup%
}%