Files
ouc_latex_template/年度考核登记表/README.md
T
laoyang 8984b93ee7 模板内容填充:全库 × 占位换成完整虚构示例,README 表述同步 #11
把 11 个模板里满篇的 × 换成一套连贯的虚构数据,让样张能看出排版效果。

虚构设定(跨模板统一):
- 数字逻辑 / 2025 秋 / 张远航 / 计算机科学与技术学院,教学日历、成绩构成
  说明、试卷归档封面、试卷四份互相对得上
- 简历:张远航,1985.03,教授博导,论文/专利/项目/获奖全套虚构
- 年度考核:同一人的 2025 年度考核表,年度总结四段写满
- 执行大纲:刻意不套用上面那套(原件就是《信号与线性系统分析》的课,
  强行改课程名会让章节体系、学时分配、思政案例全对不上)

假数据都留肉眼可辨标记:DOI 统一 10.9999/、专利号 ZL209999…、
软著 2024SR99999…、手机 138 0000 0000、邮箱 example.net。
签字/日期/评语栏仍然留空——编了就分不清该改哪儿。

修掉一个既有 bug(填充时才暴露):
年度考核登记表「出生年月」的值从来不显示,连字符都不在 PDF 里。
根因是 tabularray 的 cell{r}{c}={c=n} 里那个 c 是数据行的单元序号、
不是视觉列号,表头三处 c=2 要求该行吃 15 个视觉列而表只有 11 列,
超出部分静默丢弃。迷惑点:写 12 格丢值,写 9 格反而正常。
正解是表头不写 cell{},改用行内 \SetCell[c=n]{c},每行照常写满 11 格。
同时 R0 行原件本就装不下(前六字段 115.76mm,剩 42.20mm 要放
19.68mm 标签 + 17.22mm 值,但列宽被切成 15.31/1.38/25.51),
把标签折两行「出生/年月」解决,列宽一个没改。

README 同步:根 README 与 8 个模板 README 里「一律用 × 占位」的说法
已不成立,统一改为「示例内容全部虚构」,并说明哪些位置仍必须留空。

验证:12 个模板零 error,4 处基线警告未新增;干净副本重编页数一致;
PDF 正文 × 清零;真实信息零泄漏。
2026-10-27 12:50:02 +08:00

