제목이 거창해 보이지만 사실 굉장히 간단한 프로세스입니다.
1. hwp를 hwpx로 포맷변환(다른 이름으로 저장)
2. hwpx파일 압축해제 이러면 제목이랑 똑같잖아!ㅜ
위 두가지 기능을 각각 구현해보겠습니다.
1. 다른이름으로 저장
한글에서 제공하는 API를 형식별로 크게 나누면 네 가지 정도가 있습니다.
①일반적인 메서드, ②프로퍼티, ③파라미터가 필요한 액션, 그리고 ④파라미터가 필요없는 액션
다른이름으로 저장하기 기능은 함수 형태의 메서드로도 구현되어 있습니다. hwp.SaveAs(파일명, 포맷)입니다.
import win32com.client as win32
FILE_PATH = r"C:\Users\smj02\OneDrive\바탕 화면\빈 문서1.hwp"
hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject") # 한/글 실행
# hwp.XHwpWindows.Item(0).Visible = True # 백그라운드 작업
hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule") # 보안팝업 자동클릭
hwp.Open(FILE_PATH) # 문서 불러오기
hwp.SaveAs(hwp.Path+"x", "HWPX") # hwpx로 저장(두 번째 파라미터가 포맷)
hwp.Quit() # 한/글 종료
고작 대여섯 줄의 코드지만, 훌륭한 hwp-hwpx 변환기가 만들어졌습니다.
이 프로그램을 실행하면 제 바탕화면에 "빈 문서1.hwpx" 파일이 생성됩니다.
이제 한/글 프로그램이 필요없게 되었으니 hwp.Quit()을 통해 한/글은 종료해줍니다.
2. 확장자 바꾸기
파이썬으로 hwpx 파일의 압축을 해제하려면 굳이 확장자를 zip 등을 바꾸지 않아도 됩니다.
파이썬 내장모듈 중 압축파일을 다루는 zipfile의 ZipFile 클래스를 통해 문서를 불러오고
extractall 메서드로 압축을 해제하겠습니다.
이 때 path 파라미터로 경로를 지정해주면 해당 path 안에 압축이 해제됩니다.
그리고 이제 필요없는 hwpx 파일은 os.remove 함수를 통해 삭제해주겠습니다.
이제 코드를 보여드리겠습니다.
import os
import zipfile
os.chdir(os.path.dirname(FILE_PATH)) # 파일경로 중 경로만 추출해서 그 경로로 이동
target_path = os.path.join(os.getcwd(), "hwpx") # 압축 풀 하위폴더는 "./hwpx"
with zipfile.ZipFile(FILE_PATH + "x", 'r') as zf: # 압축파일 인스턴스를 생성하고
zf.extractall(path=target_path) # target_path 안에 압축해제
os.remove(FILE_PATH + "x") # hwpx 파일은 단호하게 삭제함
실행해보면
짜잔! 압축이 해제되었습니다.
이제 저 코드 두 개를 각각 함수로 묶고 정리해보면 아래와 같은 최종 코드가 만들어집니다.
import os
import tkinter as tk
import zipfile
from tkinter.filedialog import askopenfilename
import win32com.client as win32
# FILE_PATH = r"C:\Users\smj02\OneDrive\바탕 화면\빈 문서1.hwp"
def 파일선택(): # 파일선택 GUI 추가
win = tk.Tk()
win.withdraw()
file_path = askopenfilename(title="스타일이름을 추출할 한/글 파일을 선택해주세요.",
initialdir=os.getcwd(),
filetypes=[("한/글 파일", "*.hwp *.hwpx")])
return file_path
def hwpx로_저장(path):
hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject") # 한/글 실행
# hwp.XHwpWindows.Item(0).Visible = True # 백그라운드 작업
hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule") # 보안팝업 자동클릭
hwp.Open(path) # 문서 불러오기
hwp.SaveAs(hwp.Path + "x", "HWPX") # hwpx로 저장
hwp.Quit() # 한/글 종료
def 압축해제(path):
os.chdir(os.path.dirname(path)) # 파일경로 중 경로만 추출해서 그 경로로 이동
target_path = os.path.join(os.getcwd(), "hwpx") # 압축 풀 하위폴더는 "./hwpx"
with zipfile.ZipFile(path + "x", 'r') as zf: # 압축파일 인스턴스를 생성하고
zf.extractall(path=target_path) # target_path 안에 압축해제
os.remove(path + "x") # hwpx 파일은 단호하게 삭제함
if __name__ == '__main__':
문서 = 파일선택()
hwpx로_저장(문서)
압축해제(문서)
정리하고 나니까 훨씬 간결해진 느낌이네요.
마지막으로 위 프로그램을 실행해보겠습니다.
의도한 대로 한방에 실행이 되었네요.
이번 포스팅에서 보여드린 코드는 크게 세 가지였습니다.
① 파이썬 코드 안에 경로를 직접 넣지(하드코딩하지) 않고 tkinter GUI로 파일을 직접 선택하게 함
② 백그라운드의 한/글 프로그램을 통해 hwp -> hwpx 변환
③ zipfile 모듈을 통해 hwpx 파일 압축해제
그럼 이어지는 포스팅에서는
파이썬의 xml 모듈로 xml 문서를 파싱하기 위해 필요한 몇 가지 기능들을 먼저 알려드리고,
hwpx를 압축해제한 파일 중 ./Contents/header.xml 파일을 실제로 파싱해보면서
스타일목록을 찾는 방법까지 알아보겠습니다.
수고하셨습니다.
코드와 움짤을 다 찍어서 아쉬운 대로 포스팅을 맺기는 하지만,
개인적으로 수정이 필요하다고 생각되는 부분이 몇 군데 있습니다.
그게 어느 부분이냐면,
①먼저 여러 파일의 스타일을 추출하고 싶을 때 이 프로그램을 여러 번 실행할 게 아니라
askopenfilenames를 통해 파일을 여러 개 선택하게 하고 싶습니다.
②그러면 이하 과정은 for문 안에 넣어줘야 할 거고,
③압축이 해제되는 하위경로도 "hwpx"로 하드코딩할 게 아니라
문서이름을 그대로 하위경로로 사용하면 될 것 같기도 합니다.
종국에 가서는 완성할 코드에 이 부분을 반영할 예정입니다.
'아래아한글 자동화 > python+hwp 중급' 카테고리의 다른 글
[HDMI] 본격적으로 xml 파헤쳐보기 (0) | 2022.12.07 |
---|---|
[HDMI] 빈 문서1.hwpx를 분해해보면 (0) | 2022.12.07 |
[hwpx 분석하기] HDMI 시리즈를 시작하며 (0) | 2022.12.07 |
댓글