import sys, io, os, json, shutil sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') import openpyxl from openpyxl.styles import Alignment from copy import copy TPL = r'D:\01.프로젝트\DB수집\자료_취합_예시.xlsx' OUT = r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\전북특별자치도\11.장수군\전북특별자치도_장수군.xlsx' BK = OUT.replace('.xlsx', '_backup_재수집전.xlsx') if not os.path.exists(BK): shutil.copy2(OUT, BK); print('backup ->', os.path.basename(BK)) data = json.load(open(r'D:\01.프로젝트\DB수집\작업파일\_스크립트\_jangsu_rows.json', encoding='utf-8')) rows = [r for r in data['rows'] if r['D']] # 빈 대분류(107/108/303) 제외 print('빌드 행수:', len(rows), '(제외', len(data['rows'])-len(rows), ')') # 템플릿 헤더 복사 → 새 워크북 wb = openpyxl.load_workbook(TPL) ws = wb.active ws.title = '11_장수군' # 템플릿 잔존 병합 제거 (헤더 3개만 보존) — 행삭제 전에 KEEP = {'B1:R1', 'S1:W1', 'Y1:AA1'} for m in [str(x) for x in ws.merged_cells.ranges]: if m not in KEEP: ws.unmerge_cells(m) # 헤더(1~2행) 외 기존 샘플행 삭제 if ws.max_row > 2: ws.delete_rows(3, ws.max_row-2) CEN = Alignment(horizontal='center', vertical='center', wrap_text=True) LEFT = Alignment(horizontal='left', vertical='center', wrap_text=False) THIN_from = ws.cell(2,2) # 헤더 스타일 참고 안함; 기본 테두리는 양식 따름 r0 = 3 for i, row in enumerate(rows): r = r0 + i ws.cell(r, 2, i+1) # B 순번 ws.cell(r, 3, '전북특별자치도 장수군') # C 사이트명 ws.cell(r, 4, row['D']) # D 대 ws.cell(r, 5, row['E']) # E 중 ws.cell(r, 6, row['F']) # F 소 ws.cell(r, 7, row['G']) # G 세부/탭 kc = ws.cell(r, 11, row['K']); kc.hyperlink = row['K'] # K ws.cell(r, 12, row['L']) # L ws.cell(r, 13, row['M']) # M ws.cell(r, 14, row['N']) # N ws.cell(r, 15, row['O']) # O ws.row_dimensions[r].height = 15 for c in (4,5,6,7): ws.cell(r, c).alignment = CEN ws.cell(r, 11).alignment = LEFT for c in (2,3,13,14,15): ws.cell(r, c).alignment = Alignment(horizontal='center', vertical='center') last = r0 + len(rows) - 1 # 병합: D(대) / E(중,D내) / F(소,D+E내) — 연속 동일 구간. G無. def merge_runs(col, keyfn): s = r0 for r in range(r0+1, last+2): if r > last or keyfn(r) != keyfn(s): if r-1 > s: ws.merge_cells(start_row=s, start_column=col, end_row=r-1, end_column=col) s = r def kD(r): return ws.cell(r,4).value def kE(r): return (ws.cell(r,4).value, ws.cell(r,5).value) def kF(r): return (ws.cell(r,4).value, ws.cell(r,5).value, ws.cell(r,6).value) merge_runs(6, kF) # F 먼저 merge_runs(5, kE) merge_runs(4, kD) # D 마지막 (매뉴얼 1-6: F→E→D) wb.save(OUT) from collections import Counter print('저장 완료:', OUT) print('대분류:', list(dict.fromkeys(r['D'] for r in rows))) print('L분포:', dict(Counter(r['L'] for r in rows)), '| 총행', len(rows))