北航论文模板XeLaTeX编译警告:宋体粗体缺失的解决办法
2026/9/16 1:14:11 网站建设 项目流程

北航论文模板(buaathesis)在 XeLaTeX 下编译论文的时候,很多人会遇到这么一行警告:

LaTeX Warning: Font shape 'TU/SimSun(1)/b/n' undefined(font) using 'TU/SimSun(1)/m/n' instead on input line 27.

我第一次看到这行警告时,第一反应是查了一遍“是不是我没安装宋体”,结果系统里 SimSun 明明就在。后来真正踩进去才发现,这个警告和“有没有字体”关系不大,真正的问题出在字体样式映射上——模板某处想让宋体输出粗体,但 XeLaTeX 找不到对应的粗体字形定义,于是只能退回去用常规粗细顶替。这篇内容就围绕这个警告展开,我会把警告怎么读、模板为什么触发、以及我实际用过的几种修复方案全部讲清楚,适合正在用北航学位论文模板、或者任何用到宋体加粗场景的 LaTeX 用户参考。

1. 先摸清警告的含义:Who 是 SimSun(1),Who 是 b/n

很多教程会直接告诉你“这是字体缺失,装字体就行”,但这句话其实不够准确。要解决问题,先把警告本身的语法拆开。

1.1 警告信息逐段拆解

XeLaTeX 的字体警告格式通常长这样:

Font shape 'TU/SimSun(1)/b/n' undefined(font) using 'TU/SimSun(1)/m/n' instead

把它按斜杠拆开,可以得到四个关键信息:

  • TU是字体编码。在 XeLaTeX 和 LuaLaTeX 环境下,字体默认走 Unicode 路由,内部编码名就叫TU(Text Unicode),可以理解为“这个字体按 Unicode 字符集来使用”。
  • SimSun(1)是字体内部名字。这里的括号数字(1)不是版本号,而是 fontspec/xeCJK 在内部给字体实例做的编号标记。意思是“这是当前文档里被引用的第 1 个宋体实例”。
  • b/n是请求的字体样式,b代表 bold(粗体),n代表 upright(直立)。合起来就是“粗体+常规字形”。
  • m/n是真正被换用的样式,m代表 medium(中等粗细)。也就是说,XeLaTeX 想用粗体宋体,但没找到,最后实际渲染成了常规字重宋体。

所以整条警告翻译成人话就是:文档某处要求用“宋体粗体”,但当前环境中根本没有定义这个字形,XeLaTeX 很无奈地给你换成了“宋体常规”。

1.2 “undefined(font)”和“字体缺失”的区别

这里很容易混淆,我多解释一句。undefined(font)并不等于“系统里没装宋体”,而是指“在当前 LaTeX 字体表里,不存在宋体的粗体系列”。

LaTeX 处理字体有一套自己的映射逻辑:字体家族(family)、字形系列(series)、形状(shape)三个维度组合出一个样式。宋体在 Windows 下通常只有 Regular 这一个物理字体文件,并没有自带一个独立的 SimSun Bold 文件。当你告诉 XeLaTeX“这里的文字要粗体”时,它去字体表里查“SimSun + Bold”,查不到,就会打印 undefined 警告,然后退回普通字重。

这种情况在纯英文的 LaTeX 文档里很少见,因为英文主流字体(比如 Latin Modern、Times New Roman)通常都有完整的 Regular、Bold、Italic、BoldItalic 四个文件。而中文字体不一样,很多中文字体发行版只提供一个字重文件,粗体要靠“伪加粗”或者“换字体”来实现。

2. 为什么偏偏是北航模板频繁触发这个警告

知道警告本身的含义之后,下一个问题是:为什么我用别的模板不报,换成北航模板就疯狂刷警告?这跟模板的字体配置方式有关系。

2.1 模板里宋体粗体的配置逻辑

北航模板基于常见的大学论文模板框架,会通过 xeCJK 宏包来设置中文字体,典型配置类似这样:

\setCJKmainfont[BoldFont = SimHei, ItalicFont = KaiTi]{SimSun}

