# -*- coding: utf-8 -*- import openpyxl, copy, json, io, re from openpyxl.utils import get_column_letter from openpyxl.styles import PatternFill from openpyxl.worksheet.hyperlink import Hyperlink PATH = '한국지역난방공사.xlsx' BLUE = PatternFill(fgColor='FFBDD7EE', fill_type='solid') ORG = '한국지역난방공사' def menuno(u): m = re.search(r'menuNo=(\d+)', u or '') return m.group(1) if m else None wb = openpyxl.load_workbook(PATH) ws = wb.active merges = list(ws.merged_cells.ranges) def eff(r, c): v = ws.cell(r, c).value if v is not None: return v for m in merges: if m.min_row <= r <= m.max_row and m.min_col <= c <= m.max_col: return ws.cell(m.min_row, m.min_col).value return None def mtop(r, c): for m in merges: if m.min_row <= r <= m.max_row and m.min_col <= c <= m.max_col: return (m.min_row, m.min_col) return (r, c) DATA0 = ws.max_row COLS = range(2, 28) # B..AA orig = [] for r in range(3, DATA0 + 1): rec = {'path': [eff(r, c) for c in range(4, 11)], 'vals': {c: ws.cell(r, c).value for c in COLS}, 'klink': (ws.cell(r, 11).hyperlink.target if ws.cell(r, 11).hyperlink else None), 'styles': {c: copy.copy(ws.cell(*mtop(r, c))._style) for c in COLS}, 'rowh': ws.row_dimensions[r].height, 'r0': r, 'new': False, 'newcells': set()} orig.append(rec) tmpl = {c: copy.copy(ws.cell(*mtop(3, c))._style) for c in COLS} def newrec(path, K=None, L=None, M=None, N=None, O='미부착', site=False): v = {c: None for c in COLS} v[3] = ORG if K is not None: v[11] = K if site: v[12] = '사이트' else: v[12] = L; v[13] = M; v[14] = N; v[15] = O return {'path': list(path) + [None] * (7 - len(path)), 'vals': v, 'klink': K, 'styles': None, 'rowh': None, 'new': True, 'newcells': set()} plan = json.load(io.open('_plan.json', encoding='utf-8')) g7M = json.load(io.open('_g7M.json', encoding='utf-8')) OV = { '200106': ('페이지', 1, '어문'), '200276': ('페이지', 1, '어문'), '200091': ('페이지', 1, '어문'), '200127': ('게시판', 0, '어문,이미지'), '200427': ('게시판', 0, '어문,이미지'), } plan_by_anchor = {p.get('anchor_row'): p for p in plan if 'anchor_row' in p} g7 = [p for p in plan if p['type'] == 'categoryboard'][0] OUT = [] for rec in orig: p = plan_by_anchor.get(rec['r0']) if rec['r0'] == 11: cats = g7['tabs'] url0 = "https://www.kdhc.co.kr/kdhc/infoOthbc/infoPrmlgt/list.do?searchPublictRealmCd=G01&menuNo=200013" rec['path'][3] = cats[0] rec['vals'][11] = url0; rec['klink'] = url0 rec['vals'][12] = '게시판'; rec['vals'][13] = g7M['cats']['G01'][0] rec['vals'][14] = '어문'; rec['vals'][15] = '미부착' rec['newcells'] = {7, 11, 13} OUT.append(rec) base = rec['path'][:3] for i in range(2, 9): code = 'G0%d' % i url = "https://www.kdhc.co.kr/kdhc/infoOthbc/infoPrmlgt/list.do?searchPublictRealmCd=%s&menuNo=200013" % code OUT.append(newrec(base + [cats[i - 1]], K=url, L='게시판', M=g7M['cats'][code][0], N='어문')) continue if p and p['type'] in ('child', 'sibling'): if p['type'] == 'child': rec['path'][3] = p['self'] rec['newcells'] = {7} OUT.append(rec) base = rec['path'][:3] for it in p['new']: L, M, N = it['L'], it['M'], it['N']; mn = it['menuNo'] if mn in OV: L, M, N = OV[mn] site = (L == '사이트') OUT.append(newrec(base + [it['label']], K=it['url'], L=L, M=M, N=N, site=site)) else: OUT.append(rec) base = rec['path'][:2] for it in p['new']: L, M, N = it['L'], it['M'], it['N']; mn = it['menuNo'] if mn in OV: L, M, N = OV[mn] site = (L == '사이트') OUT.append(newrec(base + [it['label']], K=it['url'], L=L, M=M, N=N, site=site)) else: OUT.append(rec) # unmerge data merges for m in list(ws.merged_cells.ranges): if m.min_row >= 3: ws.unmerge_cells(str(m)) endrow = max(DATA0, 2 + len(OUT)) for r in range(3, endrow + 1): for c in COLS: cell = ws.cell(r, c); cell.value = None; cell.hyperlink = None for i, rec in enumerate(OUT): rr = 3 + i for k in range(7): ws.cell(rr, 4 + k).value = rec['path'][k] ws.cell(rr, 2).value = i + 1 ws.cell(rr, 3).value = ORG for c in range(11, 28): ws.cell(rr, c).value = rec['vals'].get(c) if rec['klink']: ws.cell(rr, 11).hyperlink = Hyperlink(ref='K%d' % rr, target=rec['klink']) for c in COLS: if rec['new']: ws.cell(rr, c)._style = copy.copy(tmpl[c]) else: ws.cell(rr, c)._style = copy.copy(rec['styles'][c]) # K hyperlink style only if there is a url if rec['vals'].get(11): ws.cell(rr, 11)._style = copy.copy(tmpl[11]) else: ws.cell(rr, 11)._style = copy.copy(tmpl[12]) if rec.get('rowh'): ws.row_dimensions[rr].height = rec['rowh'] if rec['new']: for c in range(4, 16): ws.cell(rr, c).fill = copy.copy(BLUE) elif rec.get('newcells'): for c in rec['newcells']: ws.cell(rr, c).fill = copy.copy(BLUE) NROW = 2 + len(OUT) def make_merges(): # D-J filled in every row; merge maximal runs where (D..c) tuple equal & value non-empty for c in range(4, 11): r = 3 while r <= NROW: v = ws.cell(r, c).value if v in (None, ''): r += 1; continue key = tuple(ws.cell(r, pc).value for pc in range(4, c + 1)) r2 = r while r2 + 1 <= NROW and tuple(ws.cell(r2 + 1, pc).value for pc in range(4, c + 1)) == key: r2 += 1 if r2 > r: # blank the non-top cells then merge for rr in range(r + 1, r2 + 1): ws.cell(rr, c).value = None ws.merge_cells(start_row=r, start_column=c, end_row=r2, end_column=c) r = r2 + 1 make_merges() wb.save(PATH) print('OUT rows:', len(OUT), 'final last row:', NROW)