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

67 lines
2.7 KiB
Python

# -*- coding: utf-8 -*-
# 괴산 _gs_nodes.json → 엑셀 재구성 (전주 빌더 패턴: 템플릿스타일 보존 + prefix-run 병합)
import openpyxl, json, sys, copy, datetime, io
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
DIR=r'1.괴산군'
F=DIR+r'\충청북도_괴산군.xlsx'
SITE='충청북도 괴산군'
import shutil
shutil.copyfile(F, F.replace('.xlsx','_backup_재구축전.xlsx'))
nodes=json.load(open('_gs_nodes.json',encoding='utf-8'))
# rows: path + L/M/N/O
rows=[]
for n in nodes:
path=[x for x in n['d'] if x]
if not path: continue
L=n['kind']
M=n['M'] if L=='게시판' else (1 if L=='페이지' else None)
O=''
if n.get('O'): O=','.join('%d유형'%t for t in n['O'])
else: O='미부착' if L in ('페이지','게시판') else None
rows.append({'path':path,'url':n['url'],'L':L,'M':M,'N':('어문' if L in('페이지','게시판') else None),'O':O})
print('빌드행',len(rows))
wb=openpyxl.load_workbook(F); ws=wb.active
TPL={}
for c in range(1,28):
s=ws.cell(3,c)
TPL[c]=dict(font=copy.copy(s.font),fill=copy.copy(s.fill),border=copy.copy(s.border),
align=copy.copy(s.alignment),numfmt=s.number_format)
keep={'B1:R1','Y1:AA1','S1:W1'}
for rng in list(ws.merged_cells.ranges):
if str(rng) not in keep: ws.unmerge_cells(str(rng))
for r in range(3,ws.max_row+1):
for c in range(1,28): ws.cell(r,c).value=None
def setcell(r,c,val):
cell=ws.cell(r,c); cell.value=val; t=TPL[c]
cell.font=copy.copy(t['font']); cell.fill=copy.copy(t['fill'])
cell.border=copy.copy(t['border']); cell.alignment=copy.copy(t['align']); cell.number_format=t['numfmt']
TODAY=datetime.date(2026,6,6)
LEVELCOL={0:4,1:5,2:6,3:7,4:8}
r0=3
for i,rec in enumerate(rows):
r=r0+i
setcell(r,2,i+1); setcell(r,3,SITE)
for idx in range(5): setcell(r,LEVELCOL[idx],None)
setcell(r,9,None); setcell(r,10,None)
setcell(r,11,rec['url']); setcell(r,12,rec['L'])
setcell(r,13,rec['M'] if rec['M'] not in('',None) else None)
setcell(r,14,rec['N']); setcell(r,15,rec['O'])
for c in (16,17,18,19,20,21,22,23,24): setcell(r,c,None)
setcell(r,25,None); setcell(r,26,None); setcell(r,27,None)
ws.row_dimensions[r].height=15
N=len(rows)
for idx in range(5):
col=LEVELCOL[idx]; i=0
while i<N:
if len(rows[i]['path'])<=idx: i+=1; continue
pref=tuple(rows[i]['path'][:idx+1]); j=i
while j+1<N and len(rows[j+1]['path'])>idx and tuple(rows[j+1]['path'][:idx+1])==pref: j+=1
ws.cell(r0+i,col).value=rows[i]['path'][idx]
if j>i: ws.merge_cells(start_row=r0+i,start_column=col,end_row=r0+j,end_column=col)
i=j+1
wb.save(F)
from collections import Counter
print('저장:',F,'| 행',N,'| L',dict(Counter(x['L'] for x in rows)))