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

59 lines
2.6 KiB
Python

# -*- coding: utf-8 -*-
# 범용 빌더: python _cb_build.py <엑셀경로> <nodes.json> <사이트명>
import openpyxl, json, sys, copy, io, shutil
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')
F=sys.argv[1]; NODES=sys.argv[2]; SITE=sys.argv[3]
shutil.copyfile(F, F.replace('.xlsx','_backup_재구축전.xlsx'))
nodes=json.load(open(NODES,encoding='utf-8'))
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)
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})
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']
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 range(16,28): setcell(r,c,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
# 트레일링 빈행 삭제
lastdata=r0+N-1
if ws.max_row>lastdata: ws.delete_rows(lastdata+1, ws.max_row-lastdata)
wb.save(F)
from collections import Counter
print('저장',F,'| 행',N,'| L',dict(Counter(x['L'] for x in rows)))