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

파이썬으로 한/글의 용지규격과 방향을 조회할 때

by 일코 2021. 7. 5.

베두인님께서 방명록에 남겨주신 글

 


 

 

현재 용지속성을 조회만 하고 싶다면?

안녕하세요 한글문서관련 프로그램을 작성하는 개발자 입니다. 우연히 한컴 개발커뮤니티에서 “현재 용지정보 가져오기 PageSetup” 관련 답변을 달아 놓으신 걸 검색 했습니다. 다름이 아니라

www.martinii.fun

 

위 포스팅을 조금 활용해서, 현재 용지의 사이즈와 방향(가로/세로)을 출력하는 함수를 만들어보겠습니다.

전체 코드는 아래와 같습니다. 가급적 모든 과정을 함수로 작성하였으므로,

하나씩 뜯어보시면 이해하기 쉬울 것입니다.

 

import win32com.client as win32

용지크기 = {
    (210, 297): "A4",
    (297, 420): "A3",
    (257, 364): "B4",
}


def 한글시작():
    hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
    hwp.XHwpWindows.Item(0).Visible = True
    return hwp


def hwp_unit_to_mili(hwp_unit):
    return round(hwp_unit / 7200 * 25.4)


def 용지종류(한글):
    Act = 한글.CreateAction("PageSetup")
    Set = Act.CreateSet()
    Act.GetDefault(Set)
    용지너비 = hwp_unit_to_mili(Set.Item("PageDef").Item("PaperWidth"))
    용지높이 = hwp_unit_to_mili(Set.Item("PageDef").Item("PaperHeight"))
    용지규격 = 용지크기[(용지너비, 용지높이)]
    용지방향 = ["가로" if (용지너비 < 용지높이) else "세로" for _ in [(용지너비, 용지높이)]][0]
    result = f"용지규격은 {용지규격}, 용지방향은 {용지방향}입니다."
    print(result)
    return result


if __name__ == '__main__':
    한글 = 한글시작()
    용지종류(한글)

메인 파트에서 실행하는 함수는 두 개인데, 한글시작()과 용지종류(한글)입니다.

이해를 돕기 위해 몇 가지 설명을 덧붙이면,

 

1. HwpUnit

한/글에서 모든 길이단위는 HwpUnit(이하 HU)이라는 단위를 사용하며,

1HU 는 1/7,200 인치입니다.

꽤 작은 단위라서 숫자가 대부분 상당히 크게 나옵니다. 계산해보면

210 mm는 59,528 HU이고, 297mm는 무려 84,186 HU 입니다.

한/글에서는 기본적으로 HU를 밀리미터와 포인트로 변환하는 두 가지 함수를 제공하는데

밀리미터나 포인트, 혹은 인치 단위를 HU로 변환하는 것도 번거로우므로

일반적으로는 HwpUnitToMili 등의 헬퍼함수를 직접 작성해서 활용하면 간편합니다. (16번라인 참고)

아래 포스팅은 HwpUnit을 사용해서 이미지 사이즈를 조정하는 예제이므로 참고하시기 바랍니다.

 

HWP여백조정 후 이미지 너비/높이를 폭에 맞게 일괄조정하는 방법

HWP포맷을 사용하는 소규모의 출판사가 의외로 많다는 걸 최근들어 알게 되었다. 그도 그럴 것이, 인디자인이나 퍼블리셔 같은 프로그램 없이도 직접 책을 출판하고 SNS로 홍보할 수 있는 시대가

www.martinii.fun

 


 

2. CreateAction, CreateSet, GetDefault, Execute

위에 나열한 메서드는 한/글에서 특정 액션을 실행하거나 속성을 조회할 때 사용합니다.

API매뉴얼을 직접 참고하셔도 좋고, 제 포스팅 대부분은 위 메서드를 사용하므로 다른 포스팅을 참고하셔도 됩니다.

위 코드 20번라인부터 보면,

 