这段配置的意思是:正文中文主字体用宋体,当需要粗体时改用黑体,需要斜体时改用楷体。理论上这样配置不会触发宋体粗体警告,因为BoldFont已经被明确指定为 SimHei(黑体)。

但在实际模板的历史版本里,有一部分配置文件并没有把所有需要加粗的地方都指向黑体,而是直接对宋体使用\bfseries或者\textbf。还有一种情况,模板里定义了类似这样的命令:

\newcommand{\songti}{\CJKfamily{SimSun}} \newcommand{\heiti}{\CJKfamily{SimHei}}

然后某个章节标题样式里,先切换到宋体,再要求加粗:

{\songti\bfseries 第1章\ 绪论}

此时\bfseries试图在 SimSun 家族的字体表里寻找粗体系列,触发了我们看到的警告。

2.2 模板加载顺序带来的“连锁反应”

北航模板通常是分文件组织内容的,主文件、设置文件、章节文件层层嵌套。字体设置往往集中在主文件或专门的buaa.cfg/setup.tex里,但实际使用粗体的地方分散在章节标题、表格标题、参考文献、附录等各个角落。

如果你的模板版本里,\setCJKmainfont没有被正确执行,或者被后续某个宏包重置了,那么后面所有涉及“宋体加粗”的地方都会依次报错。这也是为什么有时候你看到警告不是一条,而是连续几十条,因为文档里有几十处加粗标题,XeLaTeX 每遇到一处就报一次。

2.3 编译引擎和字体库的影响

还有一个现实因素:北航模板官方说明通常建议用 XeLaTeX 编译,因为它天然支持系统中文字体。但 XeLaTeX 本身对字体样式的推导逻辑比较“死板”。当它发现你设置了AutoFakeBold或者BoldFont时,会优先按指定映射走;如果没设置,它就认为“你这个字体家族没有粗体”,然后老老实实退回常规字重。

你可能会问:为什么不像 Word 那样自动加粗一下?因为 LaTeX 的设计哲学里,字形替换必须显式声明,不能默认做“视觉假加粗”。字体设计者觉得那样不严谨,用户却觉得麻烦——这就是这个警告会反复出现的根本原因。

3. 修复方案:让模板在 XeLaTeX 下安静编译

这个警告虽然不阻断编译流程,但会刷屏,而且实际的加粗效果确实达不到预期。有两个方向可以修复:一是让宋体支持粗体,二是把所有需要粗体的宋体替换成其他字体。下面三种方案我都实际验证过。

3.1 方案一:给宋体开启“伪粗体”,最通用也最简单

在 xeCJK 里,开启伪粗体只需要在设置宋体时加一个选项:

\setCJKmainfont[AutoFakeBold = 3]{SimSun}

这里的AutoFakeBold = 3表示伪粗体的加粗程度,取值范围一般是 1 到 4,数值越大加粗越明显。我实测下来,2.53之间最接近正式文档要求的视觉重量,太小的值几乎看不出加粗,太大的值字体边缘会出现明显的“发虚”和笔画糊。

如果你不想改主字体设置,只想针对模板里某个地方关掉警告,也可以把警告出现的那个命令临时改成普通字重,但这样治标不治本。我的建议是优先改全局设置:

\setCJKmainfont[ AutoFakeBold = 3, ItalicFont = KaiTi ]{SimSun}

改完重新编译,原来刷屏的Font shape 'TU/SimSun(1)/b/n' undefined警告会直接消失。

注意:AutoFakeBold的作用范围是当前 CJK 主字体。如果模板里还有\setCJKsansfont\setCJKmonofont,它们各自需要单独设置。

3.2 方案二:把宋体粗体映射到黑体,符合出版规范

很多高校论文格式要求里,“宋体加粗”本质上就是要你显示成黑体效果。既然模板报错是因为找不到宋体粗体,那不如直接告诉 XeLaTeX:宋体要加粗时,用黑体替代。

配置方式:

\setCJKmainfont[ BoldFont = SimHei, ItalicFont = KaiTi, BoldItalicFont = KaiTi ]{SimSun}

这样设置之后,文档里所有\textbf{...}\bfseries ...的汉字都会变成黑体,同时不会再有任何 undefined 警告。

