表格放置与样式

tabular 只排版表格的 *内容*。给这张表加上 带编号的标题(caption),并把它浮动到页面上合适的位置,是浮动体 table 环境 的职责。本页讨论 tabular 外围的内容:\begin{table}[htbp] 中的放置选项、\caption\label 的写法、处理超出版心表格的缩放与旋转技巧,以及为表格添加注释的 threeparttable。表格内容本身的写法请参见“tabular 基础”。

为什么表格会“浮动”

表格和图片不能在中途分页,它们必须作为一个整体完整地放在同一页上。如果 LaTeX 试图把它们放在源码中出现的位置,而页面剩余空间又不够,就会留下难看的大空白,或让表格被别扭地截断。因此 LaTeX 把表格和图片当作 浮动体(float):将它们从正文流中分离出来,并自动 浮动 到合适的位置,通常是下一页页首。

table 环境就是使用这种机制的方式。把 tabular 放在里面,用 \caption{…} 给它一个“表 1”这样的编号标题,再用 \label{…}\ref{…} 让正文可以引用它。于是正文中只需写 按编号引用,如“如表 1 所示”,无论表格实际浮动到哪一页,引用都会自动解析为正确编号。这就是浮动体的好处。

放置选项 [htbp] 与 [H]

\begin{table} 后面的方括号中,逐个字母写出你 希望它放在哪里。可以使用四种指定符。

指定符含义
h此处,即源码位置。但不能单独使用 h;会自动补上 tHere
t正文页的顶端Top
b正文页的底端Bottom
p单独的浮动体页面(没有正文)Page

如果不指定,articlebook 的默认值都是 tbp。像 [htbp] 这样把多个字母连在一起,表示 允许的位置集合:“能 here 就 here,否则 top,再否则 bottom,最后放到浮动页”。关键是,书写顺序不会改变 LaTeX 尝试的顺序:它总是按 t→b→p 尝试,所以 [htbp][bpht] 的作用相同。可以把它看作首选位置放不下时的备用链。

[!ht] 这样在开头加感叹号 !,意思是“仅对这个浮动体,忽略内部限制,例如每页可放多少浮动体、浮动体与正文的比例,然后尝试放置”。! 并不表示“就放在这里”,它只是放宽判断标准。如果真的想固定在当前位置,请使用 float 包提供的 [H]:在 \usepackage{float} 后写 \begin{table}[H],表格就停止浮动,并 准确地 排在源码的该位置(这也可能导致页面底部留下大空白)。可以把 H 理解为“不会浮动的浮动体”。

document.tex
\usepackage{float}   % \begin{table}[H] のために

\begin{table}[htbp]
  \centering
  \caption{四半期ごとの売上}
  \label{tab:sales}
  \begin{tabular}{lrr}
    \hline
    四半期 & 売上 & 前年比 \\
    \hline
    Q1 & 1{,}200 & +5\% \\
    Q2 & 1{,}350 & +8\% \\
    \hline
  \end{tabular}
\end{table}

正文中可用 Table~\ref{tab:sales} 这样的写法引用(~ 是不可断开的空格,用来避免词和编号在换行处分开)。如果放置位置始终不如预期,“浮动体与放置”页面会更详细地说明处理方法。

标题、标签与居中

\caption{…} 给浮动体一个带编号的标题,在 article 中会自动标成“Table 1:”,在 book 中会标成“Table 1.1:”这样的 连续编号。表格和图片使用不同计数器,所以表号不会和图号混在一起。带可选参数 \caption[short]{full caption} 时,表目录 中显示短标题,正文中显示完整标题。

有两个惯例很重要。第一,推进计数器的是 \caption,所以 \label 必须放在 \caption 后面;顺序反过来,\ref 会指向前一个编号。第二是 放置惯例:长期实践中,表格标题放在表上方,图片标题放在图下方(表格先看标题再读,图片先看图再读说明)。在 LaTeX 中,把 \caption 写在 tabular 之前 就在上方,写在 之后 就在下方。

\centering 是一个声明,把浮动体中的内容 从默认左对齐切换为居中。在浮动体中,惯用的是 \centering,而不是 center 环境(\begin{center}…\end{center}):center 环境会在前后加入额外垂直空白,而 \centering 只是声明,不会增加多余空白。若要细调标题格式(字体、分隔符、宽度等),可使用 caption 包;详见“标题与子图”页面。

超出版心的表格

由于 lcr 列不会自动换行,列很多或内容很长时,表格会超出正文宽度(\textwidth)。最快的处理方法是用 graphicx\resizebox 缩小整个表格。其形式是 \resizebox{width}{height}{material},把其中一个尺寸设为 ! 时,会按另一个尺寸 保持纵横比 缩放。

latex
\resizebox{\textwidth}{!}{%
  \begin{tabular}{lrrrrr}
    \hline
    項目 & 1月 & 2月 & 3月 & 4月 & 5月 \\
    \hline
    売上 & 120 & 135 & 128 & 142 & 150 \\
    \hline
  \end{tabular}%
}

