본문 바로가기
아래아한글 자동화/python+hwp 중급

[교육업무자동화6/7] 청구서자동화6(pyinstaller로 배포하기)

by 일코 2021. 1. 26.

지난 포스팅은...

 

[교육업무자동화5/10] 청구서자동화5(개선할 부분 찾아보기) #중급

지난 포스팅은... [교육업무자동화4/10] 청구서자동화4(청구서 마무리하기) 지난 포스팅은... [교육업무자동화3/10] 청구서자동화3(파이썬으로 엑셀 열어서 값 얻기) 지난 포스팅은... [교육업무자동

www.martinii.fun

 


지난 시간에 몇 가지 오류가능성을 보완한 최종 코드는 아래와 같았다.

"""
누름틀이 삽입된 1페이지짜리 한/글 파일을
엑셀파일 행 갯수만큼 복사하고,
각각의 누름틀 안에다 엑셀파일 각 칼럼의 값을 입력하는 프로그램.
실행파일과 한/글 파일, 엑셀파일 하나씩을 같은 폴더 안에 두면
GUI창이 뜨지 않는다.
"""


import os
from tkinter import Tk
from tkinter.filedialog import askopenfilename
import win32com.client as win32

BASE_DIR = os.getcwd()
os.chdir(BASE_DIR)
엑셀파일_리스트 = [i for i in os.listdir() if any((i.endswith(".xlsx"), i.endswith(".xls")))]
if len(엑셀파일_리스트) == 1:
    엑셀파일 = 엑셀파일_리스트[0]
else:
    root = Tk()
    엑셀파일 = os.path.basename(
        askopenfilename(title="엑셀 또는 CSV 파일을 선택해 주세요.", initialdir=BASE_DIR,
                        filetypes=[("스프레드시트", "*.xlsx *.xls *.csv")]))
    root.destroy()

한글파일_리스트 = [i for i in os.listdir() if i.endswith(".hwp")]
if len(한글파일_리스트) == 1:
    한글파일 = 한글파일_리스트[0]
else:
    root = Tk()
    한글파일 = os.path.basename(
        askopenfilename(title="HWP 파일을 선택해 주세요.", initialdir=BASE_DIR,
                        filetypes=[("아래아한글", "*.hwp")]))
    root.destroy()

if not all([엑셀파일, 한글파일]):
    raise FileExistsError("파일이 존재하지 않습니다.")

hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
hwp.RegisterModule("FilePathCheckDLL", "SecurityModule")
hwp.Open(os.path.join(BASE_DIR, 한글파일))
field_list = hwp.GetFieldList().split("\x02")

excel = win32.gencache.EnsureDispatch("Excel.Application")
wb = excel.Workbooks.Open(os.path.join(BASE_DIR, 엑셀파일))
ws = wb.Worksheets(1)

used_range = ws.UsedRange()
excel.Quit()
title_list = used_range[0]
content_list = used_range[1:]

hwp.XHwpWindows.Item(0).Visible = True

dict_list = []
for i in content_list:
    dict_list.append(dict(zip(title_list, i)))

hwp.Run("CopyPage")
for i in range(len(dict_list) - 1):
    hwp.Run("PastePage")
    print(i+2)  # 1페이지는 이미 있고, 2페이지부터 만들기 시작하는데, 인덱스는 0부터 시작하니까 "+2"

if not sorted(field_list) == sorted(list(title_list)):
    raise KeyError("불러온 한/글 파일과 엑셀파일의 필드목록이 다릅니다.")

for 행번호 in range(len(dict_list)):
    for 인덱스, 필드명 in enumerate(field_list):
        hwp.PutFieldText(필드명+f"{{{{{행번호}}}}}", dict_list[행번호][필드명])
        if 필드명 == field_list[-1]:
            hwp.MoveToField(필드명+f"{{{{{행번호}}}}}")

코드를 일일이 외우거나 전부 이해할 필요는 없다.
다만 줄거리 정도는 기억해줘야 한다.
맥락이 기억나지 않는다면 지난 포스팅을 한 번 읽고 돌아오자.

 


 

1. pip을 통해 pyinstaller 설치하기

이번 포스팅은 파이썬-아래아한글 청구서 자동화 시리즈의 마지막이 될 것으로 예상하는,
pyinstaller로 배포하기 시간이다. pyinstaller는 별도의 설치가 필요한 외부 모듈로,

ipython 콘솔이나, 커맨드프롬프트상에서 (혹시 가상환경을 사용한다면 활성화한 후에) 아래와 같이 실행한다.

"pip install pyinstaller"

최신버전은 4.2로 확인된다. 업데이트 완료.

설치된 pyinstaller 모듈은 4.2버전이다.

 


 

2. 아이콘파일(.ico) 생성하기

몇 번 해 보면 느끼겠지만, pyinstaller로 생성한 실행파일의 기본아이콘은 굉장히... 별로다.
(필자가 너무 많이 봐서 그럴 수도 있다. 하여튼 막 바꿔주고 싶은 아이콘이다.)

기본으로 적용되는 아이콘은 이렇게 생겼다.

허접하게나마 그림판이라도 열어서, 직접 엑셀파일의 아이콘과, 한/글파일의 아이콘을 무려 "짬뽕"해보았다.

기본아이콘이 좀 더 낫나?;;;

이 파일을 가지고 PNG to ICO | Online Icon Converter (hnet.com)에 가서 아이콘(ICO)파일을 생성한다.

Upload Images 버튼을 누르고, 해당 png파일을 선택한다.

생성한 아이콘을 파이썬 코드파일이 위치한 폴더에 복사해준다.

폴더 안에는 그림과 같이 4개 파일이 들어있다.

 


 

3. pyinstaller로 EXE파일 생성하기

커맨드프롬프트 창을 열고 py파일이 있는 디렉토리로 이동한다.
(가상환경을 사용하고 있었다면, 가상환경을 활성화하자.)

파이참을 사용하고 있다면 간단히 Alt-F12를 눌러 터미널을 열고 해당 폴더로 이동한 후
아래 명령어를 입력한다.

pyinstaller를 실행한다. 파일명은 각자 다를 것.

옵션 중 -F는 단일 EXE파일 한 개로 컴파일하는 옵션, -i 는 뒤의 아이콘파일로 실행파일 아이콘을 설정하는 옵션,
그리고 -w 는 기본 콘솔창이 뜨지 않게 하는 옵션이다. 위 커맨드를 입력하고 엔터를 누르면

최초엔 시간이 좀 걸리고, 두 번째부터는 몇 초 안에 컴파일이 끝난다.

폴더를 열어보면,

하위폴더가 세 개, .spec파일이 하나 생성되었다.

실행파일은 dist 폴더 안에 들어있다. dist 폴더를 더블클릭해보자.

이게 컴파일된 최종 실행파일이다. 가슴이 웅장해질... 정도는 아니다;

이제 이 파일과 한/글파일, 엑셀파일 세 개를 묶어서 배포/관리하면 된다.
기왕이면 ZIP으로 압축하자.

그럼 포스팅을 마치기 전에 EXE파일이 잘 작동하는지 테스트해보자.

exe파일과 엑셀,한/글파일 외에는 삭제해준 뒤, exe파일을 더블클릭한다.

 

페이지복사, 누름틀 삽입을 마치고 "작업이 완료되었습니다." 팝업이 뜨면 끝.

 


 

청구서 자동화를 마치며...

무려 6개 포스팅으로 청구서 자동화를 배포까지 진행해보았다.
코드만 놓고 보면 50라인 남짓의 짧은 코드였다. 설명 때문에 분량이 다소 길어졌지만 핵심은 간단하다.
입문~초급자를 대상으로 만든 포스팅이라 나름 상세히 설명을 붙여보았는데,
그게 오히려 지루하게 만들 수도 있었겠다는 생각이 든다.

여기까지 잘 따라와주고, 필드설정에서부터 배포까지 자기 것으로 만들었다면
여기에서 응용할 수 있는 업무자동화 테마는 정말 무궁무진할 것이다.

물론 한/글 API는 이게 다가 아니다. 정말 다양한 작업들을 자동화할 수 있고,
필자도 계속해서 튜토리얼을 올리고 있지만, 사실 테마는 얼마든지 더 만들 수도 있다.
API메서드와 약간의 파이썬 문법, 그리고 유용한 모듈을 조합하면
"못할 것이 없다"라는 말도 과장이 아니라고 여겨진다.

남은 네 개의 포스팅에서는 특별히 새로울 것 없이,
청구서 자동화 코드를 응용하여, (7)영수증, (8)수료증 발급 프로그램,
그리고 (9)단체메일 발송, (10)PDF출력-심화 순서로 포스팅을 이어갈 예정이다.

긴 글 읽어주셔서 감사드리며,
부디 많은 이들에게 도움이 되었으면 하는 바람이 있다.

행복한 하루 되시길~

 


 

다음 포스팅은...

 

[교육업무자동화7/10] 영수증자동화(개별저장 및 찾아바꾸기)

지난 포스팅은... [교육업무자동화6/10] 청구서자동화6(pyinstaller로 배포하기) 지난 포스팅은... [교육업무자동화5/10] 청구서자동화5(개선할 부분 찾아보기) #중급 지난 포스팅은... [교육업무자동화4

www.martinii.fun

 

 

 


donaricano-btn

댓글