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