这会让表格正好等于正文宽度。但 \resizebox 会对内容进行“缩放”,因此字形粗细、横线粗细,甚至数学符号都会被统一拉伸或压缩,字号常常与周围正文不协调。把缩小视为临时补救即可;真正的修正是 调整表格本身:减少列数、用 p{width} 换行,或使用缩写。与 \resizebox 相比,adjustbox 包更容易融入周围版面,也可以写成环境,如 \begin{adjustbox}{width=\textwidth}…\end{adjustbox}

如果想完全避免缩放,也可以把整张表的 字号调小一级:在 \begin{table} 中声明 \small\footnotesize,就能使用真正较小的字体,而不会扭曲横线或数学符号的比例。若想利用横向剩余空间把表格右移而不是居中,也可以在内容前放 \hfill 等做微调。更根本的宽度控制,例如会把列伸缩到目标宽度的 tabularx,在“高级表格环境”页面中介绍。

旋转 — 横向表格

如果大表无论如何都放不进竖向页面,可以把它转成 横向(landscape),占用完整一页。rotating 包(建立在标准图形层之上)提供 sidewaystable 环境,用它代替 table 即可。表格会 旋转 90 度放在专用的一页上,标题和编号也一起旋转,并且仍会正确出现在表目录中。双面排版时,包还会自动选择旋转方向,让跨页阅读更自然。图片对应的环境是 sidewaysfigure

document.tex
\usepackage{rotating}

\begin{sidewaystable}
  \centering
  \caption{多数の列を持つ横向きの表}
  \label{tab:wide}
  \begin{tabular}{lrrrrrrrr}
    \hline
    地域 & Q1 & Q2 & Q3 & Q4 & 合計 & 前年 & 増減 & 比率 \\
    \hline
    東日本 & 120 & 135 & 128 & 142 & 525 & 500 & +25 & 105\% \\
    \hline
  \end{tabular}
\end{sidewaystable}

如果不是旋转整张表,而是想把 表的一部分按任意角度旋转,可使用同样来自 graphicx / rotating\rotatebox{angle}{material}。常见用法是把某个表头单元格用 \rotatebox{90}{long column name} 竖起来(正角度为逆时针)。注意,rotating 处理的是 盒子(box)的旋转,而盒子总是在一页内。若要制作跨多页的横向 *正文*,应使用 lscape,或旋转 PDF 页面本身的 pdflscape,而不是 rotating

threeparttable — 带注释的表格

有时需要给表格单元格添加脚注。但在 tabular 中使用 \footnote 往往会出问题:注释跳到页脚,或者根本不输出。threeparttable 包解决了这一点。顾名思义,它把表格视为 三部分:标题(caption)、主体(tabular)和注释(tablenotes,并把 注释按表格宽度排在表格正下方

用法是在 threeparttable 环境中依次放置 \captiontabulartablenotes 环境。注释的对应关系是 手动 的:在单元格中放 \tnote{a} 这样的标记,并在 tablenotes 中用同样的符号写 \item[a] …(作者有意保留手动方式,因为一个注释常被多个单元格引用)。threeparttable 本身不是浮动体,如果需要编号和放置控制,要把整体包在 table 中。

document.tex
\usepackage{threeparttable}

\begin{table}[htbp]
  \centering
  \begin{threeparttable}
    \caption{品種ごとの収量}
    \label{tab:yield}
    \begin{tabular}{lrr}
      \hline
      品種 & 収量\tnote{a} & 価格\tnote{b} \\
      \hline
      コシヒカリ & 540 & 380 \\
      あきたこまち & 520 & 360 \\
      \hline
    \end{tabular}
    \begin{tablenotes}
      \footnotesize
      \item[a] 単位は 10a あたりの kg。
      \item[b] 1kg あたりの卸売価格(円)。
    \end{tablenotes}
  \end{threeparttable}
\end{table}

在这个例子中,外层 table 负责编号和放置,threeparttable 则把标题、主体和注释三部分绑定在一起。表头单元格中的 \tnote{a}\tnote{b} 会显示为小的上标标记,表格下方对应的 ab 注释会 按与表格相同的宽度 对齐。tablenotes 环境有格式选项,用法如下。

选项效果
para多条注释不换行,连续排成一个段落注释连续排列
flushleft去掉注释的悬挂缩进无悬挂缩进
online\item 标记按正常字号输出,不作上标正常字号标记
normal恢复默认格式(用于覆盖文档级选项)恢复默认值

这些选项可以像 \usepackage[para]{threeparttable} 那样应用到整个文档,也可以像 \begin{tablenotes}[flushleft] 那样按表格指定。注意,threeparttable 本身不设置标题样式;若想让标题具有合适的外观,应与 caption 包配合使用。若要给跨页表格(longtable)加注,请使用姊妹包 threeparttablex