# -*- coding: utf-8 -*- import openpyxl, re from copy import copy from openpyxl.styles import PatternFill FN='국민건강보험공단.xlsx' BLUE=PatternFill(fill_type='solid', fgColor='FFBDD7EE') H='https://www.nhis.or.kr' def pg(label, path): return (label, H+path, '페이지', 1, '어문', '미부착') def bd(label, path, m, n='어문'): return (label, H+path, '게시판', m, n, '미부착') # (parent_url_substr, level 'G'|'F', tabs[first=self,...]) GROUPS=[ ('wbhaca04500m01','G',[pg('일반건강검진','/nhis/healthin/wbhaca04500m01.do'),pg('암검진','/nhis/healthin/wbhaca04600m01.do'), pg('의료급여생애 전환기검진','/nhis/healthin/wbhaca04700m01.do'),pg('영유아건강검진','/nhis/healthin/wbhaca04800m01.do'), pg('학생건강검진','/nhis/healthin/wbhaca04900m01.do'),pg('학교 밖 청소년 건강검진','/nhis/healthin/wbhaca05200m01.do')]), ('retrieveDiseVltGnlSymp','G',[pg('일반증상','/nhis/healthin/retrieveDiseVltGnlSymp.do'),pg('어린이','/nhis/healthin/retrieveDiseVltChild.do'), pg('남성','/nhis/healthin/retrieveDiseVltMan.do'),pg('여성','/nhis/healthin/retrieveDiseVltWoman.do')]), ('wbhace05600m01','G',[bd('건강검진','/nhis/healthin/wbhace05600m01.do',4,'어문,이미지,영상'), bd('만성질환','/nhis/healthin/wbhace05800m01.do',1,'어문,이미지,영상'), bd('운동 및 건강강좌','/nhis/healthin/wbhace06800m01.do',8,'어문,이미지,영상')]), ('wbhaec14100m01','F',[pg('강당','/nhis/together/wbhaec14100m01.do'),pg('회의실','/nhis/together/wbhaec14200m01.do'), pg('체육시설','/nhis/together/wbhaec14300m01.do'),pg('주차장','/nhis/together/wbhaec14400m01.do'), pg('문화시설','/nhis/together/wbhaec14500m01.do')]), ('wbhabe08100m01','F',[pg('자세히 알아보기','/nhis/policy/wbhabe08100m01.do'),pg('대상여부 확인','/nhis/policy/wbhabe08200m01.do'), pg('적법요건','/nhis/policy/wbhabe08200m03.do')]), ('wbhaea02200m01','G',[bd('본부','/nhis/together/wbhaea02200m01.do',6648),bd('지역본부·지사','/nhis/together/wbhaea02210m01.do',437)]), ] wb=openpyxl.load_workbook(FN); ws=wb.active MAXC=27 DATA_END=159 # last possible data row to clear up to (use max_row) # effective D,E,F via merges (F also merged in this sheet? F merges exist per ranges) eff={4:{},5:{},6:{}} for col in (4,5,6): for r in range(3,161): eff[col][r]=ws.cell(r,col).value for mr in ws.merged_cells.ranges: if mr.min_col<=col<=mr.max_col and mr.min_row>=3: top=ws.cell(mr.min_row,col).value for r in range(mr.min_row,mr.max_row+1): eff[col][r]=top data_rows=[r for r in range(3,161) if ws.cell(r,2).value is not None] recs=[] for r in data_rows: rec={'src':r,'new':False,'mark':set()} rec['D']=eff[4][r]; rec['E']=eff[5][r]; rec['F']=eff[6][r] for c in range(7,MAXC+1): rec[c]=ws.cell(r,c).value rec['url']=ws.cell(r,11).value hl=ws.cell(r,11).hyperlink; rec['hlink']=hl.target if hl else rec['url'] recs.append(rec) def midx(sub): for i,rc in enumerate(recs): if rc['url'] and sub in str(rc['url']): return i return None # snapshot styles before edit stylesnap={} for r in range(3,161): for c in range(1,MAXC+1): stylesnap[(r,c)]=copy(ws.cell(r,c)._style) out=[] applied=[] i=0 # process in original order; build mapping parent substr->group gmap={g[0]:g for g in GROUPS} for rc in recs: g=None for sub,grp in gmap.items(): if rc['url'] and sub in str(rc['url']): g=grp; break if not g: out.append(rc); continue sub,level,tabs=g first=tabs[0] # reuse parent for first tab if level=='G': rc[7]=first[0] else: # F rc['F']=first[0]; rc[7]=None rc['url']=first[1]; rc['hlink']=first[1]; rc[11]=first[1] rc[12]=first[2]; rc[13]=first[3]; rc[14]=first[4]; rc[15]=first[5] rc['mark'].update([6,7,11,12,13,14,15]) out.append(rc) for t in tabs[1:]: ch={'src':rc['src'],'new':True,'mark':set(range(4,16))} ch['D']=rc['D']; ch['E']=rc['E'] if level=='G': ch['F']=rc['F']; ch[7]=t[0] else: ch['F']=t[0]; ch[7]=None for c in range(8,MAXC+1): ch[c]=None ch[11]=t[1]; ch['url']=t[1]; ch['hlink']=t[1] ch[12]=t[2]; ch[13]=t[3]; ch[14]=t[4]; ch[15]=t[5] out.append(ch) applied.append((sub,len(tabs))) recs=out print('applied groups:', applied, 'final rows:', len(recs)) # WRITE for mr in list(ws.merged_cells.ranges): if mr.min_row>=3: ws.unmerge_cells(str(mr)) SITE='국민건강보험공단' n=len(recs) for i,rc in enumerate(recs): r=3+i; src=rc['src'] for c in range(1,MAXC+1): ws.cell(r,c)._style=copy(stylesnap[(src,c)]) ws.cell(r,1).value=None ws.cell(r,2).value=i+1 ws.cell(r,3).value=SITE ws.cell(r,4).value=rc['D']; ws.cell(r,5).value=rc['E']; ws.cell(r,6).value=rc['F'] for c in range(7,MAXC+1): ws.cell(r,c).value=rc.get(c) kc=ws.cell(r,11); kc.value=rc['url']; kc.hyperlink=rc['hlink'] if rc['url'] else None for c in rc['mark']: ws.cell(r,c).fill=BLUE ws.row_dimensions[r].height=15 for r in range(3+n,161): for c in range(1,MAXC+1): cell=ws.cell(r,c); cell.value=None; cell.hyperlink=None; cell.fill=PatternFill(fill_type=None) def remerge(col, scope): r=3 while r<3+n: v=ws.cell(r,col).value if v is None or v=='': r+=1; continue r2=r while r2+1<3+n: if ws.cell(r2+1,col).value!=v: break ok=True for sc in scope: if ws.cell(r2+1,sc).value!=ws.cell(r,sc).value: ok=False;break if not ok: break r2+=1 if r2>r: for rr in range(r+1,r2+1): ws.cell(rr,col).value=None ws.merge_cells(start_row=r,start_column=col,end_row=r2,end_column=col) r=r2+1 remerge(6,[4,5]); remerge(5,[4]); remerge(4,[]) wb.save(FN) print('saved')