공공기관2 작업 중. _temp 몽타주(재생성가능)는 제외. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
103 lines
3.6 KiB
Python
103 lines
3.6 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""금산군 ui-nav_tabs 재검토 + 군민복지 cross-product 정리 (2026-05-31)
|
||
- PHASE1: ui-nav_tabs 인페이지 탭 페이지 → 1행 유지, M=라이브 탭 개수
|
||
여성가족 05030301=3, 어르신 05030401=3, 사회복지 05030601=5(무변경),
|
||
읍·면 행정복지센터 06X0101 ×10 =2
|
||
- PHASE2: 군민복지(05030701) tab-ul type1 4탭 cross-product(147~159, 13행)
|
||
→ 4행으로 축소(공지사항/금산군자원봉사센터/복지시설/관련사이트). 151~159 삭제.
|
||
"""
|
||
import sys, openpyxl
|
||
from copy import copy
|
||
from openpyxl.utils import range_boundaries
|
||
|
||
PATH = r'D:\01.프로젝트\DB수집\작업파일\광역_사이트맵\충청남도\3.금산군\충청남도_금산군.xlsx'
|
||
WRITE = '--write' in sys.argv
|
||
|
||
wb = openpyxl.load_workbook(PATH)
|
||
ws = wb.active
|
||
MAXC = ws.max_column
|
||
|
||
# ---------- PHASE 1: M 정규화 (URL 매칭) ----------
|
||
MTARGETS = {
|
||
'05030301': 3, '05030401': 3, '05030601': 5,
|
||
'06010101': 2, '06020101': 2, '06030101': 2, '06040101': 2, '06050101': 2,
|
||
'06060101': 2, '06070101': 2, '06080101': 2, '06090101': 2, '06100101': 2,
|
||
}
|
||
print('=== PHASE1: M 정규화 ===')
|
||
for r in range(3, ws.max_row + 1):
|
||
k = ws.cell(r, 11).value
|
||
if not k:
|
||
continue
|
||
ks = str(k)
|
||
for code, mval in MTARGETS.items():
|
||
if code + '.html' in ks:
|
||
old_m = ws.cell(r, 13).value
|
||
old_l = ws.cell(r, 12).value
|
||
ws.cell(r, 13).value = mval
|
||
print(f' row{r} {code} L={old_l} M:{old_m}->{mval}')
|
||
break
|
||
|
||
# ---------- PHASE 2: 군민복지 restructure ----------
|
||
print('=== PHASE2: 군민복지 정리 ===')
|
||
# Step A: 147~150 G<-H, clear H
|
||
for r in range(147, 151):
|
||
g_old = ws.cell(r, 7).value
|
||
h = ws.cell(r, 8).value
|
||
ws.cell(r, 7).value = h
|
||
ws.cell(r, 8).value = None
|
||
print(f' row{r} G:{g_old}->{h} (H clear)')
|
||
|
||
DEL_START, DEL_COUNT = 151, 9
|
||
|
||
# Step B: capture & clear merges
|
||
merges = [str(mc) for mc in ws.merged_cells.ranges]
|
||
for mc in list(ws.merged_cells.ranges):
|
||
ws.unmerge_cells(str(mc))
|
||
|
||
# Step C: manual shift up (delete 151~159)
|
||
max_row = ws.max_row
|
||
for r in range(DEL_START, max_row - DEL_COUNT + 1):
|
||
src = r + DEL_COUNT
|
||
for c in range(1, MAXC + 1):
|
||
s = ws.cell(src, c); d = ws.cell(r, c)
|
||
d.value = s.value
|
||
if s.has_style:
|
||
d._style = copy(s._style)
|
||
d.number_format = s.number_format
|
||
d.hyperlink = None
|
||
if s.hyperlink:
|
||
d.hyperlink = copy(s.hyperlink)
|
||
d.hyperlink.ref = d.coordinate
|
||
for r in range(max_row - DEL_COUNT + 1, max_row + 1):
|
||
for c in range(1, MAXC + 1):
|
||
d = ws.cell(r, c); d.value = None; d.hyperlink = None
|
||
|
||
# Step D: rebuild merges with row mapping
|
||
def surv(x):
|
||
return x < DEL_START or x >= DEL_START + DEL_COUNT
|
||
def mp(x):
|
||
return x if x < DEL_START else x - DEL_COUNT
|
||
for mc in merges:
|
||
c1, r1, c2, r2 = range_boundaries(mc)
|
||
s = [x for x in range(r1, r2 + 1) if surv(x)]
|
||
if not s:
|
||
continue
|
||
nr1, nr2 = mp(min(s)), mp(max(s))
|
||
if nr1 == nr2 and c1 == c2:
|
||
continue # collapsed to single cell, no merge
|
||
ws.merge_cells(start_row=nr1, start_column=c1, end_row=nr2, end_column=c2)
|
||
|
||
# Step E: 순번 재번호 (151행 이후 -9 → 연속성 유지)
|
||
for r in range(DEL_START, ws.max_row + 1):
|
||
v = ws.cell(r, 2).value
|
||
if isinstance(v, int):
|
||
ws.cell(r, 2).value = v - DEL_COUNT
|
||
|
||
print(f' deleted rows {DEL_START}~{DEL_START+DEL_COUNT-1} (9 rows)')
|
||
|
||
if WRITE:
|
||
wb.save(PATH)
|
||
print('SAVED', PATH)
|
||
else:
|
||
print('DRY-RUN (use --write to save)')
|