vibe-py-word

·

问题

起因是想用ai给我东西的时候直接生成word格式,省的自己调整了,结果发现自己怎么强调格式都给我生成这个样子的。。。

image-20260101204502064

看起来是正文里夹杂了加粗,为什么呢?

我又看了下发现并没有真的加粗,只是并没有如愿按我的要求生成“宋体”,而是使用了另一个字体“MS Mincho”,估计是这个字体本身的问题,下载下来ai生成word过程中的python脚本发现其实是用了宋体的,并不是没注意到文档要求。

原因

继续查阅资料,发现原因了:

python-docxDocument() 新建文档时,会使用它自带的默认 default.docx 模板。该模板在 word/settings.xml 里把东亚语言设置成了 日语(ja-JP)(等价于“本文件东亚文字环境偏日文”)。在这种情况下:

样式里的字体往往是“主题字体”(如 minorEastAsia),不是写死的“宋体/微软雅黑”;Word 会根据 eastAsia=ja-JP 去选择一套“日文东亚主题字体”,在 Windows 上常见的就是 MS Mincho

当某个字符 MS Mincho 没有对应字形时,Word 会在后台用另一套字体的字形来“补齐”。补齐来的字形笔画粗细/对比度可能不同,于是你看到“某些词突然更黑、更粗”,但字体框仍显示 MS Mincho

为了验证,我检索了几个看上去没有加粗的,都是日文常见字,加粗的则不是(第一次发现原来日文这么多字都是汉字,一模一样啊,我一开始还以为加粗的才是两种文字一样的)

这种问题,我们称之为字形回退

解决方法

补丁函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from docx.oxml.ns import qn
from docx.oxml import OxmlElement

def set_east_asia_defaults(doc, font_zh="宋体", east_asia_lang="zh-CN"):
# 1) settings.xml: 设置东亚语言,避免主题字体解析到日文字体
settings = doc.settings._element
tfl = settings.find(qn('w:themeFontLang'))
if tfl is None:
tfl = OxmlElement('w:themeFontLang')
settings.append(tfl)
tfl.set(qn('w:eastAsia'), east_asia_lang)

# 2) Normal 样式:把 East Asia 字体写死(不要只设 run.font.name)
normal = doc.styles['Normal']
normal.font.name = font_zh
rPr = normal.element.get_or_add_rPr()
rFonts = rPr.get_or_add_rFonts()
rFonts.set(qn('w:ascii'), font_zh)
rFonts.set(qn('w:hAnsi'), font_zh)
rFonts.set(qn('w:eastAsia'), font_zh)
rFonts.set(qn('w:cs'), font_zh)

def force_run_font(run, font_zh="宋体"):
# 可选:写入每个 run 的 eastAsia 字体,彻底避免主题/回退干扰
from docx.oxml.ns import qn
run.font.name = font_zh
rFonts = run._element.rPr.rFonts
rFonts.set(qn('w:ascii'), font_zh)
rFonts.set(qn('w:hAnsi'), font_zh)
rFonts.set(qn('w:eastAsia'), font_zh)
rFonts.set(qn('w:cs'), font_zh)

使用

1
2
doc = Document()#这句原本就有,在这里后面加入
set_east_asia_defaults(doc, font_zh="宋体", east_asia_lang="zh-CN")

于是,我们就强制声明了文字类型,搞定!

【最后的吐槽:为什么会用East Asia 语言这个分类还默认会是日文啊???日文使用量才多大,还默认调用,都不报个警告。。。

Word:我不会告诉你我换了字形, 你看到的粗细差异,是你应该自己理解的系统之美(bushi】


vibe-py-word
http://example.com/2026/01/01/vibe-py-word/
作者
oxygen
发布于
2026年1月1日
许可协议