在 LaTeX 中排版复杂表格是一个繁杂的问题,尽管 LaTeX 内核提供了一些简单的排版表格的命令和环境,但是复杂的、定制化的表格还需其它宏包来提供支持,使用哪些宏包、这些宏包如何使用对 LaTeX 新用户来说是一个不小的难点。
本系列将介绍排版表格所需的各种宏包,尽可能地涵盖排版表格所需的各类宏包,过时的宏包和专用于排版数学公式的宏包不会在本系列中给出。
LaTeX 中有不少宏包用以排版表格,例如:
array,重新实现了 LaTeX 内核的表格环境,提供了更多的列格式,大部分表格宏包都依赖它
booktabs,提供更多的表格线命令
cellprops,提供css 形式的表格样式输入方式
cellspace,使得数学模式下拥有更好的间距
colortbl,提供彩色表格功能
diagbox,提供斜线表头功能
fcolumn,提供排版金融数据的列格式
longfigure,提供 longfigure 环境,在表格中插入图片时,表格可断页
longtable,提供 longtable 环境,表格可断页
ltxtable,使得 longtable 可以使用 tabularx 的功能
makecell,提供在表格中输入多行文字的、表头特殊排版等功能
multirow,提供行合并功能及相关功能
spreadtab,提供的同名环境能够像 Excel 电子表格那样来引用和计算行、列、格子(cell)
tablefootnote,提供表格中插入脚注的功能
tabularx,提供自动计算列宽的表格环境
tabularew,提供同名环境,优化多列输入时的对齐问题
tabularht,提供固定高度的表格环境
threeparttable,提供的同名环境支持输入表格内注
threeparttablx,提供的 ThreePartTable 环境使得 longtable 也能使用 threeparttable 的特性,也为表格内注增加了引用功能
topiclongtable,提供合并同一列中紧邻的相同项的功能
vcell,提供额外的命令实现垂直对齐
siunitx 宏包还提供了表格中对齐小数点的列格式
tabu 宏包整合了一些宏包的功能,提供了 tabu 和 longtabu 环境来输入表格和长表格,但是以及很久未更新了,一般不推荐使用
tabularray** **宏包提供了新的表格环境,能够很方便的输入表格,使用该宏包时基本不再需要使用上述宏包,但是速度相对较慢
numerica 宏集还有 numerica-tables 宏包来排版其数学计算结果的命令
此外,还有 mdwtab、mdwtools、supertabular 、tablestyle、xtab等宏包提供类似的功能。
注意:这当中的某些宏包加载有先后顺序,详情请参考宏包文档,另外本系列也会有相应说明。宏包名称加粗代表较为常用的宏包。CTAN: Table 中给出了用于排版表格的完整的宏包列表。
本文将介绍 LaTeX 内核中定义的几个环境以及 array 宏包提供的样式修改命令。
样式说明:形如 <para> 一般表示一个变量,{<para>} 一般表示该变量是必须的(mandatory),若该变量的值有多个记号应该使用一对 { } 括号括起来;[<para>] 一般表示该变量是可选的(optional),如若需要给出该变量,则必须用一对 [ ] 括起来。
tabbing 环境
tabbing 环境是一个很基础的表格环境,一般不会使用它来排版复杂表格。tabbing表格能够自动分页,但是不能使用 \newpage 等命令强制换页,也不能嵌套使用,不能自动换行,不能使用表格线。可以用于制作符号表。
\=:列宽命令,表示两列之间以此为界,第一行的各列必须用其确定列宽度,一列的宽度是由其第一行数据的自然宽度加所设水平空白宽度;该命令还可用在其它行来设置新的列
\\:换行命令。最后一行不要使用此命令(否则将留下一行空白)。可采用形如 \\[5pt] 的方法加宽与下一行的距离
\>:分列命令,用于分隔两列数据
\ :右移命令,表示将其后各行数据向右移动一列
\-:左移命令,表示将其后各行数据向左移动一列,相当于取消之前设置的一个 \ 的作用
\<:用于一行之首,表示该行数据向左移动一列,相当于取消之前设置的一个 在该行的作用
“`:可用于一行中最后一列数据之前的任何位置,它可将该行最后一列数据移至版心右侧边
\’:该命令可以插在某一数据之中,将其一分为二,左半部置于该列左侧的左边,右半部置于右边;左半部与该列左侧之间的距离可以用 \tabbingsep 长度命令来设定,其默认值为 0.5em
\a:在 LaTeX 中,命令 \=、\“、’是用于生成重音字符的,tabbing环境重新定义了这三个命令,如果在表格中有这三种重音符号,可改用\a=、\a`,\a’` 来生成
\kill:使该行不排版出来,但其中的 \=、\ 、\- 和列宽度设置仍然有效
\pushtabs:存储当前各列宽度的设置
\poptabs:恢复最后一个 \pushtabs 命令所存储的各列宽度设置
下面给出几个例子来说明其用法。
% 胡伟《LaTeX2e 完全学习手册》\begin{tabbing} {\heiti 项目} \hspace{4mm} \= {\sffamily 802.11b} \hspace{4mm} \= {\heiti 蓝牙} \hspace{10mm} \= {\sffamily HomeRF} \\ 频率 \> 2.4GHz \> 2.4GHz \> 2.4GHz \\ 技术 \> DSSS \> FHSS \> FHSS \end{tabbing}
% 胡伟《LaTeX2e 完全学习手册》\begin{tabbing} 程序 \quad \= : \=\TeX \\ 开发者 \> : \> Donald Knuth \\ 教材 \> : \\ \pushtabs \quad \= \hspace{33mm} \= \hspace{30mm} \kill \> \kaishu 书名 \> \kaishu 出版社 \\ \> The \TeX Book \> Addison-Wesley \\ \> The Advanced \TeX \> Springer-Verlag \\ \poptabs 网址 \> : \> \sffamily http://tug.org.in/tutorial
\begin{tabbing} 夸克 quark \hspace{5mm} \= 介子 meson\\ \> 重子 baryon \hspace{5mm} \= 核子 nucleon \ \ \\ 超子 hyperon \- \\ 轻子 \> 强子 \\ \< 量子 \> 光子 \> 胶子 \\ 引力子 \> 重子\end{tabbing}
{\tabbingsep=0pt\begin{tabbing}\heiti 行星 \hspace{7mm} \= \heiti 赤道半径 km \hspace{8mm} \= \heiti 公转周期 d \\\pushtabs 水星 \hspace{20mm} \= 2\’.439 \hspace{18mm} \= 87\’.9 \\金星 \> 6\’.1 \> 224\’.682 \\地球 \> 6378\’.14 \> 365\’.25\poptabs \end{tabbing}}
tabular 和 tabular* 环境
tabular 和 tabular* 环境可以排版更加复杂的表格,也可以画表格线。这两个环境生成一个盒子,可以放在行中。
用法:
\begin{tabular}[<pos>]{<cols>} …行… \end{tabular}\begin{tabular*}{<width>}[<pos>]{<cols>} …行… \end{tabular*}
这里的 …行… 用 \\ 分隔每行,用 & 分隔列,形如:
列 & 列 … \\列 & 列 …
…行… 也可保存到一个或多个宏中,表格中出现条件判断也是能正确处理的,如
%\newif\ifsomething\begin{tabular}{cc}\ifsomething A & B \\ \else a & b \\ \fiC & D\end{tabular}
<cols> 参数用于给出每列的对齐方式,也称为导言区(preamble)。标准的 LaTeX tabular 环境可用的选项如下,array 等宏包还可使用其它选项。
l:左对齐
r:右对齐
c:居中对齐
p{<width>}:该列具有固定宽度 <width>,相当于把该格子放入 \parbox[t]{<width>} 中,能够个自动换行
|:插入竖直线,线的宽度不会改变表格的宽度
@{<decl>}:取消前后两列的列间距,并插入<decl>
*{<nums>}{<opts>}:将 <opts> 重复 <nums> 次
<pos> 参数是可选的,用于控制表格在该行的对齐方式,可用的值为c、t、b,分别表示居中对齐、按表格首行基线对齐、按表格基线对齐。
表1%\begin{tabular}{cp{1em}}列11 & 列12 \\列21 & 列22\end{tabular}的—表2%\begin{tabular}[t]{cp{1em}}列11 & 列12 \\列21 & 列22\end{tabular}的—表3%\begin{tabular}[b]{cp{1em}}列11 & 列12 \\列21 & 列22\end{tabular}的
如下的几个命令用于控制 tabular 环境的间距:
\tabcolsep:列水平间距的一半,默认值为 6pt
\arrayrulewidth:表格线的厚度(水平线的高度,竖直线的宽度),默认值为 0.4pt
\doublerulesep:两紧邻着的竖线的间距,默认值为 2pt
以上三个长度可以使用 \setlength{…}{<值>} 修改
\arraystretch:每行使用另外的高度,这个高度等于该行的 \strut 盒子的高度、深度乘 \arraystretch 的值,这个值使用 \renewcommand 修改,默认值为1
tabular* 环境用于排版定宽表格,使用得较少。
\begin{tabular*}{3cm}{c@{\extracolsep{\fill}}p{1em}}列11 & 列12 \\列21 & 列22 \end{tabular*}
该表格具有定宽3cm,第一二列之间使用弹性长度 \fill 填充,\extracolsep 命令用于增加对于列间的间距,这里使 \fill 。
array 宏包提供的列格式
array 宏包重新实现了 tabular 环境,提供了更多的列格式,也提供了自定义列格式的命令 \newcolumntype。本文介绍其预定义的列格式,具体的例子和 \newcolumntype 的用法将在本系列的下一篇文章中给出。
|:array 宏包修改了 | 格式,竖直线的宽度将影响两列的水平间距以及表格的宽度
m{<width>}:该列具有固定宽度 <width> ,该列的每个格子将与相应行的其它格子垂直居中对齐,类似于将该列的每个格子置于 \parbox{<width>} 中
b{<width>}:该列具有固定宽度 <width> ,该列的每个格子将与相应行的其它格子按基线对齐,类似于将该列的每个格子置于 \parbox[b]{<width>} 中
>{<decl>}:将 <decl> 的内容放到紧随其后的一个列的前面,如 >{1}c 将把 1 放在水平居中的这个列的内容之前,假设该列的第一个值为 a,则相当于 1a
<{<decl>}:将 <decl> 的内容追加到它之前的一个列的后面,如 c<{1} 将把 1 放在水平居中的这个列的内容之前,假设该列的第一个值为 a,则相当于 a1 。这两个格式可以多次使用,按照先增加的在后的规则,如 >{1}>{2}c<{a}<{b} ,假设该列的第一个值为 – ,则相当于 21-ba
!{<decl>}:将 <decl> 视为垂直线,可以用它来替换原本的垂直线,相较于 @{} ,它会保留原本间距
% 刘海洋《LaTeX 入门》\begin{tabular}{>{\bfseries}c >{\itshape}c >{$}c<{$}}\hline姓名 & \textnormal{得分} & \textnormal{额外加分} \\ \hline张三 & 85 & 7 \\李四 & 82 & 0 \\王五 & 70 & -2 \\ \hline\end{tabular}
% 刘海洋《LaTeX 入门》\begin{tabular}{>{$}r<{$} | >{\setlength\parindent{2em}}m{15em} |% >{\centering\arraybackslash}m{4em}}\hline\pi & 希腊字母,多用于表示圆周率,也常用做变量。表示圆周率时多使用直立体。& 常用 \\ \hline\aleph & 希伯来字母的第一个,在数学中通常用于表示特殊集合的基数。& 不常用 \\ \hline\end{tabular}
array 宏包是一个十分基础的宏包,大多数排版表格的宏包都会用到它,在实际使用时也会使输入更加便利。
下一篇中将介绍表格线的输入,表格行、列的合并,相应宏包的用法,以及 array 宏包的其它命令。