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

4. 문서여백을 파이썬으로 바꿀 수 있을까?

by 일코 2020. 8. 12.

안녕하세요?

한/글 자동화 응용편에 보시면, 한/글에서 녹화한 스크립트 매크로와 API매뉴얼의 기본적인 액션 생성 방법 두 가지 문법을 보여드렸습니다.

 

[파이썬-아래아한글] API매뉴얼과 스크립트매크로가 다르다?

안녕하세요? 회사원코딩의 신명진입니다. 이번 포스팅은, 스크립트매크로와 API매뉴얼 코드의 차이에 대해서 한 번 보여드리려고 합니다. 어떤 간단한 예제를 들어볼까 하다가, 쪽번호 감추기를

www.martinii.fun

문법에는 다소 차이가 있는 느낌이지만, 기본적인 실행방법은 동일했어요.

1. 액션을 생성한다.

2. 파라미터셋을 만든다. 필요한 경우 초기화하거나 설정값을 변경한다.

3. 액션을 실행한다.

 

이번 포스팅에서는 같은 순서로 페이지 여백을 조정하는 방법을 같이 따라해보겠습니다.

우선 스크립트 매크로를 녹화하는 방법입니다.

파이썬 문법에 익숙하지 않거나, 한/글 API문서를 참고하지 않아도 만들어낼 수 있는 코드입니다.

1. 스크립트매크로 녹화를 실행한다. (Shift-Alt-H)

스크립트 매크로 녹화(Shift-Alt-H)

아무 슬롯이나 선택하고 엔터를 누르거나 정의(Alt-D) 버튼을 누르면 녹화가 시작됩니다.

Overwrite? (Y/N)

2. 해당 액션을 수행한다.

페이지의 모든 여백과 머릿말, 꼬릿말의 높이를 0으로 바꾸는 과정입니다.

편집용지(F7)를 누르고 모든 여백을 0으로 바꿉니다.

모든 용지여백을 0으로 바꾸고 엔터나 설정버튼(Alt-D)을 누른다.

3. 스크립트 매크로 녹화를 종료(Shift-Alt-X)한다. (한/글 2007에서는 Shift-Alt-H를 다시 누르면 녹화종료)

4. 스크립트매크로 실행(Shift-Alt-L)을 열고, 해당 슬롯에서 "코드 편집(Alt-C)"을 누른다.

여기서 Alt-C를 누르면 스크립트를 볼 수 있다.

 

자바스크립트 문법으로 작성된 스크립트입니다. 아래와 같습니다.

function OnScriptMacro_script3()
{
	HAction.GetDefault("PageSetup", HParameterSet.HSecDef.HSet);
	with (HParameterSet.HSecDef)
	{
		HSet.SetItem("ApplyClass", 24);
		HSet.SetItem("ApplyTo", 3);
		PageDef.LeftMargin = MiliToHwpUnit(0.0);
		PageDef.RightMargin = MiliToHwpUnit(0.0);
		PageDef.TopMargin = MiliToHwpUnit(0.0);
		PageDef.BottomMargin = MiliToHwpUnit(0.0);
		PageDef.HeaderLen = MiliToHwpUnit(0.0);
		PageDef.FooterLen = MiliToHwpUnit(0.0);
	}
	HAction.Execute("PageSetup", HParameterSet.HSecDef.HSet);
}

위 코드를 에디터에 붙여넣고 다음과 같이 수정합니다. (with문을 수정하고, 모든 구문의 앞에 hwp를 넣습니다.)

완료된 파이썬 코드는 아래와 같습니다.

import win32com.client as win32  # 모듈 임포트
hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")  # 한/글 열기
hwp.XHwpWindows.Item(0).Visible = True  # 숨김해제

