LaTeX 怎么写中文:ctex、XeLaTeX 与字体设置

用 ctex 文档类在 LaTeX 里排中文:为什么要用 XeLaTeX 编译,fontset 的 fandol、windows、mac、ubuntu 有什么区别,在线编译缺少宋体黑体时怎么替换字体,以及字体找不到、缺字、pdfLaTeX 报错等常见问题的原因和解决办法。

最后核对:2026-10-24

在 LaTeX 里写中文,现在的标准做法只有一句话:用 ctex 文档类,用 XeLaTeX 编译。 大部分中文报错都来自没做到其中一条,或者文档指定的字体在编译的机器上不存在。本文从最小可用的文档开始,讲清楚字体是怎么选出来的,以及出错时该看哪里。

最简单的中文文档怎么写

把 \documentclass{article} 换成 \documentclass{ctexart},其余照常写:

% !TEX program = xelatex
% title: ctexart 中文文档
% 第一行告诉编辑器用 XeLaTeX 编译;ctex 的 Fandol 字库不支持 pdfLaTeX
\documentclass[UTF8, fontset=fandol, zihao=-4]{ctexart}
% fontset=fandol:使用 TeX Live 自带的 Fandol 开源字体,任何系统都能编译
% zihao=-4:正文小四号(默认是五号,写 zihao=5)

\title{中文排版示例}
\author{张三}
\date{\today}

\begin{document}
\maketitle

\section{字体命令}
% ctex 预定义的四个字体命令在所有字库里都有
{\songti 这是宋体},{\heiti 这是黑体},
{\kaishu 这是楷书},{\fangsong 这是仿宋}。
\textbf{粗体}在 Fandol 宋体下会用 Fandol 宋体的粗体。

\section{字号}
% \zihao{} 接受 0、-0、1、-1……8,负号表示“小”
{\zihao{3} 三号字} {\zihao{-4} 小四号字} {\zihao{5} 五号字}

\section{中英文混排}
中文与 English 混排时,xeCJK 会在中英文之间自动加入合适的间距,
源文件里加不加空格都可以:中文English中文。

% ctex 把“图”“表”“目录”“参考文献”等名称都换成了中文
\section{章节标题}
ctexart 的节标题默认居中;用 \verb|\ctexset| 可以改成左对齐:
\ctexset{section/format = \Large\bfseries\raggedright}
\section{改为左对齐的标题}
这一节之后的标题都左对齐。

\end{document}
ctexart 中文文档在 JointTex 中打开

ctex 宏集提供四个文档类,分别对应标准文档类:ctexart(文章)、ctexrep(报告)、ctexbook(书籍)、ctexbeamer(幻灯片)。它们会:

  • 配置中文字体和中文断行、标点处理;
  • 把"Figure""Table""Contents""References"换成"图""表""目录""参考文献";
  • 把默认字号调成五号,行距调大;节标题改成中文习惯的样式。

源文件请保存为 UTF-8 编码。ctex 默认按 UTF-8 处理,UTF8 选项写不写都可以。

为什么要用 XeLaTeX 编译

XeLaTeX 和 LuaLaTeX 能直接调用系统里的 OpenType/TrueType 字体,中文字体就是这样加载的。pdfLaTeX 不能,所以:

  • 用 article 等英文文档类、正文里直接写中文,用 pdfLaTeX 编译会报 LaTeX Error: Unicode character 中 (U+4E2D) not set up for use with LaTeX。
  • 用 ctexart,但在 Linux 上用 pdfLaTeX 编译,会报 CTeX fontset 'fandol' is unavailable in current mode。ctex 文档的自动配置表里,pdfLaTeX 只在 Windows 上可用,并且走的是 CJK 宏包的方案。

结论是统一用 XeLaTeX。有些本地编辑器靠文件第一行的魔法注释 % !TEX program = xelatex 选编译器,本页的示例都写了这一行;JointTex 以项目的编译设置为准,只写这一行不会切换编译器。LuaLaTeX 也可以,ctex 在 LuaLaTeX 下改用 LuaTeX-ja 宏包,个别细节和 XeLaTeX 不同,没有特别需要时用 XeLaTeX 即可。

fontset 是什么,fandol、windows、mac 有什么区别

ctex 的 fontset 选项决定用哪一套中文字体。不写时,ctex 会检测编译所在的操作系统自动选择:

编译环境自动选择的 fontset使用的字体
Windowswindows中易宋体、黑体、楷体、仿宋,微软雅黑
macOS(10.11 及以后)macnew华文字体、苹方
其他系统(Linux 等)fandolFandol 开源字体(TeX Live 自带)

