본문 바로가기

파일 형식 백과사전

엑셀에는 15%로 보이는데, 파이썬으로 읽으면 왜 0.15가 나올까

엑셀 파일을 파이썬으로 불러와 처리하는 스크립트를 짜다 보면, 분명 화면에서는 "15%"라고 보이던 셀이 코드에서는 0.15로 찍히는 순간을 마주치게 됩니다. 처음 보면 데이터가 잘못 읽힌 줄 알고 당황하기 쉽습니다.

결론부터 말씀드리면 버그가 아닙니다. 퍼센트나 통화 기호, 날짜처럼 "보기 좋게 꾸며진 값"은 셀 안에 그렇게 저장되어 있지 않습니다. 실제로 어떻게 저장되는지 xlsx 내부를 열어 확인해 봤습니다.

 

 

 

세 가지 서식으로 직접 저장해 봤습니다

퍼센트, 통화, 날짜 서식을 각각 지정한 셀을 openpyxl 3.1.5로 만들어 저장한 뒤, 압축을 풀어 xlsx 내부 XML을 직접 읽었습니다.

엑셀 화면 표시값과 xlsx 내부 저장값 비교. 퍼센트 서식 15%는 실제로 0.15, 통화 서식 1,234원은 실제로 1234.5, 날짜 서식 2026-08-22는 실제로 46256(일련번호)로 저장됨

 

 

세 셀 모두 <v> 태그 안에는 순수한 숫자만 있습니다.

"%"도, "원"도, "-"도 파일 어디에도 문자로 적혀 있지 않습니다. 화면에 보이는 모양은 셀 값이 아니라, 옆의 s 속성이 가리키는 서식 규칙이 그 순간 계산해서 그려 주는 결과물입니다.


왜 날짜는 46256이라는 숫자로 저장될까

날짜가 가장 낯설게 느껴지실 텐데, 엑셀은 날짜를 "1900년 1월 1일부터 며칠째인지" 세는

일련번호로 저장합니다. 2026년 8월 22일이 46256번째 날이라는 뜻입니다.

 

날짜 서식은 이 정수를 "몇 년 몇 월 며칠"로 바꿔 보여주는 규칙 중 하나일 뿐입니다.

 

같은 원리로, 시간도 하루를 1로 놓은 소수로 저장됩니다. 정오는 0.5로 저장되는 식입니다.

회계 서식과 전화번호 서식도 같은 원리로 확인해 봤습니다

퍼센트, 통화, 날짜 세 가지 외에도 실무에서 자주 쓰는 서식 두 가지를 더 저장해 봤습니다. 

손실이나 마이너스를 괄호로 표시하는 회계 서식과, 숫자를 전화번호처럼 하이픈으로 끊어 보여주는 사용자 지정 서식입니다.

<c r="A1" s="1" t="n"><v>-1500</v></c>         <!-- 화면엔 (1,500) -->
<c r="A2" s="2" t="n"><v>1012345678</v></c>    <!-- 화면엔 010-1234-5678 -->

