DB_JOB/작업파일/공공기관2/10.한국지역난방공사/_plan.py
hehihoho3 b0acd1e705 백업: 셀병합 정상화(D~J)+KDHC 옵션2/행높이17, 오늘(06-21) 제출 17곳 검수·압축
- 공공기관2/3 작업본 + 오늘 제출 17곳 D~J 카테고리 셀병합 정상화
- 한국지역난방공사 옵션2(고아셀 F98 수정)+전행 높이17
- 제출_프리랜서2_2026-06-21.zip 생성(17개 xlsx, 2,468행)

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

73 lines
3.0 KiB
Python

import json,io,openpyxl
from openpyxl.utils import get_column_letter
wb=openpyxl.load_workbook('한국지역난방공사.xlsx'); ws=wb.active
merges=list(ws.merged_cells.ranges)
def eff(r,c):
v=ws.cell(r,c).value
if v is not None: return v
for m in merges:
if m.min_row<=r<=m.max_row and m.min_col<=c<=m.max_col:
return ws.cell(m.min_row,m.min_col).value
return None
def leafcol(r):
last=None
for c in range(4,11):
if eff(r,c) not in (None,''): last=c
return last
groups=json.load(io.open('_tabgroups.json',encoding='utf-8'))
bM=json.load(io.open('_newboardM.json',encoding='utf-8'))
def host_external(url):
return ('/cyb/' in url) or ('kdhc.co.kr/kdhc/' not in url)
def classify(t):
url=t['url']; mn=t['menuNo']
if mn is None or host_external(url):
return ('사이트',None,None)
if t['board']:
info=bM.get(url)
if info:
M,tag=info['M']
if M in (0,) or (isinstance(M,str)):
return ('게시판',0,'없음') # may override
return ('게시판',M,'어문')
return ('게시판',0,'없음')
return ('페이지',1,'어문')
plan=[]
for gi,g in enumerate(groups):
anchor=[t for t in g if t['active']]
note=''
if not anchor:
# category board (G7 사전정보공표): all same menuNo
mns=set(t['menuNo'] for t in g)
plan.append({'gi':gi,'type':'categoryboard','mns':list(mns),'tabs':[t['label'] for t in g]})
continue
a=anchor[0]
if not a['sheet_rows']:
plan.append({'gi':gi,'type':'active_not_in_sheet','self':a['label']}); continue
r=a['sheet_rows'][0]; lc=leafcol(r); leaf=eff(r,lc)
sib = (a['label']==leaf)
news=[t for t in g if not t['in_sheet']]
# also any OTHER present tabs (already in sheet as own rows) -> note
others=[t for t in g if t['in_sheet'] and not t['active']]
items=[]
for t in news:
L,M,N=classify(t)
items.append({'label':t['label'],'menuNo':t['menuNo'],'url':t['url'],'L':L,'M':M,'N':N})
plan.append({'gi':gi,'type':'sibling' if sib else 'child',
'anchor_row':r,'leafcol':get_column_letter(lc),'leaf':leaf,'self':a['label'],
'others_in_sheet':[(t['label'],t['sheet_rows']) for t in others],
'new':items})
io.open('_plan.json','w',encoding='utf-8').write(json.dumps(plan,ensure_ascii=False,indent=1))
# readable
L=[]
for p in plan:
if p['type'] in ('categoryboard','active_not_in_sheet'):
L.append(f"G{p['gi']} [{p['type']}] {p}"); continue
L.append(f"G{p['gi']} [{p['type']}] anchor r{p['anchor_row']} {p['leafcol']}={p['leaf']!r} self={p['self']!r}")
if p['others_in_sheet']: L.append(f" others_already_in_sheet={p['others_in_sheet']}")
for it in p['new']:
L.append(f" + {it['L']:3} M={str(it['M']):>4} N={it['N'] or '':4} | {it['label']} (menuNo={it['menuNo']})")
io.open('_plan.txt','w',encoding='utf-8').write('\n'.join(L))
print('groups planned:',len(plan))
print('total new rows:',sum(len(p.get('new',[])) for p in plan))