feat: export core Hermes skills
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
fix-richtext-rpr-order.py — 把 openpyxl CellRichText 写出的 <rPr> 子元素顺序
|
||||
改成 OOXML 合规顺序 (rFont -> sz -> color)。
|
||||
|
||||
⚠️⚠️ 重要警告(2026-06-18 世茂实证):
|
||||
本脚本只修 rPr 顺序,但实测 **修了顺序 Microsoft Excel 仍报"需要修复"**。
|
||||
openpyxl 生成的富文本表在 Excel 严格校验下还有其他不合规处(去掉富文本只留
|
||||
纯文本都仍报错)。所以本脚本 **不保证解决 Excel 报错**,仅作"试过什么"的记录。
|
||||
|
||||
正解:不要用 CellRichText 做局部标红/加粗,改用纯文本前缀(【需客户核实】…)。
|
||||
详见 ../references/openpyxl-excel-richtext-pitfall.md
|
||||
|
||||
用法:
|
||||
python fix-richtext-rpr-order.py <文件.xlsx> # 原地修复
|
||||
python fix-richtext-rpr-order.py <文件.xlsx> --check # 只检查,不改
|
||||
python fix-richtext-rpr-order.py <文件.xlsx> --sheet sheet2.xml # 指定 sheet
|
||||
"""
|
||||
import sys, re, zipfile, os
|
||||
|
||||
|
||||
def analyze(xlsx, sheet_name="xl/worksheets/sheet1.xml"):
|
||||
z = zipfile.ZipFile(xlsx)
|
||||
if sheet_name not in z.namelist():
|
||||
sheets = [n for n in z.namelist() if re.match(r"xl/worksheets/sheet\d+\.xml$", n)]
|
||||
print(f"指定 sheet 不存在;可用:{sheets}")
|
||||
return None, None
|
||||
xml = z.read(sheet_name).decode("utf-8")
|
||||
rprs = re.findall(r"<rPr>(.*?)</rPr>", xml, flags=re.S)
|
||||
bad = 0
|
||||
for inner in rprs:
|
||||
p_sz = inner.find("<sz")
|
||||
p_color = inner.find("<color")
|
||||
if p_sz != -1 and p_color != -1 and p_sz > p_color:
|
||||
bad += 1 # color 在 sz 之前 = 错误顺序
|
||||
return xml, (len(rprs), bad)
|
||||
|
||||
|
||||
def fix(xlsx, sheet_name="xl/worksheets/sheet1.xml"):
|
||||
xml, stats = analyze(xlsx, sheet_name)
|
||||
if xml is None:
|
||||
return
|
||||
total, bad = stats
|
||||
print(f"rPr 总数 {total},错误顺序 {bad}")
|
||||
if bad == 0:
|
||||
print("无需修复(顺序已合规)。注意:顺序合规 ≠ Excel 不报错,见脚本顶部警告。")
|
||||
return
|
||||
|
||||
def _fix(m):
|
||||
inner = m.group(1)
|
||||
rf = re.search(r"<rFont[^/]*/>", inner)
|
||||
cs = re.search(r"<charset[^/]*/>", inner)
|
||||
fam = re.search(r"<family[^/]*/>", inner)
|
||||
b = re.search(r"<b[^/]*/>", inner)
|
||||
i = re.search(r"<i[^/]*/>", inner)
|
||||
sz = re.search(r"<sz[^/]*/>", inner)
|
||||
co = re.search(r"<color[^/]*/>", inner)
|
||||
# OOXML 顺序: rFont, charset, family, b, i, ..., sz, color
|
||||
parts = [x.group(0) for x in (rf, cs, fam, b, i, sz, co) if x]
|
||||
return "<rPr>" + "".join(parts) + "</rPr>"
|
||||
|
||||
fixed = re.sub(r"<rPr>(.*?)</rPr>", _fix, xml, flags=re.S)
|
||||
tmp = xlsx + ".tmp"
|
||||
with zipfile.ZipFile(xlsx, "r") as zin, zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as zo:
|
||||
for it in zin.namelist():
|
||||
zo.writestr(it, fixed.encode("utf-8") if it == sheet_name else zin.read(it))
|
||||
os.replace(tmp, xlsx)
|
||||
print(f"已修复并写回 {xlsx}")
|
||||
print("⚠️ 仍需用 Microsoft Excel 实际打开验证——本脚本不保证消除 Excel 报错。")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
path = sys.argv[1]
|
||||
sheet = "xl/worksheets/sheet1.xml"
|
||||
if "--sheet" in sys.argv:
|
||||
sheet = "xl/worksheets/" + sys.argv[sys.argv.index("--sheet") + 1]
|
||||
if "--check" in sys.argv:
|
||||
_, stats = analyze(path, sheet)
|
||||
if stats:
|
||||
print(f"rPr 总数 {stats[0]},错误顺序 {stats[1]}")
|
||||
else:
|
||||
fix(path, sheet)
|
||||
Reference in New Issue
Block a user