跳至内容
Topos Uranos

摘要

本课把上一课的易读表格推广到简单网格解决不了的情形。它讲授如何用 \multicolumn 横向合并单元格,用来在部分横线下把表头分组,或改变单个单元格的对齐方式,并推导出分组表头多出的宽度会落到哪里;讲授如何用 \multirow 纵向合并单元格,以及何时最好避免这样做;比较让表格与行宽相等的三种方法(tabularx 及其 X 列,带 \extracolsep 的 tabular*,以及不推荐的 \resizebox 缩放);用 longtable 排跨页的表格,包括重复的表头和它所需要的多遍编译;介绍为很宽的表格旋转页面的做法;用 csvsimple 和 pgfplotstable 从数据文件生成表格,并用 filecontents 创建该文件;介绍现代的替代方案 tabularray;最后在真实日志中阅读常见错误。

学习目标

  1. 用 \multicolumn 和 \cmidrule 构造分组表头,数清每一行的单元格,并预见数目不符时的结果。
  2. 在 \multirow 与 booktabs 传统中的空单元格之间作出选择,并从阅读的角度说明理由。
  3. 用 tabularx 或 tabular* 让表格与行宽相等,并解释为什么不用 \resizebox 缩放表格。
  4. 用 longtable 排一张带有自己的表头和表尾的跨页表格,读懂它的警告,并知道它为什么不能放进浮动体。
  5. 从数据文件生成表格,并说明单一数据来源的好处。

跨列的单元格

命令 \multicolumn{n}{对齐}{文本} 占据一行中 n 个相邻单元格的位置,并用一个单元格代替它们,其对齐方式由第二个参数给出,写法与表格导言中的列说明相同(l、c、r、p{…},以及 @{})。由此得出作者必须逐行核对的计数规则:普通单元格的个数加上每个 \multicolumn 声明的跨度,总和不得超过导言中的列数。

改变单个单元格的对齐

\multicolumn 最朴素的用法只跨一列:\multicolumn{1}{c}{…} 并不合并任何单元格,而是给这个单元格一种不同于其所在列的对齐方式。这样就可以让一列右对齐数字的表头居中,或者让合计行的标签右对齐,紧挨着它的数字。

例题一个项目的预算
LaTeX 代码
\documentclass{article}\usepackage{luatexja-fontspec}\setmainjfont{Noto Serif CJK SC}\usepackage{booktabs}\begin{document}\begin{tabular}{llr}\toprule科目 & 说明 & \multicolumn{1}{c}{金额} \\\midrule差旅 & 两次前往档案馆   & 1\,200 \\材料 & 纸张和移动硬盘   &    300 \\服务 & 档案数字化       &    850 \\\midrule\multicolumn{2}{r}{合计} & 2\,350 \\\bottomrule\end{tabular}\end{document}
结果
结果

表头“金额”居中于一列仍然右对齐的数字之上;跨前两列的标签“合计”右对齐,紧挨着它的数字。

分组表头

当几列同属一个类别时,两层表头会让表格更清楚:上层是组名,横跨该组的各列;下层是各列的名称。在两层之间,booktabs 提供部分横线 \cmidrule{2-3},只在第 2 至第 3 列下画线;加上选项 (lr),即 \cmidrule(lr){2-3},横线左右两端各缩进一点,使相邻的两条横线不相接,眼睛看到的是两个组。

例题一项研究的分组结果
LaTeX 代码
\documentclass{article}\usepackage{luatexja-fontspec}\setmainjfont{Noto Serif CJK SC}\usepackage{booktabs}\begin{document}\begin{tabular}{lrrrr}\toprule& \multicolumn{2}{c}{对照组}& \multicolumn{2}{c}{实验组(翻转课堂)} \\\cmidrule(lr){2-3} \cmidrule(lr){4-5}测量 & 均值 & 标准差 & 均值 & 标准差 \\\midrule前测 & 52.1 & 8.3 & 51.7 & 7.9 \\后测 & 54.0 & 8.1 & 61.2 & 7.4 \\\bottomrule\end{tabular}\end{document}
结果
结果

第一行有一个空单元格(开头的 &)和两个各跨两列的单元格:一加二加二,等于五,与导言一致。请注意,实验组的标准差一列比对照组的宽。

多出的宽度落到哪里

上例中宽度的差别并非偶然。如果 \multicolumn 的文字比它所跨各列的宽度之和还宽,表格就必须加宽,而引擎把全部多出的宽度都给这些列中的最后一列;其余各列保持自然宽度。“实验组(翻转课堂)”比“均值”和“标准差”两列加起来还宽,差额由后一列承受;“对照组”比较短,它下面的两列不受影响。表头比数据长得多时,这种效果就不再隐蔽。

例题过长的表头
LaTeX 代码
\documentclass{article}\usepackage{luatexja-fontspec}\setmainjfont{Noto Serif CJK SC}\usepackage{booktabs}\begin{document}\begin{tabular}{lrr}\toprule& \multicolumn{2}{c}{翻转课堂教学干预结束之后的实验组} \\\cmidrule(lr){2-3}测量 & 均值 & 标准差 \\\midrule前测 & 51.7 & 7.9 \\后测 & 61.2 & 7.4 \\\bottomrule\end{tabular}\end{document}
结果
结果

均值离它的标准差很远,中间隔着一段毫无意义的空白。这里要改的不是排版,而是措辞:用简短的表头(“实验组”),把说明写进表格标题或正文。