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