본문 바로가기

파일 형식 백과사전

.xls와 .xlsx, 확장자만 다른 게 아니라 안에 든 구조 자체가 다릅니다

회사 서버 어딘가에서 십 년 묵은 서식 파일을 하나 받아 왔다고 해 보겠습니다. 확장자는 .xls. 어제 내가 저장한 .xlsx와 이름만 다를 뿐 둘 다 "엑셀 파일"이라 별생각 없이 다루기 쉬운데, 막상 압축 프로그램에 넣어 보면 하나는 순순히 열리고 하나는 뻗어 버립니다.

왜 그런지 궁금해서 예전에 받아 둔 .xls 샘플과 최근 저장한 .xlsx를 나란히 뜯어봤습니다. 확인해 보니 두 파일은 압축률이 조금 다른 수준이 아니라, 애초에 데이터를 담는 설계 사상 자체가 달랐습니다.

 

xlsx와 xls의 내부 합계와 실제 파일 크기 비교. xlsx 파일은 zip 압축 후 310KB, 내부 파일 합계(비압축) 536KB. xls 파일은 전체 56KB, 내부 스트림 합계 54KB로 파일 크기와 거의 같음

 

 

첫 8바이트만 봐도 남남입니다

파일 맨 앞부분에는 이 파일이 어떤 형식인지 알려주는 고유한 바이트 값(매직 바이트)이 있습니다. 두 파일의 시작 부분을 직접 찍어 봤습니다.

college.xls               d0 cf 11 e0 a1 b1 1a e1
GCP_PCA_DUMP.xlsx         50 4b 03 04 14 00 06 00

50 4b는 아스키코드로 "PK"입니다. ZIP 압축 프로그램을 만든 필 카츠(Phil Katz)의 이니셜에서 온 표시로, xlsx가 사실은 ZIP 압축 파일이라는 뜻입니다. 반면 xls가 시작하는 d0 cf 11 e0는 마이크로소프트의 옛 문서 저장 방식인 OLE 복합 파일(Compound File)의 표시입니다.


실제로 열어서 안을 세어 봤습니다

파이썬 표준 라이브러리 zipfile과 olefile 4.1을 윈도우 11에서 사용해 두 파일의 내부를 직접 읽었습니다.

xlsx는 압축을 풀면 21개의 개별 파일이 나옵니다. 셀 내용은 xl/worksheets, 반복되는 문자열은 xl/sharedStrings.xml, 삽입된 사진은 xl/media 폴더에 각각 흩어져 있습니다.

xlsx 내부 파일(용량 순) 비압축 압축 후
xl/sharedStrings.xml 210,455 B 67,615 B
xl/media/image3.png 130,074 B 130,074 B
xl/worksheets/sheet1.xml 87,655 B 14,103 B
xl/styles.xml 4,575 B 918 B

반면 xls를 olefile로 열면 이런 구조가 아니라 단 3개의 스트림만 나옵니다. Workbook이라는 스트림 하나에 시트 내용과 서식 정보가 통째로 바이너리로 압축 없이 들어 있고, 나머지 둘(SummaryInformation, DocumentSummaryInformation)은 작성자 같은 문서 속성입니다.

    46,593 B  Workbook
     4,096 B  SummaryInformation
     4,096 B  DocumentSummaryInformation

 

왜 하나는 압축 이득이 있고 하나는 없을까

xlsx 샘플은 내부 파일을 풀면 536KB인데 실제 파일은 310KB, 약 42% 줄었습니다. XML은 사람이 읽는 글자로 이루어진 텍스트라 반복되는 태그와 공백이 많아 ZIP으로 짜낼 여지가 큽니다.

xls 샘플은 내부 스트림 합계(54KB)와 파일 전체 크기(56KB)가 거의 차이가 없습니다. OLE 복합 파일은 애초에 압축 계층이 없는, 여러 파일을 하나로 묶기만 하는 구조이기 때문입니다. 이미 바이너리로 촘촘하게 적힌 내용이라 압축 여지도 크지 않습니다.

