水平跨越页面的表格,无需旋转或使用横向布局

水平跨越页面的表格,无需旋转或使用横向布局

我有一张很宽的桌子,我喜欢它水平跨越各个页面。

  \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}

知道怎么做吗?有很多垂直跨越的示例,但我找不到适合我的情况的示例。而且我也不想使用横向模式。

答案1

这是一个快速解决的方案。正如@DavidCarlisle 所指出的,\widesplit来自这个答案或许是一个更好的解决方案。

\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}

得到以下 3 页 PDF: 三页,第一页为第一列,第二页为接下来的列,第三页为最后一列。

下面是mptab.sty

它可能包含大量的错误和不必要的复杂性,使用逗号代替&和括号代替\\。它不支持\hline,并且我也没有让您指定格式(例如,|无法使用垂直线)。所有这些都应该很容易添加到代码中,并且我已经包含了一些注释。对我来说唯一困难的事情是让它接受&\\语法,因为我不熟悉如何连接到 TeX 中这种低级 catcode 功能。它还用完了,\newlength而它可能可以使用\bgroup…\egroup和现有的临时维度,并且它在很多地方过度使用了 \global。

但至少对于简单的情况它是有效的。

欢迎任何改进,并且此脏代码属于公共领域(CC0、WTFPL,您选择)。\hline如果我有时间,我会尝试添加替代方案、格式规范以及混合表格和文本块的可能性(不保证!)。

\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}{%
      \global\addtolength{\mylen}{\columnsep}%
      \global\addtolength{\mylen}{\csname column\x maxwidth\endcsname}%
      \global\addtolength{\mylen}{\columnsep}%
      \ifdim\mylen>#2\relax%
        % Push to next page
        % Reset loop variables:
        \global\setlength{\mylen}{0pt}%
        % Re-add current cell width:
        \global\addtolength{\mylen}{\columnsep}%
        \global\addtolength{\mylen}{\csname column\x maxwidth\endcsname}%
        \global\addtolength{\mylen}{\columnsep}%
        % 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
      \g@addto@macro\thistableformat{@{\hspace{\the\columnsep}}l@{\hspace{\the\columnsep}}}% THE COLUMN FORMAT HERE
      % 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\g@addto@macro\noexpand\thistablepage{%
          % \noexpand\hspace{\noexpand\columnsep}%
          \expandafter\noexpand\thiscell%
          % \noexpand\hspace{\noexpand\columnsep}%
        }%
      }%
      \else%
      \edef\doit{%
        \noexpand\g@addto@macro\noexpand\thistablepage{%
          % \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%
      % Add the "\\"
      \edef\doit{%
        \noexpand\g@addto@macro\noexpand\thistablepage{%
          \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%
}%

相关内容