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

[Q&A](1/3) 제목을 {문서첫줄}.hwp로 저장하는 가장 쿨한 방법

by 일코 2022. 1. 14.

안녕하세요? 상의 딩, 일코입니다.

질문을 읽어보니 대략 이런 상황인 것 같습니다.

 

1. 아래와 같은 내용의 파일이 있고,

2. 이걸 아래와 같이 만들고 싶으신 것 같습니다.

여기서 잠깐 이 생각을 해 봅시다.

여러분은 아래 두 가지 중 어떤 게 좋은 방식이라고 생각하시나요? (물론 호불호일 뿐, 정답은 없다고 생각합니다.)

 

① 따로따로 만들어 각각 실행하기!?

    우선 다 잘라서 저장하는 프로그램을 하나 만들고, 파일명을 변경하는 프로그램을 별도로 만든다.

    예를 들면 간단히 페이지 번호대로 1.hwp, 2.hwp, 3.hwp ... 저장하는 식으로.

    그 후에 파일명을 변경하는 코드를 따로 만든다. (1.hwp부터 하나씩 열어서 "첫 번째 페이지입니다.hwp" 방식으로)

 

② 원클릭으로 끝까지 한 번에!?

    애초에 처음에 파일을 읽을 때부터 첫 줄을 저장해 두고,

    hwp.SaveAs({파일명}.hwp) 등 상황에 딱 맞는 명령어를 찾아서 하나의 프로그램으로 완성한다.

 

저는 예전엔 ②번처럼 한큐에 완성되는 방식을 굉장히 선호했는데,

요즘은 ①번 방식으로 코드를 짜는 게 훨씬 뭐랄까.. 효율적이기도 하고, 재활용하기도 쉬운 것 같아요.

 

그런 맥락에서, 이번에 소개하는 코드는 좀 특별히 win32com을 사용하지 않고,

olefile이라는 모듈을 사용해서 진행을 해보겠습니다.

(한/글 공식 홈페이지에 공개되어 있는 한/글문서 포맷을 사용한 방식입니다.)

우선 olefile이라는 모듈이 설치되어 있어야 합니다.

커맨드프롬프트나 가상환경 콘솔에서 아래의 명령어를 실행해 주시기 바랍니다.

pip install olefile

그러면 아래와 같이 설치됩니다.

pip install olefile

이제 에디터를 열어 코드를 입력해봅시다.

1. 문서파일의 첫 줄을 읽어오는 "첫줄읽기" 함수입니다.

from olefile import OleFileIO


def 첫줄읽기(filepath):
    """한/글 문서 텍스트를 불러와서 엔터(\r\n)로 쪼갠 후 첫 번째 행 리턴"""
    with OleFileIO(filepath) as ole:  # 한/글 파일 불러오기
        text = ole.openstream('PrvText').read().decode('UTF-16').split("\r\n")[0]
    return text

이 코드가 궁금하신 분들을 위해 네 가지만 부연설명을 드리겠습니다.

궁금하지 않으신 분들은 건너뛰세요!


① 한/글 파일의 구조는 OLE, 즉 윈도우즈의 복합파일(Compound File)의 구조를 그대로 따릅니다.

정확히는 한/글 2002 이후 문서의 구조가 그렇다는 것입니다. 한/글 3.0 등 이전 버전 문서의 포맷은 다소 다릅니다.

복합파일을 구성하는 방식인 OLE(Object Linking & Embedding)를 사용하는 파이썬 모듈이 olefile입니다.

한글문서파일형식_5.0_revision1.3.hwp 중 7페이지 


② 한/글을 (win32com으로) 열지 않고도 텍스트 정보를 가져올 수 있는 방법이 있는데,
바로 "PrvText"라는 이름의 "스트림"에 저장된 "미리보기 텍스트"를 이용하는 겁니다.

한글문서파일형식_5.0_revision1.3.hwp 중 7페이지 


③ 그런데 미리보기 텍스트를 가져와서 읽으려면 해독(디코딩) 과정이 필요합니다. 한/글 파일 안에는 암호처럼 2진수의 숫자로만 저장되어 있으니까요. 이걸 해독할 때 사용해야 하는 규칙은 자주 들어보신 적 있는 유니코드, UTF-16LE입니다.
그 때문에 read() 메서드 뒤에 decode("UTF-16") 를 붙였습니다.

 

④ 텍스트를 불러오긴 했는데, 아래 이미지처럼 한 줄의 문자열입니다.

줄바꿈은 모두 "\r\n"이라는 문자로 치환되어 있어요.

정확히는 치환이 아니라, "\r\n"이 줄바꿈 그 자체입니다. 이 부분이 궁금하시면 "탈출문자열"로 구글링해보시길ㅎ

하여튼, 이 문자열을 "\r\n"으로 잘라서(split) 리스트로 만든 후에 0번 인덱스에 접근하면([0]) 우리가 원하는 첫 번째 라인의 문자열을 얻을 수 있겠죠?

디코딩 없이 텍스트를 읽는 것은 사실상 불가능!
UTF-16으로 디코딩하자, 읽을 수 있게 됨. ("\r\n"은 줄바꿈이라는 의미)
문서 첫 번째 라인 읽어오는 데 성공!

대략 이 함수가 어떻게 작동하는지 구체적으로 알아보았습니다.

그럼 이 함수를 어떻게 사용할지 다음 포스팅에서 간단한 파일선택 GUI도 붙여서 완성해봅시다!^^

 

다음 포스팅은,

 

[Q&A] hwp파일을 페이지별로 나눈 후, 제목을 {문서첫줄}.hwp로 저장하는 가장 간단한 방법[2/3]

안녕하세요? 일상의 코딩, 일코입니다. 두 번째 시간입니다. 지난 시간에는 한/글을 열지 않고도 첫 줄을 불러오는 함수를 소개해드렸습니다. def 첫줄읽기(filepath): """한/글 문서 텍스트를 불러와

martinii.fun

 

댓글