그럼 xls는 압축해도 소용없을까

여기서 궁금증이 하나 더 생깁니다. xls 자체에는 압축 계층이 없다고 했는데, 그럼 이 파일을 zip으로 한 번 더 감싸면 어떻게 될까요. xls와 xlsx 샘플을 각각 압축 프로그램으로 한 번 더 눌러 봤습니다.

college.xls        56,832 B  →  zip 압축 후  13,308 B (23.4%)
GCP_PCA_DUMP.xlsx  317,800 B →  zip 압축 후 298,157 B (93.8%)

결과가 정반대로 갈립니다. xls는 76.6%가 그대로 더 줄어드는 반면, xlsx는 겨우 6.2% 줄어드는 데 그칩니다. 이유는 앞서 본 그대로입니다. xlsx는 이미 zip으로 한 번 짜낸 상태라 다시 압축해도 쥐어짤 게 거의 안 남았고, xls는 압축이라는 걸 한 번도 거치지 않은 원시 상태라 아직 여지가 많이 남아 있던 것입니다.

오래된 xls 파일을 메일이나 메신저로 보낼 일이 있다면, 파일을 압축해서 보내는 것만으로 용량이 4분의 1 수준으로 줄어듭니다. xlsx는 이미 압축된 상태라 zip으로 한 번 더 감싸도 큰 효과가 없다는 점과 대비됩니다.

 

xls를 압축 프로그램으로 열면 무슨 일이 벌어질까

xlsx는 확장자만 .zip으로 바꾸면 윈도우 탐색기가 그대로 열어 줍니다. 진짜 zip이기 때문입니다. 반대로 xls에 같은 방법을 시도하면 어떻게 될까요. 파이썬으로 xls 파일을 zipfile로 직접 열어 재현해 봤습니다.

>>> import zipfile
>>> zipfile.ZipFile("college.xls")
BadZipFile: File is not a zip file

실제로 발생하는 에러입니다. xls는 애초에 ZIP이 아니므로 확장자를 바꿔도 압축 프로그램이 인식하지 못합니다. "엑셀 파일이니 다 같은 원리겠지"라는 짐작이 통하지 않는 지점입니다.


실무에서는 무엇이 달라지나

구분 .xls (엑셀 97-2003) .xlsx (엑셀 2007 이후)
내부 구조 OLE 복합 파일, 바이너리 ZIP + XML 텍스트
최대 행 수 65,536행 1,048,576행
내부를 직접 열어 고치기 사실상 어려움 텍스트 편집기로도 가능
매크로 포함 여부 같은 확장자 안에 포함 가능 xlsm으로 확장자가 분리됨

행 수 제한은 엑셀이 공식적으로 문서화한 형식별 규격이며, 실제 사용 버전에 따라 동작이 달라질 수 있습니다. 65,536행을 넘는 데이터를 옛 xls로 저장하려 하면 초과분이 잘려 나갈 수 있으니, 대용량 데이터를 다룬다면 xlsx 계열을 쓰는 편이 안전합니다.

여기서 흔히 헷갈리는 부분이 하나 있습니다. 최신 엑셀에서 xls 파일을 열면 제목 표시줄에 [호환 모드]라는 문구가 붙는데, 이건 파일이 xlsx로 바뀌었다는 뜻이 아닙니다. 여전히 xls 구조 그대로 열려 있고, 그 상태에서 최신 기능 일부가 제한된다는 안내일 뿐입니다. 이 상태에서 그냥 저장(Ctrl+S)하면 다시 xls로 저장됩니다. xlsx로 넘어가려면 [파일] → [정보] → [변환]을 눌러 명시적으로 형식을 바꿔야 합니다.