也可以手动指定,例如 \documentclass[fontset=fandol]{ctexart}。可选值还有 ubuntu(思源宋体、思源黑体和文鼎楷体)、adobe、founder(方正),较新的 ctex 还有 hanyi(汉仪);none 表示 ctex 不设字体,由你自己用 \setCJKmainfont 等命令设置。

这张表解释了一个常见现象:同一份文档,在自己的 Windows 电脑上编译正常,换到 Linux 服务器或在线编辑器就出错或字体变了。 在线编译几乎都运行在 Linux 上,那里没有 Windows 的宋体黑体,ctex 自动选的是 Fandol;如果文档里写死了 fontset=windows 或 \setCJKmainfont{SimSun},就会找不到字体。

在线编译缺宋体、黑体怎么办

先判断是否真的需要宋体黑体本身:

  1. 只要能编译、字体像样:写 fontset=fandol。Fandol 是宋、黑、楷、仿宋四款开源字体,任何装了 TeX Live 的系统都有。缺点是字库较小,缺少部分生僻字和繁体字。
  2. 想要字形更好、字更全:编译环境里有思源(Noto CJK)字体时,用它代替。下面的示例先用 Fandol 保证能编译,再用 \IfFontExistsTF 检测 Noto Serif CJK SC,有就换上;西文用 TeX Live 自带的 TeX Gyre Termes 代替 Times New Roman。
  3. 学校明确要求中易宋体等字体:把字体文件放进项目里再用文件名或字体名调用,或在装有这些字体的电脑上本地编译。宋体、黑体等是商业字体,上传和使用前请确认授权。
% !TEX program = xelatex
% title: 没有宋体黑体时的字体设置
\documentclass[fontset=fandol]{ctexart}
% 先用 Fandol 保证能编译,再在有更好字体时替换

% 西文:Times New Roman / Arial 的开源替代(TeX Live 自带 TeX Gyre)
\setmainfont{TeX Gyre Termes}   % 类似 Times New Roman
\setsansfont{TeX Gyre Heros}    % 类似 Helvetica / Arial
\setmonofont{TeX Gyre Cursor}   % 类似 Courier

% 中文:有思源(Noto CJK)字体就用它,没有就保持 Fandol
% \IfFontExistsTF 由 fontspec 提供,判断系统能否找到这个字体
\IfFontExistsTF{Noto Serif CJK SC}{
  \setCJKmainfont{Noto Serif CJK SC}[BoldFont = * Bold]
  \setCJKsansfont{Noto Sans CJK SC}[BoldFont = * Bold]
  % \songti、\heiti 也指向同一套字体
  \setCJKfamilyfont{zhsong}{Noto Serif CJK SC}[BoldFont = * Bold]
  \setCJKfamilyfont{zhhei}{Noto Sans CJK SC}[BoldFont = * Bold]
  \newcommand\cjkfontname{Noto Serif CJK SC}
}{
  \newcommand\cjkfontname{Fandol}
}

\begin{document}

\section{当前字体}
本文的中文正文字体是:\cjkfontname。

Western text uses TeX Gyre Termes, a free Times-like font.
\textsf{Sans serif text uses TeX Gyre Heros.}

\section{生僻字测试}
% Fandol 缺少部分生僻字和繁体字,缺字时日志里会有
% Missing character 警告,PDF 里这个字会空着
人名常见用字:堃、喆、昇、犇。

{\heiti 黑体} 与 \textbf{粗体}。

\end{document}
没有宋体黑体时的字体设置在 JointTex 中打开

注意 Fandol 缺字时不会报错,只在日志里留下 Missing character: There is no 堃 (U+5803) in font [FandolSong-Regular.otf]...(在日志里搜索 Missing character 即可找到),PDF 里那个字是空白。人名、地名里有生僻字时,要检查日志里有没有这条警告。

英文模板里怎么加中文

期刊或会议的英文模板不能换成 ctexart,这时在导言区加 ctex 宏包。scheme=plain 表示只提供中文支持,不改模板的字号、标题样式和"Figure"等名称:

% !TEX program = xelatex
% title: 在英文模板中加入中文
\documentclass[11pt]{article}
% 期刊或会议的英文模板不能换成 ctexart 时,用 ctex 宏包。
% scheme=plain 只加中文支持,不改标题、日期、字号等格式
\usepackage[UTF8, scheme=plain, fontset=fandol]{ctex}

\title{A Paper with 中文 Text}
\author{Zhang San (张三)}
\date{}

\begin{document}
\maketitle

\section{Introduction}
This template stays in English: the section name, the date format
and the font sizes are unchanged. 但正文里可以直接写中文,
中英文之间的间距由 xeCJK 自动处理。

\section{Notes}
% 只想在少数地方写中文时,xeCJK 宏包也可以,
% 但 ctex 还会处理中文的断行和标点,更省心
\textbf{加粗的中文} and \emph{强调的中文}。

