DB_JOB/작업파일/완료/광역_사이트맵/충청북도/_cy3_build.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

115 lines
4.7 KiB
Python

# -*- coding: utf-8 -*-
# 청양 본문탭 누락전개(+29) + 고아행386~390 삭제. 123+ 재구축, 1~122 불변, D/E/F/G 병합재계산.
import openpyxl, json, io, sys, shutil
from copy import copy
from collections import Counter
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
F=r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\충청남도\13.청양군\충청남도_청양군.xlsx'
BK=r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\충청남도\13.청양군\충청남도_청양군_backup_본문탭전개전.xlsx'
shutil.copyfile(F,BK); print('백업',BK)
miss=json.load(open('_cy3_missing.json',encoding='utf-8'))
wb=openpyxl.load_workbook(F); ws=wb.active
NCOL=17; CCOL=3
def style_of(r,c):
cell=ws.cell(r,c)
return dict(font=copy(cell.font),border=copy(cell.border),fill=copy(cell.fill),
alignment=copy(cell.alignment),number_format=cell.number_format,protection=copy(cell.protection))
def apply_style(cell,st):
cell.font=st['font']; cell.border=st['border']; cell.fill=st['fill']
cell.alignment=st['alignment']; cell.number_format=st['number_format']; cell.protection=st['protection']
last=ws.max_row
# 1) 123+ 캡처
ORPHAN=set(range(386,391))
PARENT_B={135:'r133',248:'r243',250:'r246',296:'r291',297:'r292'} # anchor B순번
# anchor별 자식 children(label,url,blank), child col
def childcol(b): return 8 if b in (296,297) else 7
def childlist(b):
key={135:'133',248:'243',250:'246',296:'291',297:'292'}[b]
return miss[key]['miss']
# 부모 값 세팅
PARENT_SET={
135:{'set':{7:'청양사랑기부제 안내'},'L':'페이지'},
250:{'set':{7:'인구증가 시책'}},
296:{'set':{8:'고추'}},
297:{'set':{8:'전통주(구기주/생막걸리)'},'L':'페이지'},
}
rowh=ws.row_dimensions[200].height or 15
old=[]
for r in range(123,last+1):
if r in ORPHAN: continue
b=ws.cell(r,2).value
hl=ws.cell(r,11).hyperlink
rec={'b':b,'vals':{c:ws.cell(r,c).value for c in range(2,NCOL+1)},
'st':{c:style_of(r,c) for c in range(2,NCOL+1)},
'hyper':(hl.target if hl else None)}
# 부모 값/ L 수정
if b in PARENT_SET:
ps=PARENT_SET[b]
for c,v in ps.get('set',{}).items(): rec['vals'][c]=v
if 'L' in ps: rec['vals'][12]=ps['L']
old.append(rec)
# 2) 새 리스트 구성(부모 뒤 자식 삽입)
def copy_st(st):
return dict(font=copy(st['font']),border=copy(st['border']),fill=copy(st['fill']),
alignment=copy(st['alignment']),number_format=st['number_format'],protection=copy(st['protection']))
def make_child(lab,url,blank,col,style_src):
vals={c:None for c in range(2,NCOL+1)}
vals[3]='충청남도 청양군'
vals[col]=lab
vals[11]=url
if blank:
vals[12]='사이트'
else:
vals[12]='페이지'; vals[13]=1; vals[14]='어문'
return {'b':None,'vals':vals,'st':style_src,'hyper':url if url and url.startswith('http') else None,'new':True}
newlist=[]
added=0
for rec in old:
newlist.append(rec)
b=rec['b']
if b in PARENT_B:
col=childcol(b)
# 스타일은 부모행 각 컬럼 스타일 복사
src={c:rec['st'][c] for c in range(2,NCOL+1)}
for x in childlist(b):
newlist.append(make_child(x['lab'],x['absu'],x['blank'],col,{c:copy_st(src[c]) for c in range(2,NCOL+1)}))
added+=1
print('기존123+',len(old),'신규',added,'→ 합',len(newlist))
# 3) 123+ 전체 삭제
ws.delete_rows(123, last-123+1)
# 4) 새 행 쓰기
for i,rec in enumerate(newlist):
r=123+i
for c in range(2,NCOL+1):
cell=ws.cell(r,c); cell.value=rec['vals'][c]; apply_style(cell,rec['st'][c])
ws.row_dimensions[r].height=rowh
u=rec['hyper']
if u: ws.cell(r,11).hyperlink=u
newlast=122+len(newlist)
print('새 max data row',newlast)
# 5) 병합 재계산 D/E/F/G (4~7), 123+만
keep=[m for m in ws.merged_cells.ranges if not (m.min_row>=123 and m.min_col in (4,5,6,7))]
# delete_rows가 123+ D/E/F 병합 제거했지만 잔여 가능 → 명시적 정리
for m in list(ws.merged_cells.ranges):
if m.min_row>=123 and m.min_col in (4,5,6,7):
ws.unmerge_cells(str(m))
def has_val(r,c):
v=ws.cell(r,c).value
return v is not None and str(v).strip()!=''
for c in range(4,8): # D,E,F,G
r=123
while r<=newlast:
if has_val(r,c):
end=newlast
for r2 in range(r+1,newlast+1):
if any(has_val(r2,cc) for cc in range(4,c+1)):
end=r2-1; break
if end>r: ws.merge_cells(start_row=r,start_column=c,end_row=end,end_column=c)
r=end+1
else:
r+=1
wb.save(F)
print('저장 완료')
d=Counter(ws.cell(r,12).value for r in range(123,newlast+1))
print('123+ L분포',dict(d))