오래된 xls 파일을 받았고 내용을 조금이라도 손보게 된다면, 그대로 저장하지 말고 "다른 이름으로 저장"에서 xlsx로 바꿔 저장해 두는 편이 이후 호환성 문제를 줄입니다.

 

자주 묻는 질문

Q. xls를 xlsx로 바꾸면 내용이 깨지나요?
엑셀에서 다른 이름으로 저장만 하면 내용은 그대로 옮겨집니다. 다만 매크로가 있었다면 별도로 xlsm으로 저장해야 유지됩니다.

Q. xlsx 안의 XML을 직접 고쳐도 되나요?
가능은 하지만 압축 구조와 파일 간 참조 관계를 함께 맞춰야 해서, 값 하나 고치는 정도가 아니면 권하지 않습니다. 이 구조를 이용해 용량 원인을 진단하는 방법은 따로 다룬 글이 있습니다.

Q. xls 파일 안의 텍스트도 검색되나요?
바이너리 구조라 메모장으로 열면 알아보기 어렵지만, 문자열 자체는 인코딩된 형태로 스트림 안에 남아 있어 전용 도구로는 추출이 가능합니다.

Q. [호환 모드]로 열린 파일을 저장만 여러 번 해도 xlsx가 되나요?
안 됩니다. 몇 번을 저장하든 확장자와 내부 구조는 xls 그대로 남습니다. 형식을 바꾸려면 반드시 "변환" 또는 "다른 이름으로 저장"에서 xlsx를 직접 선택해야 합니다.

Q. xls를 굳이 압축해서 보내지 않고 그냥 xlsx로 바꿔 보내면 안 되나요?
그 방법이 더 근본적인 해결입니다. 다만 상대방이 예전 프로그램만 쓴다거나 원본 형식을 그대로 유지해야 하는 상황이라면, 형식은 xls로 두고 압축만 해서 보내는 절충도 가능합니다.

 

xls와 xlsx는 같은 회사, 같은 프로그램이 만든 파일이지만 태어난 시대가 다릅니다. 하나는 압축이라는 개념이 자리 잡기 전, 정보를 통째로 이어 붙여 저장하던 시절의 결과물이고 다른 하나는 웹 시대의 표준(XML, ZIP)을 그대로 가져다 쓴 결과물입니다. 이 배경을 알면 "왜 이 파일은 안 열리지" 같은 호환성 문제를 만났을 때 짐작이 훨씬 빨라집니다.

 

위 바이트 값과 내부 구성은 실제 xls, xlsx 샘플 파일을 파이썬 olefile과 zipfile로 직접 열어 확인한 값입니다.

 

 

PNG를 화질 손실 없이 WebP로, 무손실 변환하면 용량이 얼마나 줄어들까 확인해보니

WebP는 흔히 화질을 조금 줄여 용량을 아끼는 형식으로 알려져 있습니다. 그런데 WebP에는 무손실 모드가 따로 있어서, 픽셀을 하나도 건드리지 않고 용량만 줄이는 것도 가능합니다. 로고나 화면

richyeon.com

 

 

JPG 저장할 때 화질(quality)을 몇으로 두면 좋을까, 옵션별 용량 실측 방법

사진을 JPG로 저장할 때 화질 값을 묻는 프로그램이 많습니다.보통 0부터 100 사이의 숫자인데, 이 값을 얼마로 두느냐에 따라 파일 크기가 몇 배씩 달라집니다.무작정 100으로 두면 용량이 커지고,

richyeon.com

 

 

큰 CSV를 엑셀 대신 SQL로 다루기, SQLite에 불러와 조회하는 방법

수천 행짜리 CSV에서 도시별 매출 합계나 특정 조건의 주문만 뽑아내려면, 엑셀에서는 피벗 테이블과 필터를 여러 번 거쳐야 합니다. 이럴 때 CSV를 SQLite라는 가벼운 데이터베이스에 한 번 넣어

richyeon.com