회계 서식(#,##0;(#,##0))을 적용한 A1은 화면에 (1,500)으로 보이지만

저장된 값은 그냥 -1500입니다. 세미콜론 뒤의 괄호 표시는 값이 음수일 때 어떻게 그릴지 정한 규칙일 뿐,

값 자체에 괄호나 마이너스 기호 텍스트가 붙는 게 아닙니다. 전화번호 서식(000-0000-0000)을 적용한 A2도 마찬가지로,

하이픈 없는 순수한 숫자 1012345678이 그대로 저장되어 있습니다.

두 사례 모두 앞서 본 퍼센트, 통화와 결이 같습니다. 서식 문자열이 무엇이든, 셀에 실제로 남는 건 항상 순수한 값입니다. 다만 전화번호처럼 앞자리가 0으로 시작하는 값을 이렇게 서식으로 처리하면, 숫자 자체는 010으로 시작하지 않고 10으로 시작한다는 점을 스크립트에서 특히 주의해야 합니다.

파이썬으로 읽으면 실제로 뭐가 나오나

같은 파일을 openpyxl과 pandas로 각각 읽어 비교했습니다.

엑셀 화면 openpyxl .value pandas.read_excel
퍼센트 서식 15% 0.15 0.15
통화 서식 1,234원 1234.5 1234.5
날짜 서식 2026-08-22 datetime(2026, 8, 22) Timestamp('2026-08-22')

흥미로운 점은 날짜만 예외라는 것입니다. openpyxl과 pandas 둘 다 셀 서식이 날짜 패턴이라는 걸 알아채고 46256이라는 숫자 대신 사람이 읽을 수 있는 날짜 객체로 바꿔서 돌려줍니다. 반면 퍼센트와 통화는 이런 자동 변환이 없어서, 저장된 순수 숫자 그대로 나옵니다.

스크립트를 짤 때 챙겨야 할 것

서식 주의할 점
퍼센트 0.15에 100을 곱해야 "15"라는 사람이 보는 숫자가 됩니다
통화 숫자만 저장되므로 통화 기호나 천 단위 쉼표는 코드에서 직접 붙여야 합니다
회계(음수 괄호) 저장값은 그냥 음수입니다. 괄호 표시가 필요하면 코드에서 직접 만들어야 합니다
전화번호 등 사용자 지정 하이픈 없는 순수 숫자로 저장되고, 맨 앞 0은 기록되지 않습니다
날짜 openpyxl, pandas는 알아서 날짜 객체로 바꿔 주지만, 직접 XML을 다룬다면 일련번호 변환식을 따로 챙겨야 합니다

화면에 보이는 값과 셀에 저장된 값은 별개라는 사실 하나만 기억해 두면, 이후 어떤 서식을 마주쳐도 당황하지 않고 원인을 짐작할 수 있습니다.


자주 묻는 질문

 

Q. 셀 서식을 코드로 확인하려면?
openpyxl에서는 cell.number_format으로 확인할 수 있습니다. 값과 별개로 이 서식 문자열을 같이 읽어야 화면과 같은 모양으로 재현할 수 있습니다.

 

Q. 이미 텍스트로 "15%"라고 직접 타이핑한 셀은 다른가요?
다릅니다. 그 경우는 처음부터 문자열로 저장되어 파이썬에서도 문자열 "15%"로 그대로 읽힙니다. 서식이 자동으로 계산해 보여주는 값과는 저장 방식 자체가 다릅니다.

 

Q. 이 차이 때문에 큰 숫자를 다룰 때도 문제가 생기나요?
서식과는 다른 이유지만, 자릿수가 아주 긴 숫자는 저장 단계에서부터 정밀도가 깎이는 별도의 문제가 있습니다. 따로 다룬 글에서 실제 수치로 확인한 적이 있습니다.

 

엑셀 파일을 코드로 다루기 시작하면 한 번쯤 반드시 마주치는 간극입니다. 화면은 사람에게 보여주는 연출이고, 셀에 저장된 값은 그와 별개라는 원칙만 기억해 두면 다음번엔 헤매는 시간이 줄어들 것입니다.

 

 

위 저장값과 읽기 결과는 실제로 서식을 지정한 xlsx 파일을 만들어, openpyxl과 pandas로 각각 읽고 내부 XML도 함께 확인해 얻은 값입니다.

 

 

 

행은 3천 개뿐인데 엑셀 파일이 3.4MB, 용량을 먹는 범인을 파일 안에서 찾아내기

엑셀 파일이 무거워지면 대개 데이터가 많아서라고 생각하게 됩니다. 하지만 실제로는 데이터 양과 파일 용량이 따로 노는 경우가 훨씬 흔합니다.3,000행짜리 주문 내역을 실제로 만들어 저장해

richyeon.com

 

 

움짤(GIF) 용량이 유독 커요, 프레임과 색상 수로 줄이는 법

사진 몇 장을 이어 붙여 움짤을 만들었는데, 정지 사진 하나보다 용량이 몇 배나 커진 경험 있으신가요. 카카오톡으로 보내려니 전송이 느리고, 커뮤니티에 올리려니 용량 제한에 걸리기도 합니

richyeon.com

 

 

여러 개의 PDF를 하나로 합치고, 필요한 페이지만 빼내는 법

계약서, 영수증, 신분증 사본을 따로따로 스캔해 두었다가 한 파일로 제출해야 할 때가 있습니다. 반대로 여러 장짜리 PDF에서 딱 두 장만 보내야 할 때도 있고요.PDF는 워드처럼 열어서 이어 붙이

richyeon.com