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

看起来是正文里夹杂了加粗,为什么呢?
我又看了下发现并没有真的加粗,只是并没有如愿按我的要求生成“宋体”,而是使用了另一个字体“MS Mincho”,估计是这个字体本身的问题,下载下来ai生成word过程中的python脚本发现其实是用了宋体的,并不是没注意到文档要求。
原因
继续查阅资料,发现原因了:
python-docx 用 Document() 新建文档时,会使用它自带的默认 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"): 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)
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="宋体"): 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】