Act = 한글.CreateAction("PageSetup"

PageSetup이라는 액션을 생성합니다. "액션"이란 한 개의 동작을 수행하는 일종의 명령어인데,

재미있는 것은 이게 "이름"만 붙은 일종의 "빈 그릇"이라는 겁니다. 초기화를 해 주는 느낌이죠.

여기에 파라미터가 필요한 경우에는 아래의 CreateSet 명령을 추가로 실행해서 파라미터셋도 만들어줍니다.

 

Set = Act.CreateSet()

Act 안에다 Set이라는 파라미터셋을 생성합니다. Set도 마찬가지로 현재는 값이 부여되지 않은 빈 그릇입니다.

파라미터셋 안에 액션실행에 필요한 최소의 파라미터만 입력하고 Execute를 입력하면, 해당 값으로 액션을 실행합니다.

 

Act.GetDefault(Set)

이 명령어를 실행하는 시점에야, 현재 문서에 부여되어 있거나 설정되어 있는 값들이 Set 안에 들어갑니다.

현재 용지속성을 조회만 하려면 Execute를 생략하고, Set의 아이템을 직접 조회하면 됩니다.

(Set값을 변경하고 적용하려면 Execute를 실행하면 됩니다. 이번 예제에서는 조회만 하므로 Execute를 쓰지 않습니다.)

 

Set.Item("PageDef").Item("PaperWidth")

Set.Item("PageDef").Item("PaperHeight")

각각 용지너비와 용지규격을 리턴하는 명령어입니다.

CreateAction 때와 마찬가지로, 아이템셋의 이름을 문자열로 지정한다는 점이 특이한데,

사실 이것 때문에 VSCode나 파이참에서도 코드자동완성이 어렵고,

수시로 API문서를 들여다봐야 한다는 아쉬움이 있습니다.

그럼에도 API문서를 검색하는 데 조금만 익숙해지면, 금방 찾아서 작성할 수는 있습니다.

한가지 꼼수로 스크립트매크로 녹화를 후딱 돌려서 필요한 아이템의 이름을 조회할 수도 있습니다.

 


 

I. 스크립트매크로로 아이템아이디 찾는 방법, 이 참에 한 번 같이 해보실까요?

 

1. 한/글을 열고

한/글2020을 열었습니다.

2. 스크립트매크로 녹화(Shift-Alt-H)를 실행합니다. 저는 5번에 임시로 저장해보겠습니다.

스크립트매크로 녹화 시작

 

3. 녹화상태에서 편집용지설정(F7)을 누르고 상단의 길이만 임의로 수정한 후 설정(D)을 누릅니다.

폭과 길이에 10mm씩 더했습니다.

 

 

 

4. 스크립트 녹화를 종료(Shift-Alt-X)한 후, 바로 Shift-Alt-L, Alt-C를 눌러 해당 스크립트를 열어봅시다.

붉은 네모 안의 파라미터가 우리가 원하는 문자열입니다.

점으로 구분된 건 파라미터셋이 2중이라서 그렇습니다.

코드를 보면 Set의 "PageDef" 아이템 안에 있는 "PaperWidth"와 "PaperHeight"라는 아이템이

용지의 너비값을 가진 파라미터라는 걸 알 수 있습니다.

 

II. API 매뉴얼을 직접 찾아보는 과정도 내친김에 같이 해보실까요?

1. 액션테이블 문서(Action Table.hwp)를 열고 "용지"로 검색해봅시다.

23쪽에 한 개 나오네요.

PageSetup 액션의 파라미터셋 아이디는 SecDef 라고 나옵니다.

2. 파라미터셋 테이블 문서(ParameterSet Table.hwp)를 열고 SecDef를 찾아봅시다.

117쪽에 있습니다.

용지 설정 정보는 PageDef라는 서브타입 안에 있다고 하네요?

3. 용지설정 정보는 SecDef의 서브타입인 PageDef 셋으로 설정이 가능하다고 합니다.

다시 PageDef를 찾아가보겠습니다. (같은 문서 97쪽입니다.)

용지 가로 크기, 용지 세로 크기 및 방향과 각종 여백에 대한 아이템아이디가 나옵니다.

4. 찾은 정보를 조합해보면,

① 용지설정에 필요한 액션아이디는 "PageSetup"이므로 이 액션아이디를 통해 액션과 빈 파라미터셋을 생성합니다.

 

Act = 한글.CreateAction("PageSetup")
Set = Act.CreateSet()

② GetDefault를 실행해서 현재 값을 셋 안에 넣습니다.

 

Act.GetDefault(Set)  # 초기화

 

③ 용지설정에 필요한 파라미터셋 아이디는 SecDef / PageDef / PaperWidth, PaperHeight 인데,

Set.Item("SecDef")를 실행해보면 None을 리턴합니다. (뭔가 잘못된 거겠죠?)

 

Set.Item("SecDef")  # == None

 

④ 서브타입이 있는 경우 이 방식으로 조회를 할 때는 아래 코드처럼 바로 서브타입의 아이디로 건너뛰면 됩니다.

 

Set.Item("PageDef").Item("PaperWidth")   # == 59,528  : 용지너비HU
Set.Item("PageDef").Item("PaperHeight"# == 84,186 : 용지높이HU

 

⑤ 리턴되는 값들은 HU 단위이므로 mm로 변환해서 확인하면 됩니다.

 

round(59,528 / 7,200 * 25.4)  # == 210

round(84,186 / 7,200 * 25.4)  # == 297

 

전체코드 시연영상

용지규격과 방향을 출력합니다.

하위부서나 소속기관들의 한/글 보고자료를 자주 취합하시는 분들이라면 

조금만 응용해서 컴파일해놓으면 업무중에 종종 사용하실 수 있겠습니다.

여백이나 용지설정이 원래 배포한 서식과 다르지 않은지 금방 테스트해본다든지 말이죠.

 

그럼 이번 포스팅은 여기서 마칩니다.

행복한 하루 되세요^^

 

 


donaricano-btn

댓글