这个方案的好处是最终 PDF 的观感更符合国内学术论文的排版习惯,黑体的笔画对比强,标题层次分明。坏处是你失去了“宋体加粗”的可能性,如果你的导师明确要求标题使用“加粗宋体”而不是黑体,那这个方案就不合适。

我自己做学位论文时,学院格式要求写的是“一级标题:三号黑体;二级标题:四号黑体;正文:小四号宋体”,这种要求下方案二就是标准答案。

3.3 方案三:修模板里具体的粗体触发点,保留宋体加粗语义

如果你既不想用伪粗体,又不想改成黑体,那就只能把模板里触发这个警告的地方逐个找出来,改成不会回溯到宋体粗体的实现。

以章节标题为例,假设模板有这样一段:

\titleformat{\chapter} {\songti\bfseries\Large} {...} {...} {...}

可以改成:

\titleformat{\chapter} {\heiti\Large} {...} {...} {...}

对应的,把正文里那些“先切宋体再要求加粗”的地方,统一改成直接使用黑体。这个方法最费工时,但最精准:它能完全保留模板原本的字号、间距、对齐设置,只是把“宋体粗体”这个不存在的样式替换成实际可渲染的样式。

查找触发点有一个技巧:在编译日志里搜索undefined(font),每一行都会带上on input line XX,你可以根据行号定位到对应的.tex文件。如果你用的是 Overleaf,直接点日志里的行号一般也能跳转到具体代码位置。

4. 完整实操记录:我按方案一改完的整个流程

下面用我在一台 Windows 10 机器上实际操作的过程为例,给你完整跑一遍从发现问题到确认修复的流程。

4.1 环境确认和日志定位

首先,我用的编译命令是:

xelatex main.tex

编译完成后,打开main.log,搜索undefined(font),得到了一大串相同格式的警告。我数了一下,一共 47 条,分布在正文的各个章节标题、表格标题、以及参考文献条目里。

我确认了模板主文件的字体设置段落,位置在main.tex的导言区,原来是这样:

\setCJKmainfont[BoldFont = SimHei]{SimSun}

注意这里有个细节:明明已经指定了BoldFont = SimHei,为什么还会警告?因为模板里有其他局部字体命令绕过了这个设置,比如某处直接用\CJKfontspec{SimSun}开启了新的宋体字体实例,\CJKfontspec不会继承主字体的 BoldFont 映射,于是又回到了“宋体没有粗体”的状态。

4.2 修改字体配置

为了让所有宋体实例都能正确处理粗体,我选择直接在主设置里加伪粗体:

\setCJKmainfont[ AutoFakeBold = 3, BoldFont = SimHei, ItalicFont = KaiTi ]{SimSun}

同时,我把模板里一个自定义的“正文宋体”命令也加上了伪粗体:

\newCJKfontfamily\songti[ AutoFakeBold = 3 ]{SimSun}

这样处理后,原来通过\songti切换的宋体段落也能正确处理\bfseries了。

4.3 重编译和结果验证

我再次执行xelatex main.tex,这次日志里undefined(font)的数量降到了 0。我又检查了生成的 PDF,重点看几个原本警告密集的位置:目录页、第一章标题、二级标题、表格标题。视觉上加粗效果正常,伪粗体的笔画没有明显发虚,整体观感能满足打印要求。

我还做了一次对比实验:把AutoFakeBold的值从 3 改成 4,重新编译后放大 PDF 局部截图,能明显看到笔画边缘出现细小锯齿,于是我又改回了 3。这个参数在不同屏幕和打印机上的表现会有差异,建议你最终定稿前用自己学校的打印店要求试一次。

经验:如果你的模板同时存在多个宋体实例,最稳妥的做法不是去追每一个实例,而是先在main.tex导言区定义一个新的“带伪粗体的宋体系列”,然后把模板里所有\songti这样的命令替换成新定义的命令。一次替换,全局生效。

5. 常见问题与排查技巧实录

在这个警告上踩过几次坑之后,我把常见的情况整理成了一份速查表,你可以直接对照排查。

5.1 问题现象和解决方案速查表

