"""修正 WPS 写错的字体字符集:中文字体(名字含汉字,或是常见中文字体英文名)被标成 SYMBOL(02) 时改成 GB2312(86)。 输入、输出都是 DOCX。用法:python -I fix_charset.py in.docx out.docx""" import re, sys, zipfile CJK_LATIN = {"SimSun", "NSimSun", "SimHei", "FangSong", "KaiTi", "Microsoft YaHei", "DengXian"} def is_cjk_font(name: str) -> bool: return bool(re.search(r"[一-鿿]", name)) or name in CJK_LATIN def fix_font_table(xml: str) -> tuple[str, list[str]]: fixed = [] def repl(m): name, body = m.group(1), m.group(2) if is_cjk_font(name) and re.search(r'w:charset w:val="02"', body): fixed.append(name) body = body.replace('w:charset w:val="02"', 'w:charset w:val="86"') return f'{body}' return re.sub(r'(.*?)', repl, xml, flags=re.S), fixed def main(src, dst): with zipfile.ZipFile(src) as zin, zipfile.ZipFile(dst, "w", zipfile.ZIP_DEFLATED) as zout: for item in zin.infolist(): data = zin.read(item.filename) if item.filename == "word/fontTable.xml": xml, fixed = fix_font_table(data.decode("utf-8")) data = xml.encode("utf-8") print("fixed:", fixed) zout.writestr(item, data) if __name__ == "__main__": main(sys.argv[1], sys.argv[2])