fix(xlsx): tabular 헤더 자동판정 강화 — 비병합 제목행을 헤더로 잡지 않기 - #335
Hidden character warning
Conversation
- _detect_header: '가로병합 없는 첫 행=헤더' 로직에 성긴 배너행 스킵 추가.
3열 이상 && 채워진 칸이 절반 미만이면 제목행(title)으로 보고 다음 행 탐색.
('□ 제조업 등' 같은 비병합 단일셀 제목행이 헤더로 오인되던 문제 수정)
- load_tables flatten: 세로병합 ffill 로 상위·leaf 가 같은 라벨인 컬럼의
'연번_연번' 중복을 연속 중복 제거로 접음.
- 2열 이하 표는 기존 동작 유지(기존 테스트 보존).
- 유닛 7개 추가(배너 스킵/빈칸 헤더 비스킵/다중배너/배너+계층/2열 레거시/
override 우선/세로병합 중복접기). 실제 SIF 원본으로 두 시트 정상 검증.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
📝 WalkthroughWalkthroughXLSX tabular 처리에서 3열 이상인 표의 희소한 비병합 행을 제목행으로 분류하고, 완전히 채워진 행을 실제 헤더로 선택한다. 계층 헤더 flattening에서는 연속 중복 라벨을 제거하며 관련 동작을 단위 테스트로 검증한다. ChangesXLSX 헤더 자동 판정 및 중복 제거
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant XLSXInput
participant load_tables
participant _detect_header
participant HeaderFlattener
participant ParsedTable
XLSXInput->>load_tables: 테이블 데이터 제공
load_tables->>_detect_header: 헤더 후보 판정
_detect_header-->>load_tables: title_rows와 leaf header 반환
load_tables->>HeaderFlattener: group/leaf 라벨 전달
HeaderFlattener-->>load_tables: 중복 제거된 헤더 생성
load_tables-->>ParsedTable: title, headers, data_rows 구성
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@genon/preprocessor/tests/unit/test_xlsx_processor.py`:
- Around line 273-287: Update test_tabular_two_column_banner_preserves_legacy to
use a sparse one-cell first row while retaining a two-column sheet, then assert
legacy parsing keeps that row as the leaf data row rather than applying banner
skipping; preserve the existing two-column headers and downstream data
assertions as appropriate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 08fc234a-6436-4560-be7a-908795522353
📒 Files selected for processing (2)
genon/preprocessor/converters/xlsx_processor.pygenon/preprocessor/tests/unit/test_xlsx_processor.py
- _detect_header: '절반 이상 채움' → '빈 칸 2개 이하 && 채워진 칸 > 빈 칸' 으로 조정.
담당자 의도('전부 채운 첫 행=헤더')에 최대한 맞추되, 진짜 헤더에 빈 칸 한두 개가
있을 때 데이터행이 헤더로 승격/유실되는 것을 방지(빈 칸 2개까지 허용).
병합 상위행은 hms 분기에서 이미 group 으로 빠지므로 계층헤더는 안 깨짐.
- 유닛 갱신: 빈칸 한두 개 헤더 비스킵(4열 1빈/5열 2빈), 좁은 표 2칸 배너 배제 추가.
전체 18 passed, 실제 SIF 두 시트 정상 재확인.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- '빈 칸 2개 이하'(절대 기준)는 표가 넓어지면 정상 헤더(예: 15열 중 3칸 빔)를 배너로 오판 → 데이터행 승격/유실. 열 수에 비례하는 과반(절반 초과) 기준으로 교체. len(ne)*2 <= len(used_cols) 이면 배너/제목행으로 보고 스킵. - SIF 배너(9칸 중 1칸), 좁은 표 2칸 배너(4칸 중 2칸)는 과반 미달로 배제 - 넓은 표 빈칸 헤더(12/15)는 과반이라 유지(데이터 보존) - 전체 18 passed. 실제 SIF 두 시트 + 사용자 샘플(spacer 열 포함) 정상 확인. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
연도 뒤 '증감' 열의 헤더를 비워두는 통계표(8열 중 5칸=과반). 절대 기준이면 헤더가 스킵돼 첫 데이터행이 헤더로 승격/유실되지만, 과반 기준은 헤더로 유지하고 데이터 3행을 모두 보존함을 고정. 전체 19 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
담당자 방침: 한 칸이라도 비면 헤더로 보지 않고, 모든 칸이 찬 첫 행만 헤더로 잡음. - _detect_header: 과반 기준 → len(ne) < len(used_cols) 이면 제목/배너행으로 스킵. - 헤더에 빈 칸이 섞인 표(증감열 통계표 등)는 헤더로 안 잡히지만, 실무상 드물다는 판단에 따라 확정. 병합 상위행은 hms 분기에서 먼저 group 으로 빠져 계층헤더는 유지. - 빈칸 봐주기 검증 테스트 2개 제거, '전부 채운 행만 헤더' 테스트로 대체. 18 passed. - 실제 SIF 두 시트 정상(strict 규칙에서도 결과 동일) 재확인. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(xlsx): tabular 헤더 자동판정 강화 — 비병합 제목행을 헤더로 잡지 않기
Closes #331
문제
□ 제조업 등(건설업 외 업종))을 헤더행으로 오인함col_N무명 키로 저장되고column_map엔 제목행 하나만 남음원인
_detect_header가 "가로병합 없는 첫 행 = 컬럼명행(leaf)"으로 판정함 (converters/xlsx_processor.py)□ 제조업 등은 병합 안 된 단일 셀이라 제목행으로 안 잡히고 leaf(헤더)로 잡힘data_start = leaf + 1로 밀려서 데이터가 됨수정
변경 파일:
genon/preprocessor/converters/xlsx_processor.py,genon/preprocessor/tests/unit/test_xlsx_processor.py(1)
_detect_header— 모든 칸이 찬 행만 헤더로 잡기기존엔 "가로병합 없는 첫 행"을 무조건 헤더행으로 확정했음. 그래서
□ 제조업 등같은 제목행이 그대로 헤더가 됨. 이를 방지하기 위해, 한 칸이라도 비면 헤더로 보지 않고, 모든 칸이 꽉 찬 첫 행만 헤더로 잡게 함.□ 제조업 등(9칸 중 1칸), 부분행(4칸 중 2~3칸)은 모두 빈 칸이 있으므로 헤더가 아니라 제목/배너행으로 스킵됨if hms:에서 이미 group 으로 빠지므로 계층헤더는 안 깨짐3열 이상일 때만 적용. 2열 이하 표는 이 기준이 불안정해서 기존 동작(첫 비병합 행 = 헤더) 그대로 둠 → 기존 테스트 다 보존됨(2)
load_tables— 계층 헤더 flatten 중복 접기(1) 넣으니까 건설업 시트 2줄짜리 계층 헤더가 처음으로 제대로 잡혔는데, 세로병합된 컬럼(연번·재해종류 등)이 상위행·하위행에 같은 값으로 채워져서
연번_연번처럼 이름이 겹침. 직전 조각이랑 같으면 안 붙이게 함.검증
test_xlsx_processor.py18 passed, 3 skipped(실샘플/docling/e2e는 의존성 없어 skip)header_rowoverride 우선 / 세로병합 중복 접기영향 범위
Summary by CodeRabbit
개선 사항
테스트