# -*- coding: utf-8 -*- import openpyxl, copy, os, shutil from openpyxl.styles import PatternFill PATH = r'D:\01.프로젝트\DB수집\작업파일\공공기관3\6.한국자산관리공사\한국자산관리공사.xlsx' BK = r'D:\01.프로젝트\DB수집\작업파일\공공기관3\6.한국자산관리공사\한국자산관리공사_backup_조직안내탭전개전.xlsx' SKY = PatternFill('solid', fgColor='FFBDD7EE', bgColor='FFBDD7EE') NOFILL = PatternFill(fill_type=None) NC = 27 # AA mt0 = os.path.getmtime(PATH) shutil.copy(PATH, BK) wb = openpyxl.load_workbook(PATH) ws = wb.active MAXR = ws.max_row # merge anchor map for data rows anchor = {} for mr in list(ws.merged_cells.ranges): if mr.min_row >= 3: for rr in range(mr.min_row, mr.max_row+1): for cc in range(mr.min_col, mr.max_col+1): anchor[(rr,cc)] = (mr.min_row, mr.min_col) def eff(r,c): a = anchor.get((r,c),(r,c)) return ws.cell(*a).value, copy.copy(ws.cell(*a)._style) records = [] for r in range(3, MAXR+1): rec = {'path':[], 'pstyle':[], 'cells':{}, 'cstyle':{}, 'klink':None} for c in range(4,11): # D..J v,st = eff(r,c) rec['path'].append(v); rec['pstyle'].append(st) for c in [2,3]+list(range(11,NC+1)): cell = ws.cell(r,c) rec['cells'][c] = cell.value rec['cstyle'][c] = copy.copy(cell._style) if c==11 and cell.hyperlink: rec['klink'] = cell.hyperlink.target records.append(rec) # locate 조직안내 (F, mId=0104020000) ti = None for i,rec in enumerate(records): if rec['path'][2]=='조직안내' and '0104020000' in str(rec['cells'].get(11,'')): ti = i; break assert ti is not None, '조직안내 행 못찾음' base = records[ti] print('target record idx', ti, 'sheetrow', ti+3, 'path', base['path'][:4]) def mkchild(label, url, Nval): rec = {'path':[base['path'][0], base['path'][1], '조직안내', label, None, None, None], 'pstyle':[copy.copy(s) for s in base['pstyle']], 'cells':{}, 'cstyle':{}, 'klink':url} rec['cells'][2]=None rec['cells'][3]='한국자산관리공사' rec['cells'][11]=url rec['cells'][12]='페이지' rec['cells'][13]=1 rec['cells'][14]=Nval rec['cells'][15]='미부착' for c in [16,17]+list(range(18,NC+1)): rec['cells'][c]=None for c in [2,3]+list(range(11,NC+1)): rec['cstyle'][c]=copy.copy(base['cstyle'][c]) return rec c1 = mkchild('조직안내도', 'https://www.kamco.or.kr/portal/contents.do?mId=0104020100', '어문') c2 = mkchild('부서·업무내용 및 연락처', 'https://www.kamco.or.kr/portal/contents.do?mId=0104020200', '기타') c3 = mkchild('운영위원회', 'https://www.kamco.or.kr/portal/contents.do?mId=0104020300', '어문') records[ti:ti+1] = [c1,c2,c3] # remove all data merges for mr in list(ws.merged_cells.ranges): if mr.min_row >= 3: ws.unmerge_cells(str(mr)) start = 3 N = len(records) for idx,rec in enumerate(records): r = start+idx for k,c in enumerate(range(4,11)): cell = ws.cell(r,c); cell.value = rec['path'][k]; cell._style = copy.copy(rec['pstyle'][k]) bcell = ws.cell(r,2); bcell.value = idx+1; bcell._style = copy.copy(rec['cstyle'][2]) for c in [3]+list(range(11,NC+1)): cell = ws.cell(r,c); cell.value = rec['cells'].get(c); cell._style = copy.copy(rec['cstyle'][c]) kc = ws.cell(r,11); kc.hyperlink = None kv = rec['cells'].get(11) if kv and str(kv).startswith('http'): kc.hyperlink = kv # clear trailing rows newmax = start+N-1 if newmax < MAXR: for r in range(newmax+1, MAXR+1): for c in range(1, NC+1): ws.cell(r,c).value = None ws.cell(r,c).hyperlink = None # strip cyan + sky-blue on the 3 new rows for j in range(3): r = start+ti+j for c in range(2, NC+1): ws.cell(r,c).fill = NOFILL for c in [7,11,12,13,14,15]: # G,K,L,M,N,O ws.cell(r,c).fill = SKY ws.cell(start+ti, 6).fill = SKY # F=조직안내 merged anchor # re-merge path cols D..J by full-prefix equal runs for c in range(4,11): i = 0 while i < N: v = records[i]['path'][c-4] if v is None or v=='': i += 1; continue j = i+1 while j < N: same = all(records[j]['path'][cc-4]==records[i]['path'][cc-4] for cc in range(4,c+1)) if not same: break j += 1 if j-i > 1: ws.merge_cells(start_row=start+i, start_column=c, end_row=start+j-1, end_column=c) i = j if os.path.getmtime(PATH) != mt0: raise SystemExit('ABORT: mtime changed during work') wb.save(PATH) print('saved. rows', N, 'maxrow', ws.max_row)