\end{document}
在英文模板中加入中文在 JointTex 中打开

如果用 XeLaTeX 编译英文模板、却没有加载任何中文支持,编译不会报错,但中文全部消失,日志里是 Missing character: There is no 中 (U+4E2D) in font [lmroman10-regular]。看到这条就说明当前字体里没有汉字,加上 ctex 宏包即可。

宋体、黑体、楷体怎么切换

ctex 为每套字库定义了字体命令:

  • \songti 宋体,\heiti 黑体,\kaishu 楷书,\fangsong 仿宋。所有字库都有这四个命令(旧版 ctex 的 ubuntu 字库没有仿宋)。
  • \lishu 隶书、\youyuan 幼圆只在 windows、founder、macnew 字库里有;\yahei 在 windows 和 macnew 里有。

这些命令等价于 \CJKfamily{zhsong}、\CJKfamily{zhhei} 等。在 Fandol 下用 \lishu 会报 Undefined control sequence;直接写 \CJKfamily{zhli} 则不报错,只有一条 Unknown CJK family 'zhli' is being ignored 警告,文字仍是宋体。所以"换了电脑以后隶书变成宋体",原因多半是 fontset 变了。

字号用 \zihao{-4}(小四)、\zihao{5}(五号)这类写法;全文默认字号用文档类选项 zihao=-4。

行距、段首缩进和标点怎么调

学校格式要求里常见的几项,ctex 都有对应的选项。有的只能写在文档类选项里,有的只能写在 \ctexset{...} 里,多数两处都可以:

  • 行距:ctex 文档类默认 linespread = 1.3,即 1.3 倍行距,相邻两行基线距离是字号的 1.3 × 1.2 = 1.56 倍。要改就在文档类选项里写,例如 \documentclass[linespread=1.5]{ctexart};这个选项不能放进 \ctexset,否则会报 The key 'ctex/linespread' is unknown。注意不要和 linestretch 搞混:linestretch 控制的是汉字之间为了左右对齐可以拉开多少,不是行距。
  • 段首缩进:ctex 文档类默认每段缩进两个汉字宽,并且在字号变化时自动跟着调整。要固定成别的长度,先写 \ctexset{autoindent=false},再 \setlength\parindent{...}。
  • 标点宽度:punct 选项可选 quanjiao(全角式)、banjiao(半角式)、kaiming(开明式:句末点号占一个字宽,其他标点占半个字宽)等。
  • 日期:ctex 把 \today 改成了"2026 年 10 月 24 日"的格式;\ctexset{today=big} 得到全汉字的"二〇二六年十月二十四日",today=old 恢复英文格式。

用 ctex 宏包加 scheme=plain 时,以上这些都不会自动修改,行距和缩进沿用原来的文档类。

常见报错对照

日志里的内容原因解决
The font "SimSun" cannot be found文档指定了编译机器上没有的字体(常见于 fontset=windows)改用 fontset=fandol,或换成环境里有的字体,或上传字体文件
Unicode character 中 (U+4E2D) not set up for use with LaTeX用 pdfLaTeX 编译中文改用 XeLaTeX,并使用 ctex
CTeX fontset 'fandol' is unavailable in current modectex 文档用 pdfLaTeX 编译改用 XeLaTeX
Missing character: There is no ... in font FandolSong-Regular字库缺这个字(生僻字、繁体字)换用字更全的字体,如思源宋体
Missing character: There is no 中 ... in font [lmroman10-regular]没有加载中文支持加载 ctex 宏包或使用 ctexart
\lishu 等命令 Undefined control sequence当前字库没有这款字体换 fontset,或用 \setCJKfamilyfont 自定义

更多与中文无关的报错,见常见编译报错解读。

西文字体也要一起考虑

ctex 只管中文字体。XeLaTeX 下西文默认是 Latin Modern,要用 Times 风格时,可以 \setmainfont{TeX Gyre Termes};\setmainfont{Times New Roman} 只有在系统装了这款字体时才能用,道理和宋体一样。数学公式字体是另一套设置,不受这两条命令影响。

本页示例在 JointTex 中可以一键打开为新项目,打开的项目已经设为 XeLaTeX;自己的项目要在编译设置里把引擎改为 XeLaTeX。JointTex 的编译服务器是 Linux 环境,没有 Windows 和 macOS 的字体,提供 TeX Live 自带字体和 Noto CJK 字体;项目里自带的字体文件(建议放在 fonts/ 文件夹)也能被找到。接下来可以看表格和插图的写法。

JointTex

Browser compatibility

JointTex could not start

The application did not finish loading. Check your connection, then try again.

Supported versions

  • Chrome and Edge 88 or later
  • Firefox 84 or later
  • Safari and iOS Safari 14 or later
Reload