import openpyxl, copy from openpyxl.styles import PatternFill from openpyxl.worksheet.hyperlink import Hyperlink FN="제주특별자치도_교육청.xlsx" wb=openpyxl.load_workbook(FN); ws=wb.active MAXCOL=27 SKY="FFBDD7EE" def find_row_by_menucd(mc): for r in range(3, ws.max_row+1): k=ws.cell(r,11).value if k and ("menuCd="+mc) in str(k) and "boardId=" not in str(k): return r return None # 1) M = tab count for PAGE rows for mc,cnt in [("DOM_000000101002001000",4),("DOM_000000104002007000",4)]: r=find_row_by_menucd(mc); assert r, mc print(f"M update r{r}: {ws.cell(r,13).value} -> {cnt}"); ws.cell(r,13).value=cnt # record + unmerge all merges=[(m.min_col,m.min_row,m.max_col,m.max_row) for m in ws.merged_cells.ranges] for m in list(ws.merged_cells.ranges): ws.unmerge_cells(str(m)) def insert_row_at(P, style_src_row): for r in range(ws.max_row, P-1, -1): for c in range(1, MAXCOL+1): src=ws.cell(r,c); dst=ws.cell(r+1,c) dst.value=src.value if src.has_style: dst._style=copy.copy(src._style) if c==11: dst.hyperlink=src.hyperlink; src.hyperlink=None src.value=None ssr = style_src_row+1 if style_src_row>=P else style_src_row for c in range(1, MAXCOL+1): cell=ws.cell(P,c); cell.value=None; cell.hyperlink=None s=ws.cell(ssr,c) if s.has_style: cell._style=copy.copy(s._style) # shift recorded merges for i,(c1,r1,c2,r2) in enumerate(merges): if r1>=P: r1+=1 if r2>=P: r2+=1 merges[i]=(c1,r1,c2,r2) def set_new(P, F, url, M): ws.cell(P,3).value="제주특별자치도교육청" ws.cell(P,6).value=F kc=ws.cell(P,11); kc.value=url; kc.hyperlink=Hyperlink(ref=kc.coordinate, target=url) ws.cell(P,12).value="게시판"; ws.cell(P,13).value=M ws.cell(P,14).value="어문"; ws.cell(P,15).value="미부착" for c in range(4,18): ws.cell(P,c).fill=PatternFill(start_color=SKY,end_color=SKY,fill_type="solid") # 2) inserts (top-down with shift bookkeeping) r_jp=find_row_by_menucd("DOM_000000101002001000"); P1=r_jp+1 insert_row_at(P1, style_src_row=r_jp) set_new(P1,"자료실","https://www.jje.go.kr/board/list.jje?boardId=BBS_0000544&menuCd=DOM_000000101002004000",175) print("inserted 전편입학 자료실 at r",P1) r_gj=find_row_by_menucd("DOM_000000101003001000"); P2=r_gj+1 insert_row_at(P2, style_src_row=r_gj) set_new(P2,"자료실","https://www.jje.go.kr/board/list.jje?boardId=BBS_0000007&menuCd=DOM_000000101003003000",60) print("inserted 검정고시 자료실 at r",P2) # re-merge for c1,r1,c2,r2 in merges: ws.merge_cells(start_row=r1,start_column=c1,end_row=r2,end_column=c2) # 3) rebuild K hyperlinks from values fixed=0 for r in range(3, ws.max_row+1): kc=ws.cell(r,11); v=kc.value if isinstance(v,str) and v.startswith("http"): tgt=kc.hyperlink.target if kc.hyperlink else None if tgt!=v: kc.hyperlink=Hyperlink(ref=kc.coordinate,target=v); fixed+=1 print("K hyperlink fixed:",fixed) wb.save(FN); print("saved. max_row=",ws.max_row)