7.7 KiB
7.7 KiB
엑셀 파일 미리보기 시 도형(Shapes) 렌더링 한계 분석 및 대응 방안
본 문서는 웹 브라우저 환경에서 엑셀(.xlsx) 파일을 직접 파싱하여 미리보기 화면을 구성할 때, 도형(Shapes, 화살표, 선, 프로세스 차트 등)이 렌더링되지 않는 기술적 원인과 한글(HWP) 파일 파싱 방식과의 구조적 차이점, 그리고 이를 보완하기 위한 최선의 대응 방안을 정리한 기술 분석서입니다.
1. 개요 및 현상
- 정상 작동 영역: 셀 데이터(텍스트, 숫자, 날짜), 셀 스타일(배경색, 폰트 크기, 테두리), 시트 수식, 셀 병합 상태, 그리고 일부 부유형 이미지(그림 파일)는 브라우저 미리보기 화면에서 정상적으로 표현됩니다.
- 비정상 작동 영역: 사각형, 원형, 화살표, 말풍선, 블록 화살표, 다이어그램, 연결선 등 **엑셀 본문 그리드 위에 독립적으로 배치된 드로잉 도형 객체(Shapes/Drawings)**들은 화면에 아예 표시되지 않거나 누락되는 현상이 발생합니다.
2. 기술적 원인 분석 (오픈소스 라이브러리의 한계)
본 시스템은 웹 브라우저 단에서 서버 리소스를 쓰지 않고 빠르게 엑셀을 렌더링하기 위해 다음 두 가지 라이브러리를 결합하여 사용하고 있습니다.
- LuckyExcel: 엑셀(
.xlsxbinary/zip) 파일을 자바스크립트 객체(JSON) 데이터 모델로 변환해주는 파서. - Luckysheet: 변환된 JSON 모델을 바탕으로 웹 브라우저 화면에 엑셀 시트 그리드를 그려주고 셀 동작을 처리해주는 렌더러.
이 두 오픈소스 라이브러리는 태생적으로 **"셀(Cell) 중심의 그리드 표현"**에 특화되어 개발되었기 때문에 다음과 같은 한계를 가집니다.
① LuckyExcel (파서) 측면의 한계 (XML 스펙 무시)
- 엑셀 파일(
.xlsx)은 OpenXML 포맷을 따르며, 시트 내에 배치된 도형 정보는xl/drawings/drawing1.xml과 같은 파일 내에 DrawingML 규격으로 기록됩니다. - LuckyExcel은 이 XML 파일을 파싱할 때 이미지 객체를 정의하는
<xdr:pic>태그만 선별적으로 추출하여 Luckysheet의 이미지 모델로 넘겨줍니다. - 반면, 일반 도형을 정의하는 **
<xdr:sp>(Shape)**나 연결선을 정의하는<xdr:cxnSp>(Connection Shape) 등 기타 드로잉 엘리먼트들은 코드 레벨에서 파싱을 전혀 지원하지 않고 무시합니다.
② Luckysheet (렌더러) 측면의 한계 (드로잉 모델 부재)
- Luckysheet의 내부 데이터 스키마에는 셀 서식, 수식, 그리고 부유형 이미지를 관리하는 속성(
images)은 설계되어 있으나, 다각형이나 선, 벡터 그래픽을 추상화하여 저장하고 실시간으로 그려주는 도형 전용 데이터 규격 및 컴포넌트(Drawing Engine)가 존재하지 않습니다. - 이미지는 웹 브라우저가 기본적으로 지원하는
<img>태그를 절대 좌표 기반으로 얹어주면 비교적 단순하게 렌더링할 수 있지만, 벡터 도형은 브라우저 상에서 가변적으로 그리기가 매우 까다로워 처음부터 설계 범위에서 배제되었습니다. - 추가 이슈: 현재 Luckysheet 프로젝트는 공식적으로 개발이 중단(Unmaintained)되었으며, 후속 아키텍처 프로젝트인 Univer로 이전이 권장되고 있어 향후에도 도형 렌더링 기능이 보완될 가능성이 없습니다.
3. 한글(HWP) 파일 파싱 방식과의 차이점
"한글 파일은 도형이 나오는데 엑셀은 왜 구현이 불가능한가?"에 대한 구조적 비교는 다음과 같습니다.
| 비교 항목 | 한글(HWP) 미리보기 파싱 | 엑셀(Excel) 미리보기 파싱 |
|---|---|---|
| 사용 라이브러리 | hwp.js (자체 커스텀 버전) |
LuckyExcel + Luckysheet (외부 CDN 주입) |
| 도형 데이터 모델 | HWP 스펙에 정의된 Line, Rectangle, Ellipse 객체 모델을 내부에 명확히 파싱하여 보유함 | 데이터 모델(JSON) 상에 도형에 대한 정보(좌표, 타입, 스타일 등)를 담을 필드 자체가 없음 |
| 렌더링 방식 | 추출된 도형 노드를 브라우저 화면상의 **HTML5 SVG(Scalable Vector Graphics)**로 직접 변환하여 문서 플로우 내에 동적으로 삽입 및 드로잉 처리함 | 시트 좌표계에 독립적인 드로잉 레이어나 SVG 변환 규칙이 존재하지 않으며, 오직 Canvas 표 위에 텍스트/셀 테두리만 출력함 |
| 개선 가능 범위 | 라이브러리 소스 코드가 프로젝트 내(libs/hwp.js)에 패키징되어 있어 좌표 보정이나 텍스트 누락 방어 등의 수정이 유연하게 가능함 |
외부 라이브러리이며, 도형 표현을 위해선 파서와 렌더링 캔버스 엔진을 바닥부터 다시 코딩해야 하므로 프로젝트 규모의 프레임워크 재설계가 필요함 |
4. 직접 구현 시의 기술적 난제 (CAD/웹 오피스 수준의 공수)
서버 도움 없이 클라이언트 브라우저 단에서 엑셀 도형을 직접 그리려면 다음과 같은 고난도의 기술적 해결책을 직접 만들어야 합니다.
- DrawingML Parser 개발:
JSZip으로 엑셀 파일 내의xl/drawings/drawingX.xml을 압축 해제하고 DOMParser로 열어 각 도형의 크기, 회전각, 선 스타일, 그라데이션, 정렬, 텍스트 상자 등을 파싱하는 코드를 개발해야 합니다. - 동적 픽셀 좌표(Dynamic Cell-to-Pixel) 매핑 엔진:
- 엑셀에서 도형 위치는 절대 픽셀이 아니라, 특정 셀을 기준으로 한 위치인 "Two Cell Anchor" 구조로 관리됩니다.
- 예: "C열 4번째 행의 왼쪽으로부터 10px, 위로부터 5px 떨어진 곳에서 시작하여 E열 8번째 행까지..."
- 따라서 엑셀 시트 내의 열 너비(Column Width)와 행 높이(Row Height)의 동적 변화를 실시간으로 가산하여 정확한 웹 픽셀(X, Y, Width, Height)로 치환해야 합니다.
- 엑셀에서 도형 위치는 절대 픽셀이 아니라, 특정 셀을 기준으로 한 위치인 "Two Cell Anchor" 구조로 관리됩니다.
- 스크롤, 확대/축소 및 열 너비 조절 동기화:
- 사용자가 그리드를 마우스로 조작(스크롤, 컬럼 너비 리사이즈, 시트 확대/축소)할 때마다 SVG 도형 객체의 크기와 좌표도 실시간 재계산 및 Repositioning 처리를 해야 하며, 싱크가 1ms라도 어긋나면 도형이 표 위에 둥둥 떠다니는 왜곡 현상이 발생합니다.
5. 프로젝트 내 조치 내용 및 우회 해결 방법 (Best Practice)
웹 브라우저의 프론트엔드 파싱만으로는 엑셀 본래의 완벽한 폰트, 다이어그램, 차트 및 수많은 도형 레이아웃을 100% 보존하여 출력할 수 없습니다.
이 때문에 업계 표준(Google Docs, Slack, Confluence 등)에 맞춰 서버 측 고성능 오피스 변환 엔진을 이용한 PDF 뷰어 폴백(Fallback) 방식을 조합하여 최선의 UX를 제공하도록 처리했습니다.
적용된 우회 해결책
- "PDF로 보기" 버튼 상시 노출 처리 (2026-06-19 패치):
- 기존에는 엑셀 파싱 에러(포맷 불일치 등)가 났을 경우에만 "PDF로 보기" 버튼이 활성화되어, 정상적으로 시트가 열린 상태에서 도형이 깨져 보이는 문서는 원본을 열람할 수 없었습니다.
- 엑셀 뷰어가 실행되는 즉시 화면 상단 우측에 "PDF로 보기" 버튼이 항상 노출되도록 3개 뷰어 모듈(
pageRenderer.js,docPageRenderer.js,popup.js)을 개선하였습니다. - 사용자는 도형 및 완벽한 레이아웃 보존이 필요한 경우 "PDF로 보기" 버튼을 눌러 서버가 변환한 정밀한 PDF 뷰어 화면으로 즉시 스위칭하여 원하는 내용을 고화질로 확인할 수 있습니다.