107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""한국의료분쟁조정중재원 빡센검수: 구조검사 + 전체내용덤프 (읽기전용)"""
|
|
import openpyxl
|
|
from openpyxl.utils import get_column_letter
|
|
|
|
PATH = r'D:/01.프로젝트/DB수집/작업파일/공공기관3/2.한국의료분쟁조정중재원/한국의료분쟁조정중재원.xlsx'
|
|
wb = openpyxl.load_workbook(PATH, data_only=True)
|
|
ws = wb.active
|
|
print('=== SHEET:', ws.title, '| dim:', ws.dimensions, '| max_row:', ws.max_row, '===')
|
|
|
|
# 병합 목록
|
|
merges = sorted([str(m) for m in ws.merged_cells.ranges])
|
|
print('\n=== MERGES (%d) ===' % len(merges))
|
|
print(', '.join(merges))
|
|
|
|
# 행높이 / 채움색 비정상 체크
|
|
print('\n=== ROW HEIGHTS != 17 (1..max) ===')
|
|
bad_h = []
|
|
for r in range(1, ws.max_row+1):
|
|
h = ws.row_dimensions[r].height
|
|
if h is not None and abs(h-17) > 0.5:
|
|
bad_h.append('%d:%s' % (r, h))
|
|
print(bad_h if bad_h else 'all ~17 or default')
|
|
print('defaultRowHeight=', ws.sheet_format.defaultRowHeight)
|
|
|
|
print('\n=== FILL (3행~끝 채움색 있는 셀) ===')
|
|
fills = []
|
|
for r in range(3, ws.max_row+1):
|
|
for c in range(1, 28):
|
|
cell = ws.cell(r, c)
|
|
f = cell.fill
|
|
if f and f.fill_type and f.fill_type != 'none':
|
|
fg = f.fgColor.rgb if f.fgColor else None
|
|
fills.append('%s%d=%s' % (get_column_letter(c), r, fg))
|
|
print(('%d cells: ' % len(fills)) + ', '.join(fills[:60]) if fills else 'none')
|
|
|
|
# B 연속성
|
|
print('\n=== B 순번 ===')
|
|
bvals = []
|
|
for r in range(3, ws.max_row+1):
|
|
v = ws.cell(r, 2).value
|
|
bvals.append((r, v))
|
|
ints = [(r,v) for r,v in bvals if isinstance(v, int)]
|
|
print('정수B 개수:', len(ints), '| 첫행 B=', ints[0] if ints else None, '| 끝 B=', ints[-1] if ints else None)
|
|
seq = [v for r,v in ints]
|
|
gaps = [seq[i] for i in range(1,len(seq)) if seq[i] != seq[i-1]+1]
|
|
print('비연속(이전+1 아님) 값:', gaps if gaps else '없음(연속)')
|
|
nonint = [(r,v) for r,v in bvals if v is not None and not isinstance(v,int)]
|
|
print('비정수 B:', nonint if nonint else '없음')
|
|
|
|
# 전체 내용 덤프 B..Q
|
|
print('\n=== CONTENT DUMP (행: B|C|D|E|F|G|H|I|J | K(url) | L|M|N|O|P|Q) ===')
|
|
cols = list(range(2, 18)) # B..Q
|
|
for r in range(3, ws.max_row+1):
|
|
vals = [ws.cell(r, c).value for c in cols]
|
|
if all(v is None for v in vals):
|
|
continue
|
|
b,c_,d,e,f,g,h,i,j,k,l,m,n,o,p,q = vals
|
|
menu = ' > '.join([str(x) for x in [d,e,f,g,h,i,j] if x not in (None,'')])
|
|
def s(x): return '' if x is None else str(x)
|
|
print('r%d B=%s | %s | K=%s | L=%s M=%s N=%s O=%s P=%s Q=%s' % (
|
|
r, s(b), menu, s(k)[:70], s(l), s(m), s(n), s(o), s(p), s(q)))
|
|
|
|
# K 이상
|
|
print('\n=== K(URL) 이상 (빈/javascript/#) ===')
|
|
kbad = []
|
|
for r in range(3, ws.max_row+1):
|
|
if ws.cell(r,2).value is None and all(ws.cell(r,c).value is None for c in range(4,11)):
|
|
continue
|
|
k = ws.cell(r, 11).value
|
|
ks = '' if k is None else str(k).strip()
|
|
if ks=='' or ks.startswith('javascript:') or ks=='#':
|
|
# L=사이트 아닌데 K빈 → 문제. L 확인
|
|
l = ws.cell(r,12).value
|
|
kbad.append('r%d K=%r L=%r' % (r, ks, l))
|
|
print(kbad if kbad else '없음')
|
|
|
|
# N 값 분포
|
|
print('\n=== N(저작물유형) 분포 ===')
|
|
from collections import Counter
|
|
ncnt = Counter()
|
|
for r in range(3, ws.max_row+1):
|
|
n = ws.cell(r,14).value
|
|
if n is not None and str(n).strip():
|
|
ncnt[str(n).strip()] += 1
|
|
for k,v in ncnt.most_common():
|
|
print(' %s: %d' % (k, v))
|
|
|
|
# L 값 분포 / O 분포
|
|
print('\n=== L(게시판형태) 분포 ===')
|
|
lcnt = Counter()
|
|
for r in range(3, ws.max_row+1):
|
|
l = ws.cell(r,12).value
|
|
if l is not None and str(l).strip():
|
|
lcnt[str(l).strip()] += 1
|
|
for k,v in lcnt.most_common():
|
|
print(' %s: %d' % (k, v))
|
|
print('=== O(공공누리) 분포 ===')
|
|
ocnt = Counter()
|
|
for r in range(3, ws.max_row+1):
|
|
o = ws.cell(r,15).value
|
|
if o is not None and str(o).strip():
|
|
ocnt[str(o).strip()] += 1
|
|
for k,v in ocnt.most_common():
|
|
print(' %s: %d' % (k, v))
|
|
print('\nDONE')
|