# -*- coding: utf-8 -*- """ 为待补分类(定位销/勾销缸/翻转缸/电缸)生成附图。 来源: Univer 官方图册 PDF(X盘 官方图册 / 选型表/spanner)。 输出: manual/<系列>/p.png + <系列>_manual.pdf 用法: PYTHONUTF8=1 python gen-pending-manual.py [--clean] """ import fitz, os, shutil, sys SRC = r'X:/新开发产品-Research and Development/2_产品资料/Univer资料/官方图册' SPANNER = r'X:/新开发产品-Research and Development/2_产品资料/Univer资料/选型表/spanner' DST = r'D:/开发/OnebotCatalog/onebot-data/catalog/manual' DPI = 110 CLEAN = '--clean' in sys.argv # 系列 -> (目录, [pdf 名]);pdf 名不含扩展名 SPECS = { # ---- 定位销 ---- 'ULA': (SRC, ['ula40cten_en419', 'ula63cten_en407']), 'ULB': (SRC, ['ulb32cten_en423']), 'ULL': (SRC, ['ull50cten_en411']), 'ULM': (SRC, ['ulm50cten_en410']), 'ULO': (SRC, ['ulo50cten_en413']), 'ULP': (SRC, ['ulp32cten_en404', 'ulp50cten_en405', 'ulp63cten_en406']), 'ULR': (SRC, ['ulr50nken_en476', 'ulr63cten_en477']), 'ULT': (SRC, ['ult50cten_en408']), 'ULX': (SRC, ['ulx50cten_en425']), 'ULY': (SRC, ['uly40cten_en426']), 'ULZ': (SRC, ['ulz40cten_en428']), # ---- 勾销缸 ---- 'USP': (SRC, ['usp32cten_en355', 'usp50cten_en437', 'usp50ucten_en168']), 'USL': (SRC, ['usl50cten_en171']), 'USR': (SRC, ['usr40cten_en436']), 'USS': (SRC, ['uss50cten_en433', 'uss63cten_en434']), 'USSL': (SRC, ['ussl50cten_en358']), # ---- 翻转缸 ---- 'UAGP': (SRC, ['uagp075wcten_en580', 'uagp075bcten_en181', 'uagp080wcten_en174', 'uagp080wcten_en573', 'uagp120bcten_en175', 'uagp120wcten_en574', 'uagp150bcten_en178', 'uagp150wcten_en577', 'uagp155wcten_en583', 'uagp170bnken_en176', 'uagp170wcten_en575', 'uagp210bcten_en182', 'uagp210wcten_en581', 'uagp215bcten_en373', 'uagp215wcten_en584', 'uagp300bcten_en177', 'uagp300wcten_en576', 'uagp350bcten_en183', 'uagp350wcten_en582', 'uagp355bcten_en374', 'uagp355wcten_en585', 'uagp600bcten_en179', 'uagp600wcten_en578', 'uagp605bcten_en180', 'uagp605wcten_en579']), # LAGP 官方已改名 UAGP,图册在选型表/spanner(老版) 'LAGP': (SPANNER, ['lagp075_en_c181', 'lagp120_en_c175', 'lagp150_en_c178', 'lagp155_en_c350', 'lagp170_en_c176', 'lagp210_en_c182', 'lagp215nwrev-00-0119en_en373', 'lagp300_en_c177']), # ---- 电缸 ---- 'LAE': (SRC, ['lae140_en_c220', 'lae225_en_c221', 'lae350_en_c222']), } def classify(page): t = page.get_text().upper() if 'ACCESSORIES' in t or 'CLAMPING ARMS' in t or 'BLADE ARMS' in t: return 'arm' if 'DIMENSIONS' in t: return 'dim' if 'CHARACTERISTICS' in t or 'CODIFICATION' in t: return 'char' return 'other' def main(): os.makedirs(DST, exist_ok=True) missing = [] for series, (srcdir, pdfs) in SPECS.items(): d = os.path.join(DST, series) if CLEAN and os.path.isdir(d): shutil.rmtree(d) os.makedirs(d, exist_ok=True) docs, all_pages = [], [] for name in pdfs: p = os.path.join(srcdir, name + '.pdf') if not os.path.exists(p): missing.append(f'{series}: {name}') continue doc = fitz.open(p) docs.append((name, doc)) for i in range(doc.page_count): all_pages.append((doc, i, classify(doc[i]))) if not all_pages: print(f'[{series}] 无可用源 PDF') continue order = {'char': 0, 'dim': 1, 'arm': 2, 'other': 3} all_pages.sort(key=lambda x: order[x[2]]) n = 1 for doc, i, _k in all_pages: # 彩色输出 (官方图册本身是彩色的; 早期版本误用 csGRAY 转灰度, # 体积约翻倍但相对整个数据包可忽略) doc[i].get_pixmap(dpi=DPI).save( os.path.join(d, f'p{n:02d}.png')) n += 1 out_pdf = fitz.open() for _name, doc in docs: out_pdf.insert_pdf(doc) outp = os.path.join(d, series + '_manual.pdf') out_pdf.save(outp, garbage=3, deflate=True) out_pdf.close() print(f'[{series}] {len(all_pages)} 页 / {len(pdfs)} PDF -> ' f'{os.path.getsize(outp)/1024:.0f}KB') if missing: print('\n源缺失:') for m in missing: print(' ', m) print('完成') if __name__ == '__main__': main()