hwp.HAction.GetDefault("PageSetup", hwp.HParameterSet.HSecDef.HSet)  # 액션생성
hwp.HParameterSet.HSecDef.HSet.SetItem("ApplyClass", 24)  # 적용범위 구분. 없어도 됨
hwp.HParameterSet.HSecDef.HSet.SetItem("ApplyTo", 3)  # 적용범위. 필수
hwp.HParameterSet.HSecDef.PageDef.LeftMargin = hwp.MiliToHwpUnit(0.0)  # 파라미터셋 설정
hwp.HParameterSet.HSecDef.PageDef.RightMargin = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HSecDef.PageDef.TopMargin = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HSecDef.PageDef.BottomMargin = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HSecDef.PageDef.HeaderLen = hwp.MiliToHwpUnit(0.0)
hwp.HParameterSet.HSecDef.PageDef.FooterLen = hwp.MiliToHwpUnit(0.0)
hwp.HAction.Execute("PageSetup", hwp.HParameterSet.HSecDef.HSet)  # 해당액션 실행(파라미터셋 적용)

 

코드가 길고 복잡해 보이지만, 직접 작성하는 게 아니고 붙여넣는 코드니까 그러려니 합시다.

그래도 몇 가지 궁금한 부분들이 있을 것 같아요.

- 모든 구문의 앞에 hwp를 다 붙여줘야 하는 이유는, 위의 자바스크립트 코드는 해당 객체나 함수가 모두 미리 정의되어 있는데, 파이썬에서는 그것들이 전부 hwp라는 COM오브젝트 안에서 메서드나 속성의 형태로 정의되어 있기 때문이에요.

- hwp.MiliToHwpUnit() 메서드를 쓰는 이유는, 한/글에서는 페이지나 크기, 위치를 설정할 때 내부적으로는 모두 HwpUnit이라는 단위로 변환해서 입력하기 때문이에요. 참고로 1mm는 283HwpUnit이에요. 이와 유사한 메서드로는 hwp.PointToUnit() 이라는 메서드도 있어요. 이건 폰트크기나 문단여백 등을 설정할 때 주로 사용하는 단위인데 1포인트는 100HwpUnit이에요.

그럼 파이썬 코드를 만들었으니 테스트해볼까요?

(전) 기본 여백에서
파이참 에디터에서 해당 코드를 선택하고 선택실행(Shift-Alt-E)을 누르면 True를 반환하면서
(후) 짜잔~ 한/글 문서의 모든 여백이 바로 0으로 바뀌었습니다.

간단하죠?

이번에는 스크립트 매크로가 아니라, API 문서를 직접 참고하는 방식으로 코드를 작성해보겠습니다.

1. 우선 API 문서 중 Action Table.hwp 를 열어서 편집용지를 설정하는 액션의 이름이 뭔지 검색합니다.

"용지"로 검색하자 단번에 나옵니다. 23페이지에 있습니다.

액션 아이디는 "PageSetup"이고, 파라미터셋 아이디는 "SecDef"네요.

2. 그럼 이번엔 ParameterSet Table.hwp 파일을 열어서 해당 파라미터셋 아이디인 "SecDef"로 검색해봅니다.

그런데 찾고 보니 서브타입이 필요합니다.

SecDef의 아이템 아이디를 전부 읽어봐도 "여백"을 조정하는 아이템들이 안 보입니다. 가만 읽어보니 PageDef라는 서브타입의 파라미터셋이 용지 설정 정보 셋이라고 합니다. "PageDef"로 다시 검색해봅시다.

드디어 찾았어요. 용지 여백을 설정할 수 있는 파라미터셋!

코드작성에 필요한 액션아이디, 파라미터셋 아이디, 서브셋 아이디를 모두 찾았으니까, 이제 코드를 직접 작성해봅시다. 한/글 API 중 주요 메서드에는 C++이나 VB, Javascript 등으로 예제 코드를 적어둔 것들이 있어요. API 매뉴얼 중 파라미터셋에는 이 메서드에 대해 아래와 같은 C++ 예제가 기록되어 있습니다.