189 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 年度考核登记表 — 中国海洋大学 教职工年度考核登记表(LaTeX 版)
把学校下发的 Word 版《中国海洋大学教职工年度考核登记表》复刻为 LaTeX 模板,
版式与原 `.docx` 逐项对齐,**表格里不含任何真人信息**(姓名/职工号/出生年月/
单位/岗位全部是编的)。
> 样张填的是一份**完整的虚构考核表**:张远航(1985.03,信息科学与工程学部
> 计算机科学与技术学院,教授三级,中共党员),2025 年度,年度总结写了
> 思政 / 教学(176 学时)/ 科研(到账 320 万元)/ 人才培养四段。
> 之所以不写成满篇 `×`,是因为这张表**表格密、字数多**,光看叉号判断不出
> 行高会不会被内容撑开。虚构内容能直接看出「写这么多字正好排满 2 页」。
## 文件
| 文件 | 说明 |
| :-- | :-- |
| `年度考核登记表.tex` | 主文件。填表只改第 1 节(基本信息)与 `\khsummary`(年度总结) |
| `ouckhtb.sty` | 版式包。页面/字体/列宽/行高/全部尺寸都写在这里,附换算注释 |
## 编译
```bash
xelatex 年度考核登记表.tex
xelatex 年度考核登记表.tex # 跑两遍,第二遍取到正确页码
```
需要 **XeLaTeX**(用 fontspec + xeCJK),并安装:
`ctex`、`geometry`、`fontspec`、`xeCJK`、`tabularray`。
字体不需要安装 —— 全部来自仓库公共字体包 `../fonts/`(由 `../fonts.tex` 加载),
详见 [`../fonts/README.md`](../fonts/README.md)。**不再依赖系统里的宋体/黑体/仿宋**。
实测环境:TeX Live 2022 + `tabularray 2022A`。用 LuaLaTeX 理论上也行,但未验证。
产出 2 页、A4、正反面打印正好。
## 改内容
### 基本信息
```latex
\khtbyear{2025} % 表头“2025 年度”那一行
\newcommand{\khnum}{0000000} % 职工号
\newcommand{\khname}{{\fangsong 张远航}} % 姓名
\newcommand{\khsex}{{\fangsong 男}} % 性别
\newcommand{\khbirth}{{\fangsong 1985.03}} % 出生年月
\newcommand{\khdept}{{\fangsong 信息科学与工程学部}} % 单位(学部 / 学院)
\newcommand{\khsubdept}{{\fangsong 计算机科学与技术学院}} % 系(研究所、实验室、科室)
\newcommand{\khparty}{{\fangsong 中共党员}} % 政治面貌
\newcommand{\khtitle}{{\fangsong 教授}} % 现专业技术职务
\newcommand{\khpost}{{\fangsong 教授三级}} % 所聘岗位
```
> 上列值是**样张实际用的虚构内容**。职工号 `0000000` 故意留着没编 ——
> 职工号位数各校各单位不等,编一个反而会误导「照这个位数填」。
>
> ⚠️ 「出生年月」的**标签**不是写在 `\khbirth` 里,而是单独的
> `\khbirthlabel`(默认 `出生\par 年月`,折两行)。原因见下文第 0 条:
> 那一格只有 15.31mm,放不下 4 个 14pt 的字(要 19.68mm)。
> 想让标签恢复成一行「出生年月」,值就会重新被挤掉。
> **`{\fangsong ...}` 不能去掉。** 占位符 `×` 是 U+00D7,xeCJK 默认按 Unicode
> 区段把它判成**西文**,交给 fontspec 的西文字体(Termes/Times),而那儿的
> `×` 宽度与汉字不一致,几个就能撑破整列。
>
> **更好的做法**:`../fonts.tex` 里已经全局加了
> `\xeCJKDeclareCharClass{CJK}{"00D7}`,把 `×` 归入 CJK 字符类 ——
> 于是它自动按汉字全角宽度排,**不必再包 `\fangsong` 也不会撑破**。
> 这是本次字体改造顺带修掉的老 bug(原注释的修法从未真正生效过)。
### 年度总结
```latex
\newcommand{\khsummary}{%
第一段……\par
第二段……\par
第三段……}
```
段间用 `\par`(不要用空行 —— 空行在 `\newcommand` 参数里会被当成分段但不易数)。
首行自动缩进 2 字,末行自动带「本人签名 / 年 月 日」,都写在 `ouckhtb.sty` 里。
## 版式数据来源
所有尺寸都从 `.docx` 内部的 OOXML 数值换算,不使用目测:
```
twips → mm : mm = twips / 1440 × 25.4
twips → pt : pt = twips / 20 (1 pt = 1/72 in)
w:sz : 半磅值,÷ 2 即 pt
```
| 项 | docx 值 | LaTeX 值 |
| :-- | :-- | :-- |
| 纸张 | 11907 × 16840 twips | A4(210 × 297 mm) |
| 表宽 `tblW` | 8976 twips | 158.33 mm(11 列 + 边框) |
| 11 个 `gridCol` | 1087 283 1221 1047 284 1105 952 600 870 80 1447 | 见 `ouckhtb.sty` 第 3.1 节 |
| 正文字号 | `w:sz=28` | 仿宋 14 pt / 行距 15.6 pt |
| 大标题 | `w:sz=44`,`w:spacing=-14` | 黑体 22 pt / 字距 −0.7 pt |
| 行高 `trHeight` | 412 460 939 1261 1252 1009 556 1258 1258 | 7.27 / 8.11 / 16.56 / 22.24 / 22.08 / 17.80 / 9.81 / 22.19 / 22.19 mm |
### 页边距为什么不照抄 docx
docx 是左右各 30 mm 版心(150 mm),但表宽 158.33 mm 比它还宽 8.33 mm,
Word 是靠 `tblPr/jc=center` 把这张表“压”进页边距里的。
本模板把页边距改成 `(210 − 158.33)/2 = 25.835 mm`,使 `\textwidth` 恰好等于表宽:
- 表格天然居中,不需要 `\leftskip` / `\centerline` 之类的偏移;
- **表格在纸面上的绝对位置与 Word 完全一致**(左右各 25.835 mm);
- 编译时不会刷 `Overfull \hbox`。
表外文字(标题、脚注)仍是水平居中,视觉上与 30 mm 版心没有差别。
## 排版时的坑(sty 里都有详细注释)
0. 🔴 **表头 `cell{r}{c}={c=n}` 会静默丢内容 —— 已全部改成行内 `\SetCell`。**
这是本模板最难查的一个 bug:某个格子的值**整格不显示**,日志零 error 零
warning,光看日志和 PDF 页码完全发现不了。
- 现象:「出生年月」的值一直是空白。用 `××××.××` 占位时也是空白,
所以原版一直没人发现;换成真实内容才暴露。
- 根因:`cell{r}{c}` 里那个 `c` 是**数据行的单元序号**,不是视觉列号。
表头那三处 `c=2` 加起来要求该行吃掉 15 个视觉列,而表只有 11 列,
超出部分被静默丢弃 —— 丢的正好是最后一个值。
- 迷惑点:同一行写 12 格 → 丢值;写 10 格 / 9 格 → **反而显示**
(空缺给了它余量)。所以「格子数对不对」在这里完全不能当判断依据。
- 正解:表头不写 `cell{}`,合并直接标在被合并的那格上:
`\SetCell[c=2]{c} 职工号 & & 0000000 & ...`,每行照常写满 11 格。
- 附带修的:这个表 R0 行本来就装不下 —— 前六个字段已占 115.76mm,
剩 42.20mm 要装「出生年月」标签(19.68mm)+ 值(17.22mm),
但列宽被 `c9=15.31 / c10=1.38 / c11=25.51` 切死,标签占不住 c9
只能整体右移,值就被挤出去。处理是把标签折成两行「出生 / 年月」
(每行 9.84mm 放得下),值回到 c10-c11。**列宽一个都没改。**
1. **合并单元格不折行。** 合并格的单元类型 `{c}` 是 LR 模式,
格子里的文字比所跨各列合计更宽时,它**不折行,而是把列撑宽、整表超出版心**。
实测「系(研究所、实验室、科室)」把表从 448 pt 撑到 559 pt。
→ 所以合并格里的文字一律包 `\khtbfit{跨度宽宏}{文字}`。
单列的 `Q[c,m,wd=…]` 没有这个问题(超了只是溢出,列宽不变)。
2. **合并格里的 `\hsize` 没被重设。** span=10 的格子里 `\hsize` 仍是整页版心宽,
长文本会按 450 pt 折行、冲出格子。→ 长内容必须用定宽 `\parbox`(`\khtbcell`)。
3. **跨度声明写法:`cell{r}{c}={c=n}{c}` 与行内 `\SetCell[c=n]{c}` 都要用
`{c=n}{c}` 这一种。** `={c=n}`、`={n}{c}`、`={span=n}{c}` 都不认,最后那个
会报 `The key 'tblr-cell-span/span' is unknown`。
⚠️ 但如第 0 条所述,**跨列请优先用行内 `\SetCell`**,表头 `cell{}` 有丢内容的风险。
4. **`colspec` / `row{}` 里不能放宏。** tabularray 在宏展开之外解析列类型,
会报 `Unexpandable command … inside column type`。所以列宽只能字面写死。
另外两个容易忘的:
- `longtblr` 默认会把各列按 `\textwidth` 等比拉伸(`tblr` 不会),必须写 `stretch=0`;
- `longtblr` 会在续页处印「表 0: (Continued)」,必须用 `\DefTblrTemplate` 把
`caption` / `capcont` / `conthead-text` / `contfoot-text` **四个模板全清**。
## 与原 docx 的已知差异
| 位置 | docx | 本模板 | 说明 |
| :-- | :-- | :-- | :-- |
| 表头「×××× 年度」 | `firstLine` 缩进 2 字、未设居中 | 居中 | 更像原排版疏漏,按意图改居中。想还原就把 `\khtbtitle` 里的 `\centering` 换成 `\hspace*{2\ccwd}` |
| 「师德考核结果」首列 | `师师德考核结果` | `师德考核结果` | docx 原文首字重复(WPS 竖排遗留),已按正常写法更正 |
| 「单位年度考核建议档次」首列 | `单单位年度考核建议档次` | `单位年度考核建议档次` | 同上 |
| 单元格内边距 | 左右各 108 twips(1.905 mm) | 0 | c10 只有 1.41 mm,比两倍内边距还窄,统一内边距会算出负宽。代价是文字可贴竖线,但全部单元格本就水平居中,观感一致 |
| 未勾选框 | Wingdings `¨`(char 0x00A8) | U+25A1 `□` | Wingdings 在 Linux/macOS 上不可靠。仓库里的仿宋、黑体、宋体都含 `□`;且 `../fonts.tex` 已把 U+25A1 归入 CJK 类,不会再落到不含该字的西文字体上 |
| 电子签名图片 | 内嵌两张手写签名 JPEG | 无 | 模板不含真人信息 |
## 校验方法(想改版式时照这个验)
不要靠肉眼看 PDF。用矢量坐标对:
```bash
xelatex 年度考核登记表.tex
pdftocairo -svg 年度考核登记表.pdf pg.svg # 转成 SVG 取精确线条坐标
pdftotext -bbox 年度考核登记表.pdf - # 取每个字的 xMin/yMin/xMax/yMax
```
正确结果应当满足:
- 表格左边界 73.14 pt、右边界 520.91 pt(宽度 447.8 pt ≈ 157.96 mm);
- 表格所有横线都是 **10 段**(8 个网格列位置被合并掉,只剩 10 段可见);
- 页数为 2;
- `grep "Overfull\|too small" 年度考核登记表.log` 无输出。
当前状态:**零 Overfull、零 Underfull、2 页、表宽 157.96 mm**(目标 158.33 mm,
差 0.23%,为消除 0.45 pt 的 `Overfull` 累积误差而取整所致,肉眼不可辨)。