파이썬 openpyxl 엑셀 연동 수정하고 읽기

조회수 12539회

파이썬에서 openpyxl로 파일을 수정하고 수정한 데이터를 읽어오고 싶습니다. 하지만 오류가 발생합니다.

다음과 같은 파일이 이미 존재합니다. 파일의 이름은 '더하기.xlsx' 입니다. 이미지

보시면 셀 'C3'은 수식으로 이루어져 있다는 것을 알 수 있습니다.

수정하고자 하는 부분은 셀 'A1'와 'B1'를 각각 1과 2로 바꾸는 것입니다. 최종적으로 제가 얻고자 하는 것은 셀 'A1'와 'B1'의 합이 계산되어 나온 결과인 셀 'C3'의 값 '3' 입니다.

파일의 값을 수정하고자, 다음과 같이 작성하였습니다.

from openpyxl import load_workbook
wb = load_workbook(filename = '더하기.xlsx', read_only=False, data_only=False)
ws = wb['Sheet1']
ws['a1'] = 1
ws['b1'] = 2
a1 = ws['a1']
b1 = ws['b1']
c1 = ws['c1']
print(a1.value)
print(b1.value)
print(c1.value)
wb.save('더하기1.xlsx')`

파일의 이름을 바꾸어 저장하여 원본 파일을 유지하도록 하였습니다.

출력된 결과는 다음과 같습니다.

1
2
=SUM(A1:B1)

파일을 불러올 때, 'data_only=False'로 지정하여 계산된 값이 아니라 식이 출력되었습니다.

'data_only=False '로 지정하지 않고 'data_only=True '로 파일을 불러온 이유는 저장할 때 식이 전부 사라지기 때문입니다.

이제 저장된 ' 더하기1' 파일을 읽을 차례입니다. 파일을 읽기 위하여 다음과 같이 작성하였습니다.

from openpyxl import load_workbook
wb = load_workbook(filename = '더하기1.xlsx', read_only=False, data_only=True)
ws = wb['Sheet1']
a1 = ws['a1']
b1 = ws['b1']
c1 = ws['c1']
print(a1.value)
print(b1.value)
print(c1.value)

이때, '식'이 아니라 '값'만 필요하므로 'data_only=True'로 바꾸었습니다.

이때 출력된 결과는 다음과 같습니다.

1
2
None

출력된 결과를 보면 값은 성공적으로 바뀌었으나 셀 'C3'이 마치 빈 셀인냥 'None'이라고 되어있는 것을 볼 수 있습니다.

하지만 실제로 생성된 '더하기1' 엑셀파일을 열어보면 아래와 같이 엑셀 파일이 원하는 대로 만들어져 있는것을 알 수 있습니다.

이미지

이를 해결하기 위해 여러가지 시도를 한 결과 제가 알아낼 수 있는 사실이 몇 가지 있었습니다만 아직 최종적으로 해결하지는 못했습니다. 제가 알아낸 사실은 다음과 같습니다.

  1. 위의 코딩 내용을 설명드린 것과 같이 실행하면 'None'값이 나온다. 하지만 생성된 '더하기1' 파일을 열고 닫을 때 이상하게도,이미지

    이미 만들어진 파일임에도 불구하고 다음과 같은 메세지가 나오는데 이때 저장을 하면 두번째 코딩내용을 다시 실행했을 때 정상적인 결과가 출력되고 저장을 하지 않으면 계속해서 'None' 값이 출력됩니다. 그러니 무엇인가 저장이 제대로 되지 않아서 발생한 오류인듯 싶습니다.

  2. 위와 같은 문제는 기존에 존재하던 파일을 파이썬으로 수정하여 새로 만들어진 파일을 읽을 때에만 발생하며, 기존에 이미 존재하는 파일을 그냥 읽을 때에는 발생하지 않습니다. 예컨데, 직접 엑셀 파일을 여러 수식이 포함된 엑셀 파일을 하나 만들어 저장하고 그 파일을 'data_only'로 불러와 값을 읽을 때에는 오류가 발생하지 않는다는 것입니다. 이 역시 파이썬으로 기존 파일을 수정하고 저장할 때 다음에 불러와 '계산식의 값'을 읽을 때에만 발생하는 것이므로 무언가 저장하는 과정에서 놓친부분이 있지 않나 추측이 됩니다.

워낙 초보라 이제 쓰기, 읽기를 하고 있는데도 오류가 나서 고생입니다. 도와주세요 ㅠㅠ 읽어주셔서 진심으로 감사합니다!! 새해 복 많이 받으세요 ㅎㅎ

  • (•́ ✖ •̀)
    알 수 없는 사용자

3 답변

  • 이 이슈는 openpyxl 라이브러리의 특성 상 어쩔 수 없는 부분입니다.

    공식문서에 따르면 openpyxl는 formula(=A1+B1과 같은 식)를 절대로 evaluate하지 않습니다. 데이터를 읽거나 쓸 때, formula 자체는 저장하지만, formula를 실행했을 때의 값은 저장되지 않아요.


    예를 들어볼게요.

    wb = load_workbook(filename = '더하기.xlsx', read_only=False, data_only=False)
    wb.save('더하기1.xlsx') # step1
    
    wb1 = load_workbook(filename = '더하기1.xlsx', read_only=False, data_only=True) # step2
    

    위 코드의 step1을 실행하면 '더하기1.xlsx'에 c1에는 formula만 저장되며, 5라는 evaluated value는 저장되지 않습니다.

    따라서 step2에서 data_only = True 로 워크북을 로드하면 c1에는 아무 값도 없다고 표시됩니다.


    • '더하기1' 파일을 더블클릭해 열었을 때, 5라는 값이 보이는 이유는 excel 프로그램이 로딩 시 formula를 계산하기 때문입니다.
    • (•́ ✖ •̀)
      알 수 없는 사용자
  • 답변 감사합니다!!

    • (•́ ✖ •̀)
      알 수 없는 사용자
  • 2년전 글이지만, 같은 문제로 고생을 해서 답변 남겨요.ㅎ...

    똑같은 문제를 겪었고, 해결을 win32 모듈을 사용해서 엑셀을 실행시키고, 작업중인 파일은 다른 이름으로 저장, 그후 다른 이름으로 저장된 파일을 openpyxl을 통해 읽는 방식으로 해결했습니다~.

    요지는. 1.웹이나 기타 등등에서 엑셀에 파일을 쓴다. 2.그후 해당 파일을 사용?하기 전에 win32를 이용해 해당 파일을 직접 열고, 다른 이름으로 저장한다.

    1. 다른이름으로 저장된 파일을 불러오면 해결!
    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)