{
	DHwpAction dact = m_cHwpCtrl.CreateAction("PageSetup");
	DHwpParameterSet dset = dact.CreateSet();
	dact.GetDefault(dset);
		
	dset.SetItem ("ApplyTo", (COleVariant)(long)3);
	DHwpParameterSet _dset = dset.CreateItemSet ("PageDef", "PageDef");

	// 1mm = 283.465 HWPUNITs
	_dset.SetItem ("TopMargin", (COleVariant)(long)5668);
	_dset.SetItem ("BottomMargin", (COleVariant)(long)5668);
	_dset.SetItem ("LeftMargin", (COleVariant)(long)2834);
	_dset.SetItem ("RightMargin", (COleVariant)(long)2834);
	_dset.SetItem ("HeaderLen", (COleVariant)(long)1417);
	_dset.SetItem ("FooterLen", (COleVariant)(long)1417);
	_dset.SetItem ("GutterLen", (COleVariant)(long)0);

	dact.Execute(dset);
}

다른 매뉴얼 중 하나인 HwpCtrl API.hwp에는 위 예제가 Visual Basic으로도 기록되어 있습니다.

Set act = ACTIVEXHWP.CreateAction("PageSetup")
Set set = act.CreateSet()
Set pset = set.CreateItemSet("PageDef","PageDef")		
act.GetDefault(set)
set.SetItem "ApplyTo", 3	' 적용범위 : 문서전체

' 1mm = 283.465 HWPUNITs
pset.SetItem "TopMargin", 3401
pset.SetItem "BottomMargin", 5669
pset.SetItem "LeftMargin", 4251
pset.SetItem "RightMargin", 4251
pset.SetItem "HeaderLen", 0
pset.SetItem "FooterLen", 0
pset.SetItem "GutterLen", 0
act.Execute(set)

그럼 이번엔 파이썬 코드를 보여드리겠습니다. 위의 코드들과 차이가 많이 나는지 읽어보시기 바랍니다.

(위와 마찬가지로 임포트 구문은 생략했습니다.)

act = hwp.CreateAction("PageSetup")
pset = act.CreateSet()
act.GetDefault(pset)
pset.SetItem("ApplyTo", 3)

item_set = pset.CreateItemSet("PageDef", "PageDef")

item_set.SetItem("TopMargin", 0)
item_set.SetItem("BottomMargin", 0)
item_set.SetItem("LeftMargin", 0)
item_set.SetItem("RightMargin", 0)
item_set.SetItem("HeaderLen", 0)
item_set.SetItem("FooterLen", 0)
item_set.SetItem("GutterLen", 0)

act.Execute(pset)

이 코드에서 변수명은 문맥이 이해되는 선에서 자유롭게 변경하셔도 괜찮지만, 파이썬 기본 자료형 중에 set가 있다는 점을 감안하면, 파라미터셋은 가급적 set로 변수명을 정하지는 말고, dset이든 pset이든 중복되지 않는 이름으로 정의하는 게 좋겠다는 생각입니다.

테스트해보니 역시 잘 작동합니다.

 

덧)

페이지여백 조정기능은, 아래아한글 버전업이 되면서 자동화에 잘 쓰이지 않는 기능이 되는 느낌입니다. 왜냐면, 현재 2018 이상의 버전에서는 "페이지 복사" 기능이 생겨서 여백이나 페이지 방향까지 깔끔하게 복사를 해 주고요, 저런 길쭉한 코드로 새 문서를 생성할 필요 없이 빈 파일을 하나 만들어놓고 코드 내에서 복사해서 쓰는 걸 선호하는 분들도 있겠죠.

그럼에도 여백 기능을 활용할 수 있는 재미있는 예제들이 많은 것도 사실입니다. 파이썬 스크립트로 한/글 파일을 동적으로 생성하고 속성을 명시적으로 정의할 수 있어 오히려 간편해지는 부분도 있고요.

조만간 기본예제들 몇 개를 조합해서, 실제로 활용할 수 있는 사례를 하나씩 포스팅하려고 합니다. 기대해주세요!

 

그리고 긴 글 읽어주셔서 감사합니다.

행복한 하루 되세요!^^

댓글