DB_JOB/작업파일/완료/공공기관/23.국민건강보험공단/_nhis_tabexpand.py
hehihoho3 df16c98366 백업: DB수집 전체 스냅샷 (공공기관2 정리 전)
공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 18:15:40 +09:00

141 lines
5.8 KiB
Python

# -*- 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')