4 Jul
2012
Posted in: 코드
By    4 Comments

파이썬에서 엑셀 파일 다루기…


파이썬에서 엑셀 파일 다루기…
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaru, http://www.jiniya.net


XIGNCODE는 간지나는 엑셀 리포트도 제공해 드립니다 ㅋ~

최근에 고객사의 요청으로 엑셀 리포트를 만드는 기능을 웹 시스템에 추가했다. 일간, 주간으로 월요일 0시에 째깍 째깍 리포트를 자동으로 생성할 뿐만 아니라 영정시킬 수 있는 로그는 별도 색깔로 하이라이팅을 해준다. 여기에 덧붙여 게임 운영자가 아주 손쉽게 쓸 수 있도록 사용자 별로 영정 대상 해킹툴 사용 카운트를 소팅해서 보여준다. 진짜 쏘 쿨한 기능이 아닐 수 없다. ㅋㅋ~

어쨌든 이런 멋진 기능을 만들기 위해서 난 파이썬에서 엑셀 파일을 다루는 라이브러리를 좀 찾아봤다. 배터리가 포함된 파이썬답게 다양한 방법이 있었는데 여기서는 내가 사용해본 3가지 방법에 대해서 이야기 해볼까 한다. 라이브러리를 3가지나 거쳤다는 것은 그만큼 시행 착오를 겪었다는 말이다. 혹시 비슷한 일을 하는 다음 사람은 부디 그런 삽질을 하지 않았으면 한다. 오픈 소스 라이브러리의 경우 문서화가 아주 잘 된 것들도 아니라서 스타일 기능을 쓸 때 마다 라이브러리 소스를 뒤지고, 구글링하는 수고를 거쳐야 했기 때문이다. 몹시 스트레스풀한 작업이었다. ㅋ~

#0. xlwt
제일 처음 살펴보았던 녀석이 xlwt였다. 이놈은 파이썬 독자적으로 엑셀 파일을 다룰 수 있도록 만든 라이브러리다. 하지만 제일 안습했다. 문제는 간단했다. 우리가 만드는 엑셀 파일은 일간 로그는 많게는 한 시트에 2만건 정도의 데이터가 기록되고, 주간 로그는 많게는 15-20만건 정도의 로그가 기록된다. 근데 이 xlwt는 65536개의 데이터만 기록할 수 있는 한계가 있었다. xls 파일의 한계라 그렇다는데 어쨌든 그런 연유로 다 만들었다 제일 먼저 아웃되었다.

#1. openpyxl
다음으로 살펴본 녀석은 openpyxl이다. 이것도 파이썬 독자적으로 엑셀 파일을 다룰 수 있도록 만든 라이브러리다. 활발하게 만들어지고 있는 녀석답게 xlsx 포맷을 지원하고 20만건의 데이터도 저장할 수 있는 위용을 자랑한다. 크게 문제없이 이 녀석으로 구현해 놓고 사용하고 있었는데 이상하게 월요일만 되면 로그가 생성되지 않는 문제가 발생했다. 그래서 살펴봤더니 서버 메모리가 부족해서 처리를 못하는 문제가 있었다. 리포트 생성 스크립트는 서버에서 동시에 실행되도록 되어 있는데 그래서 그런 줄 알고 하나씩 순차적으로 처리하도록 구조를 변경했다. 그래도 메모리가 부족하긴 마찬가지 였다. 그래서 가장 큰 놈을 실행해서 메모리 점유율을 살펴보았는데, 이건 뭐 2기가 바이트를 넘는 메모리가 필요했다. 잘 아다시피 32비트 윈도에서 특별한 옵션없이 부팅하면 애플리케이션은 2기가 이상을 사용하지 못한다. 첨에는 내가 너무 막짜서 그런 줄 알았다. 파이썬은 막 짜는게 간지지 않은가? 그래서 아래와 같은 글까지 살펴보면서 데이터를 일일이 최적화 시켰다.

http://stackoverflow.com/questions/2211965/python-memory-usage-loading-large-dictionaries-in-memory
http://stackoverflow.com/questions/2670005/python-large-variable-ram-useage

그런데 결론은? 개뻘짓이었다. 왜냐하면 내가 쓰는 메모리가 많은 게 아니라 openpyxl 안에서 너무 많은 메모리를 사용하고 있었기 때문이다. openpyxl이 사용하는 메모리를 줄이기 위해서는 데이터를 끊어서 저장하고 다시 그 파일을 열어서 추가하고 또 저장하고 하는 식으로 처리를 해야 했다. 그래서 5만건씩 데이터를 나눠서 저장하도록 프로그램을 고쳤는데, 그랬더니 이번에는 스타일이 모두 깨지는 문제가 발생했다. 저장하고 다시 열면 해당 파일의 스타일을 제대로 가져오지 못하는 문제가 있었던 것이다. 흙~ 맞다. 오픈 소스는 아직 갈 길이 멀다.

#2. COM
최종 종착지는 여기다. 엑셀을 다루는 가장 좋은 방법은 엑셀을 사용하는 것 아니겠는가? 우리는 다행이도 윈도우 서버를 운영하고 있었다. 서버에 엑셀을 설치했다. 그리고 COM을 사용해서 접근했다. 결과는 어땠을까? 가장 큰 파일을 저장할 때에도 파이썬은 20메가 안팍의 메모리를, 실행된 엑셀도 30메가를 넘지 않는 점유율을 보였다. 당연히 엑셀에서 사용할 수 있는 모든 기능을 자유자재로 사용할 수 있음은 말할 것도 없다. 근데 메모리 점유율은 확 떨어졌지만 그렇게 빠른 편은 아닌 것 같다.

#3. 결론
파이썬에서 엑셀을 다루어야 한다. 파일 크기가 작다면 아무꺼나 쓰든 크게 상관없다. 물론 복잡한 스타일이나 기능을 사용하려면 아무래도 COM이 가장 좋다. 그렇지 않으면 가장 결정적인 순간에 지원되지 않는다거나 아직 구현되지 않았다거나 하는 이유로 결국 다시 COM으로 돌아갈 수 밖에 없기 때문이다. 이런 점을 충분히 고려하고도 독자 라이브러리를 쓰겠다면 openpyxl이 그나마 좀 더 좋은것 같다. 큰 파일을 다루어야 한다. 그러면 걍 COM 쓰자. 그게 편하다. 리눅스 서버다. 그럼 좀 더 고민해보고 ㅋ~

Browser does not supports flash movie

  • 트랙백 주소: http://www.jiniya.net/wp/archives/7692/trackback

관련 글

  • http://khmirage.tistory.com 환상경

    아…. xlwt에 저런 제약이 있었군요 -0-
    이전 프로젝트에서 엑셀 파일 저장할때 xlwt를 사용해서 구축했는데
    저런 제약이 있었다니 OTL

  • codewiz

    환상경 // 네… 저도 다 만들고 나서 알았습니다. ㅠㅜ~

  • 최규성

    COM의 연결된 주소가 잘못되었네요…찾아보니
    http://pythonexcels.com/python-excel-mini-cookbook/ 로 변경된 듯합니다..

    잘 읽고 갑니다..

  • 코번

    xlsxwriter 모듈 쓰시면 openpyxl보다 월등히 성능이 앞섭니다. openpyxl은 데이터 수십만개 되면 거의 파일을 못만들다시피 하는 반면, xlsxwriter는 아무 문제없네요