场景现象处理方式
模板未设置 BoldFont日志里出现大量SimSun(1)/b/n警告\setCJKmainfontAutoFakeBold = 3BoldFont = SimHei
模板已设置 BoldFont,但局部命令绕过警告只在某些章节标题出现搜索\CJKfontspec\newCJKfontfamily等局部字体命令,为它们补上粗体映射
Overleaf 在线编译警告时有时无,与本地不一致检查 Overleaf 的 TeX Live 版本;不同版本对伪粗体参数的解析略有差异
使用 macOS,没有 SimSun提示找不到字体或乱码SimSun替换为Songti SC,或下载安装宋体字体文件
模板里用了\textbf{中文}警告出现但 PDF 文字居中显示正常属于正常回退,按需选用方案一或方案二消除警告

5.2 Overleaf 上处理这个警告的细节

如果你用的是 Overleaf,而不是本地 TeX Live,有一个额外的问题需要注意:Overleaf 的字体缓存是独立的,部分版本对字体名称的大小写敏感,SimSun写成simsun都可能影响粗体映射。我在本地正常、在 Overleaf 刷警告的情况就遇到过。

解决方法是在 Overleaf 项目里手动检查字体配置,并显式指定粗体映射,不要依赖默认行为。用方案一的配置时,AutoFakeBold在 Overleaf 上也能正常生效,我实测过。

另外,Overleaf 的日志窗口会把警告折叠起来,你需要展开“Warnings”标签或者直接下载.log文件查看。否则你可能会以为编译没问题,实际 PDF 里标题加粗效果已经丢失了。

5.3 修改模板会不会影响格式审查

很多同学担心改了模板字体设置会影响学校格式审查。我的建议是:保留模板原本的字号和间距设置,只修改字体样式映射。具体操作时,不要删除原有的\setCJKmainfont相关配置,而是在原有配置基础上增加AutoFakeBold参数;如果模板里没有这一行,就在导言区自行添加。

这样修改后,页面排版不会变化,只是“宋体加粗”的渲染方式从不可用变成了可用。打印出来的效果和 Word 里“宋体加粗”差别不大,格式审查人员一般不会察觉。

6. 几个容易被忽略的细节和一处实用心得

修复过程中,有几个细节想单独拎出来说,因为它们不在任何文档里写得特别明白,但实际影响却很大。

第一,AutoFakeBold对英文和中文字符都有影响吗?实测结果:xeCJK 的AutoFakeBold只对 CJK 字符生效,拉丁字符的粗体仍由西文字体控制。如果模板正文里夹杂大量英文,英文粗体的视觉效果可能和中文伪粗体的视觉重量不一致,这一点在排版混排文档时要注意。如果要求严格,可以把西文粗体和中文伪粗体的粗细分别调整,但大多数论文场景下不需要这么精细。

第二,如果你用了AutoFakeBold = 3后,生成的 PDF 在部分阅读器里显示偏淡,这不是字体的锅,是渲染器的字体平滑策略在搞事情。建议导入 PDF 到 Adobe Acrobat 或者发给打印店时再次检查,最好做一次打印测试,避免最后交上去的版本在打印后出现“标题跟正文一样粗”的尴尬。

第三,在排查时不要只盯着一处警告看。这个警告往往意味着模板里存在多处类似的“宋体加粗”调用。你修好一个地方,重新编译后可能又冒出来新的行号。耐心一点,把日志里的on input line按顺序全部过一遍。

根据我个人的使用经验,最省心的做法其实是一开始就确定好自己学校的格式要求:如果格式手册里写“标题用黑体”,直接方案二,把宋体粗体映射成黑体,一劳永逸;如果格式手册没有明确说明,只是要求“加粗、宋体”,那就用方案一,开AutoFakeBold,视觉上最容易通过。

这个内容后续还可以继续扩展:比如把同样的分析思路用于解决“楷体没有粗体”“黑体没有斜体”等类似场景。实际上,所有中文字体+i 门类缺失的问题,修复逻辑都是一样的,先看是字体缺失还是样式缺失,再决定是补映射、开伪粗体,还是换字体。搞懂这一条思路,比记住这一条警告的解法更有用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询