LaTeX 表格怎么做:三线表、列宽与合并单元格
LaTeX 表格从入门到论文常用写法:tabular 的列格式与横竖线,booktabs 三线表,p 列和 tabularx 控制列宽与自动换行,multirow 和 multicolumn 合并单元格,表格标题、引用和跨页长表格,每个示例都能直接打开编译。
最后核对:2026-10-24LaTeX 的表格由两层组成:tabular 环境负责排出表格本身,table 浮动体负责标题、编号和在页面上的位置。先分清这两层,后面的问题(标题怎么加、表格为什么跑到下一页、为什么引用编号不对)就都好理解了。
最基本的表格怎么写
% !TEX program = xelatex
% title: LaTeX 表格入门
\documentclass{ctexart}
\begin{document}
\section{最简单的表格}
% tabular 的参数是列格式:l 左对齐,c 居中,r 右对齐,| 竖线
% 单元格之间用 & 分隔,每行用 \\ 结束,\hline 画横线
\begin{tabular}{|l|c|r|}
\hline
姓名 & 性别 & 成绩 \\
\hline
张三 & 男 & 92 \\
李四 & 女 & 88 \\
\hline
\end{tabular}
\section{带标题、可引用的表格}
% table 是浮动体:负责标题、编号和位置;tabular 负责表格本身
如表~\ref{tab:score} 所示,两位同学的成绩都在 85 分以上。
\begin{table}[htbp]
\centering
% 表格的标题习惯放在表格上方
\caption{期末成绩}
% \label 必须写在 \caption 之后,否则 \ref 得到的是节号
\label{tab:score}
\begin{tabular}{lcc}
\hline
姓名 & 数学 & 英语 \\
\hline
张三 & 92 & 85 \\
李四 & 88 & 90 \\
\hline
\end{tabular}
\end{table}
\end{document}
tabular 的参数是列格式,每个字母代表一列:
l、c、r:左对齐、居中、右对齐,列宽由内容决定;|:在两列之间画竖线;p{3cm}:固定宽度的列,内容超长时自动换行(见下文)。
表格内容里,& 分隔单元格,\\ 结束一行,\hline 画一条贯穿整行的横线。每行的 & 个数必须等于列数减一,多了会报 Extra alignment tab has been changed to \cr。
表格标题和引用怎么加
把 tabular 放进 table 环境,用 \caption 写标题,用 \label 打标签,正文里用 \ref 引用:
- 中文论文的习惯是表题在表格上方,所以
\caption写在tabular前面;图题则在图的下方。 \label一定要写在\caption之后。写在前面时,\ref拿到的是当前节号而不是表号,这是"表格引用编号不对"最常见的原因。\centering让表格居中。不要用center环境代替,它会在上下多加一段空白。- 用 ctex 文档类时,标题前缀自动是"表";用英文文档类时是"Table"。
table 的可选参数 [htbp] 控制位置,表格"乱跑"的原因和解决办法与图片相同,见插图与浮动体。
论文里的三线表怎么做
学术论文最常见的是三线表:顶线、底线较粗,表头下面一条细线,没有竖线。booktabs 宏包提供了这三条线:\toprule、\midrule、\bottomrule,以及只画在部分列下面的 \cmidrule。
% !TEX program = xelatex
% title: 三线表(booktabs)
\documentclass{ctexart}
\usepackage{booktabs} % 提供 \toprule、\midrule、\bottomrule、\cmidrule
\begin{document}
表~\ref{tab:result} 是论文里常见的三线表:
顶线和底线粗,栏目线细,没有竖线。
\begin{table}[htbp]
\centering
\caption{不同方法的实验结果}
\label{tab:result}
\begin{tabular}{lccc}
\toprule
方法 & 准确率(\%) & 召回率(\%) & 耗时(s) \\
\midrule
方法 A & 91.2 & 88.5 & 12.3 \\
方法 B & 93.6 & 90.1 & 15.8 \\
本文方法 & \textbf{95.4} & \textbf{92.7} & 13.1 \\
\bottomrule
\end{tabular}
\end{table}
% \cmidrule{2-3} 只在第 2~3 列下面画细线,(lr) 让线两端缩进一点
\begin{table}[htbp]
\centering
\caption{分组表头}
\label{tab:group}
\begin{tabular}{lcccc}
\toprule
& \multicolumn{2}{c}{训练集} & \multicolumn{2}{c}{测试集} \\
\cmidrule(lr){2-3} \cmidrule(lr){4-5}
模型 & 准确率 & 损失 & 准确率 & 损失 \\
\midrule
基线 & 0.92 & 0.21 & 0.88 & 0.30 \\
改进 & 0.95 & 0.15 & 0.91 & 0.24 \\
\bottomrule
\end{tabular}
\end{table}
% 注意:三线表不要再加竖线 |,booktabs 的横线与竖线接不上
\end{document}
几个要点:
\cmidrule(lr){2-3}在第 2 到第 3 列下面画线,(lr)让线的左右两端缩进一点,相邻两组表头的线就不会连在一起。booktabs的文档明确建议不要用竖线,也不要用双横线。它的横线上下带有额外的间距,文档也说明这些横线不保证能和竖线接上,混用时常见断开的缺口。- 单位、百分号写在表头里,如"准确率(%)"。在 LaTeX 源码里
%是注释符,要写成\%。
列太宽、文字超出页面怎么办
l、c、r 列不会换行,内容一长,表格就会伸出页边,日志里出现 Overfull \hbox。解决办法是给列一个宽度:
p{5cm}:列宽固定为 5cm,文字在列内自动换行。array宏包还提供m{5cm}(垂直居中)和b{5cm}(底端对齐)。tabularx环境:先指定整个表格的宽度(常用\linewidth),再把需要自动换行的列写成X,这些列平分剩余宽度。表格因此正好占满一行,不会超出。X列和p列一样两端对齐;列很窄、英文较多时,可以定义>{\raggedright\arraybackslash}X让它左对齐。想要居中的X列,用array宏包的>{...}在列前插入命令,定义一个新列型:\newcolumntype{Y}{>{\centering\arraybackslash}X}。\arraybackslash必不可少,否则这一列里的\\会失效。
% !TEX program = xelatex
% title: 表格列宽与自动换行
\documentclass{ctexart}
\usepackage{booktabs}
\usepackage{array} % 提供 >{...} 列前命令和 m{}、b{} 列
\usepackage{tabularx} % 提供按总宽度自动分配的 X 列
% 定义一个居中的 X 列:Y
\newcolumntype{Y}{>{\centering\arraybackslash}X}
\begin{document}
\section{固定列宽:p\{宽度\}}
% p{5cm} 列宽固定为 5cm,内容超长时自动换行
% 另有 m{宽度}(垂直居中)和 b{宽度}(底端对齐),需要 array 宏包
\begin{tabular}{lp{5cm}l}
\toprule
术语 & 解释(p 列) & 备注 \\
\midrule
浮动体 & 可以在页面中移动位置的对象,如图和表,由 LaTeX 决定放在哪里。 & 见插图一节 \\
\bottomrule
\end{tabular}
\section{占满整行:tabularx}
% 第一个参数是表格总宽度,X 列平分剩下的宽度
\begin{table}[htbp]
\centering
\caption{tabularx 示例}
\begin{tabularx}{\linewidth}{lXY}
\toprule
编号 & 说明(X 列,两端对齐,自动换行) & 状态(Y 列,居中) \\
\midrule
1 & 表格的总宽度固定为行宽,长文字会在 X 列里自动换行,不会超出页面。 & 完成 \\
2 & 短内容。 & 进行中 \\
\bottomrule
\end{tabularx}
\end{table}
\section{整体缩小}
% 表格太宽时,优先改列宽或换行;字号可以小一号,但不要用 \resizebox 硬缩
{\small
\begin{tabular}{lcccccc}
\toprule
数据集 & A & B & C & D & E & F \\
\midrule
结果 & 1.0 & 2.0 & 3.0 & 4.0 & 5.0 & 6.0 \\
\bottomrule
\end{tabular}}
\end{document}
表格只是略宽时,可以把字号调小一号(如 \small)。不建议用 \resizebox 把整个表格硬缩到行宽:缩放后表格的字号和正文不一致,线宽也跟着变细。
怎么合并单元格
- 跨列用 LaTeX 自带的
\multicolumn{列数}{对齐}{内容},例如\multicolumn{2}{c}{成绩}。它也常用来单独改变某个单元格的对齐方式。 - 跨行用
multirow宏包的\multirow{行数}{宽度}{内容},宽度写*表示按内容的自然宽度。被占用的下面几行,对应的单元格要留空(但&不能少)。 - 画了竖线的表格里,
\multicolumn的对齐参数要把竖线一起写上,如{|c|},否则这一格的竖线会消失。 - 不用
booktabs时,只在部分列下面画横线用\cline{2-3};用booktabs时用\cmidrule{2-3}。
% !TEX program = xelatex
% title: 合并单元格
\documentclass{ctexart}
\usepackage{booktabs}
\usepackage{multirow} % 提供 \multirow(跨行)
\begin{document}
% \multicolumn{列数}{对齐}{内容}:跨列,LaTeX 自带
% \multirow{行数}{宽度}{内容}:跨行,宽度写 * 表示按内容自然宽度
如表~\ref{tab:merge} 所示,“文科”“理科”各占两行,
“成绩”横跨两列。
\begin{table}[htbp]
\centering
\caption{合并单元格示例}
\label{tab:merge}
\begin{tabular}{llcc}
\toprule
\multirow{2}{*}{类别} & \multirow{2}{*}{科目} & \multicolumn{2}{c}{成绩} \\
\cmidrule(lr){3-4}
& & 期中 & 期末 \\
\midrule
% 被 \multirow 占用的下一行,对应单元格留空
\multirow{2}{*}{文科} & 语文 & 85 & 88 \\
& 历史 & 90 & 92 \\
\midrule
\multirow{2}{*}{理科} & 数学 & 95 & 93 \\
& 物理 & 87 & 91 \\
\bottomrule
\end{tabular}
\end{table}
% 带竖线的表格里,\multicolumn 的对齐参数要自己写上竖线,如 {|c|};
% 只在部分列画横线用 \cline{3-4}(不用 booktabs 时)
\begin{tabular}{|c|c|c|}
\hline
\multicolumn{3}{|c|}{横跨三列的标题} \\
\hline
\multirow{2}{*}{跨两行} & a & b \\
\cline{2-3}
& c & d \\
\hline
\end{tabular}
\end{document}
表格太长、要跨页怎么办
table 是一个整体,不能跨页。表格超过一页时,用 longtable 宏包的 longtable 环境代替 table 加 tabular。它可以分别设置首页表头、续页表头和每页底部:
\usepackage{longtable}
\usepackage{booktabs}
\begin{longtable}{lcr}
\caption{长表格示例}\label{tab:long} \\
\toprule
编号 & 名称 & 数值 \\
\midrule
\endfirsthead % 以上内容只出现在第一页
\multicolumn{3}{l}{(续表~\ref{tab:long})} \\
\toprule
编号 & 名称 & 数值 \\
\midrule
\endhead % 以上内容出现在后续每一页的顶部
\bottomrule
\endfoot % 每一页的底部
1 & 甲 & 10 \\
2 & 乙 & 20 \\
% ……更多行
\end{longtable}
注意:longtable 不放在 table 环境里,它的 \caption 写在环境内部、以 \\ 结尾;它需要多编译一次才能算准各页的列宽。
表格行距太挤怎么调
表格的行高由 \arraystretch 控制,默认是 1。整体调大可以在表格前写:
\renewcommand{\arraystretch}{1.3}
把这行放在 table 环境里面,只影响这一个表格;放在导言区,影响全文所有表格。三线表的 \toprule、\midrule 本身已经在线的上下留了空隙,通常不需要再调。
数字怎么按小数点对齐
实验数据表里,小数位数不同的数字居中后参差不齐。siunitx 宏包的 S 列按小数点对齐,table-format=3.2 表示整数部分最多 3 位、小数部分 2 位:
\usepackage{siunitx}
\begin{tabular}{l S[table-format=3.2]}
\toprule
样本 & {均值} \\
\midrule
甲 & 1.5 \\
乙 & 123.25 \\
\bottomrule
\end{tabular}
S 列里不是数字的内容(比如表头)按 siunitx 文档的建议用花括号包起来,如 {均值},宏包就会把它当作文字处理,而不会尝试把其中像数字的部分拿去对齐。
表格下方的注释怎么写
表格下方的"注:""a. 数据来源……"这类注释,可以用 threeparttable 宏包:表格放进 threeparttable 环境,单元格里用 \tnote{a} 标注,表格后面用 tablenotes 环境写注释内容,每条以 \item[a] 开头。它让标题和注释的宽度与表格本身一致,所以表格很窄时,标题也会跟着折行。
表题格式怎么改成"表 1 标题"
ctex 文档类默认的表题是"表 1: 标题"。很多学校要求编号和标题之间用空格而不是冒号,或者表题用小一号的字。用 caption 宏包统一设置,图题和表题都会生效:
\usepackage{caption}
\captionsetup{labelsep=quad, font=small}
labelsep=quad 表示编号后空一个 quad 的距离,也可以用 space(一个空格)或 period(句点)。只改表题时写 \captionsetup[table]{...}。
有没有更快的办法
手写大表格容易错位。可以先在 Excel 里排好,再用 Excel2LaTeX 这类插件或在线表格生成器导出 tabular 代码,然后按本文的方法换成三线表、调整列宽。生成的代码一定要再检查一遍 & 的数量和特殊字符的转义。
本文的示例都可以在 JointTex 中一键打开为新项目并直接编译,可以在示例的基础上改成自己的表格。表格里出现中文时要用 XeLaTeX 编译,见中文排版与字体;编译报错可以对照常见编译报错解读。
