- 공공기관2/3 작업본 + 오늘 제출 17곳 D~J 카테고리 셀병합 정상화 - 한국지역난방공사 옵션2(고아셀 F98 수정)+전행 높이17 - 제출_프리랜서2_2026-06-21.zip 생성(17개 xlsx, 2,468행) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
81 lines
3.9 KiB
Python
81 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""성과관리교육>교육신청(사이트), 홍보영상>홍보영상(PR)/인포그래픽영상(PR2) 신규 자식탭 G레벨 삽입.
|
|
self탭(교육과정안내·브랜드필름)=부모 동일URL이라 중복 안 만들고 신규URL 탭만 추가. 스타일 보존·B재부번."""
|
|
import openpyxl, shutil, copy as _copy
|
|
from openpyxl.styles import PatternFill, Font
|
|
BLUE=PatternFill('solid',fgColor='FFBDD7EE',bgColor='FFBDD7EE')
|
|
SRC='한국조세재정연구원.xlsx'
|
|
shutil.copy(SRC,'한국조세재정연구원_backup_tab2전.xlsx')
|
|
wb=openpyxl.load_workbook(SRC); ws=wb.active
|
|
maxr=ws.max_row
|
|
def data_row(r): return any(ws.cell(r,c).value not in (None,'') for c in range(2,18))
|
|
eff={}
|
|
for r in range(3,maxr+1):
|
|
for c in range(4,7): eff[(r,c)]=ws.cell(r,c).value
|
|
for m in list(ws.merged_cells.ranges):
|
|
if m.min_row>=3 and 4<=m.min_col<=6:
|
|
top=ws.cell(m.min_row,m.min_col).value
|
|
for rr in range(m.min_row,m.max_row+1): eff[(rr,m.min_col)]=top
|
|
rows=[]
|
|
for r in range(3,maxr+1):
|
|
if not data_row(r): continue
|
|
sty={c:(_copy.copy(ws.cell(r,c).font),_copy.copy(ws.cell(r,c).fill),
|
|
_copy.copy(ws.cell(r,c).border),_copy.copy(ws.cell(r,c).alignment)) for c in range(2,18)}
|
|
rec={'vals':{c:ws.cell(r,c).value for c in range(2,18)},
|
|
'D':eff.get((r,4)),'E':eff.get((r,5)),'F':eff.get((r,6)),
|
|
'hl':ws.cell(r,11).hyperlink.target if ws.cell(r,11).hyperlink else None,
|
|
'sty':sty,'h':ws.row_dimensions[r].height}
|
|
rec['vals'][4]=rec['D']; rec['vals'][5]=rec['E']; rec['vals'][6]=rec['F']
|
|
rows.append(rec)
|
|
tmpl=rows[0]['sty']
|
|
def childrec(parent,G,url,L,M,N,O='미부착'):
|
|
cv={2:None,3:'한국조세재정연구원',4:parent['D'],5:parent['E'],6:parent['F'],7:G,8:None,9:None,10:None,
|
|
11:url,12:L,13:M,14:N,15:O if L!='사이트' else None,16:None,17:None}
|
|
return {'vals':cv,'D':parent['D'],'E':parent['E'],'F':parent['F'],'hl':url,
|
|
'sty':{c:(_copy.copy(t[0]),_copy.copy(t[1]),_copy.copy(t[2]),_copy.copy(t[3])) for c,t in tmpl.items()},
|
|
'h':parent['h'],'NEW':True}
|
|
new=[]
|
|
for rec in rows:
|
|
new.append(rec)
|
|
K=str(rec['vals'].get(11) or '')
|
|
if rec['F']=='성과관리교육' and 'CurriculumGuide' in K and (rec['vals'][7] in (None,'')):
|
|
new.append(childrec(rec,'교육신청','https://www.kipf.re.kr/cpem/education/EduDateInfo/cpEduApp/1/list.do',
|
|
'사이트',None,None))
|
|
if rec['F']=='홍보영상' and 'About_PR3' in K and (rec['vals'][7] in (None,'')):
|
|
new.append(childrec(rec,'홍보영상','https://www.kipf.re.kr/kor/About_PR.do','페이지',1,'어문,영상'))
|
|
new.append(childrec(rec,'인포그래픽영상','https://www.kipf.re.kr/bbs/kor_About_PR2.do','게시판',2,'어문,영상'))
|
|
print('원본',len(rows),'-> 확장',len(new))
|
|
|
|
# wipe & rewrite
|
|
for m in list(ws.merged_cells.ranges):
|
|
if m.min_row>=3: ws.unmerge_cells(str(m))
|
|
for r in range(3,maxr+8):
|
|
for c in range(2,28):
|
|
cc=ws.cell(r,c); cc.value=None; cc.hyperlink=None; cc.fill=PatternFill(); cc.font=Font()
|
|
r=3
|
|
for i,rec in enumerate(new,1):
|
|
for c in range(2,18):
|
|
cell=ws.cell(r,c); cell.value=rec['vals'].get(c)
|
|
f,fi,bo,al=rec['sty'][c]; cell.font=f; cell.fill=fi; cell.border=bo; cell.alignment=al
|
|
ws.cell(r,2).value=i
|
|
if rec.get('hl'):
|
|
ws.cell(r,11).hyperlink=rec['hl']; ws.cell(r,11).font=Font(color='0000FF',underline='single')
|
|
if rec.get('NEW'):
|
|
for c in range(2,18): ws.cell(r,c).fill=BLUE
|
|
if rec.get('h'): ws.row_dimensions[r].height=rec['h']
|
|
r+=1
|
|
last=r-1
|
|
for col in (4,5,6):
|
|
rr=3
|
|
while rr<=last:
|
|
v=ws.cell(rr,col).value
|
|
if v in (None,''): rr+=1; continue
|
|
r2=rr
|
|
while r2+1<=last and ws.cell(r2+1,col).value==v: r2+=1
|
|
if r2>rr:
|
|
for x in range(rr+1,r2+1): ws.cell(x,col).value=None
|
|
ws.merge_cells(start_row=rr,start_column=col,end_row=r2,end_column=col)
|
|
rr=r2+1
|
|
wb.save(SRC)
|
|
print(f'저장. 행수={last-2}')
|