공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
115 lines
4.7 KiB
Python
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))
|