Type Here to Get Search Results !

02 Go언어:HWP자동화: HWP 실행하기 및 창 보이기



이번에는 Go언어로 HWP를 실행하고 문서 창을 보이는 것을 보여드리려 합니다.


앞서 한컴 오토메이션은 OLE(COM) Object를 이용한다는 것은 알게 되었고, 한컴디벨로퍼 사이트에서 관련 API 매뉴얼을 참조할 수 있다는 것을 알았습니다. 근데, 개발자가 아닌 입장에서 보면 매뉴얼을 보고도 "이걸로 뭘 어쩌라는 것인가?" 하는 생각이 듭니다. 


gohwp package

HWP 자동화 코드를 만드려고 하면 ole를 이용하다보면 생각보다 상당히 귀찮은 일입니다. 몇 번 하다가 도저히 안되겠다 싶어서 패키지를 만들었고 처음으로 github로 배포란 것을 해봅니다. 

gohwp  https://github.com/b612nightsky/gohwp


설치하기

go get github.com/b612nightsky/gohwp


HWP 실행하여 새 문서 창을 띄우기

package main

import (
      "github.com/b612nightsky/gohwp"
)

func main() {
    hwp := gohwp.Initialize()   // 초기화
    defer hwp.UnInitialize()
    hwp.ShowWindow(true)        // hwp문서창 보이기
}

gohwp.Initialize()에서는 HWPFrame.HwpObject 객체를 생성하고 본격적으로 HWP를 다룰 수 있게 하고 있습니다. 프로그램이 종료될 때 정리하기 위해 defer로 UnInitialize()를 실행합니다.

ShowWindow(true)는 실질적으로는 활성화된 HWP 문서창을 화면에 보이게 합니다. false의 경우 백그라운드에서 실행되어, HWP 문서창이 안보입니다.

여기 언급된 Initialize(), UnInitialize(), ShowWindow() 메서드는 한글오토메이션 매뉴얼에 있는 메서드가 아니라, 편의상 만들어진 메서드입니다.


이 아래의 글은 gohwp package 배포 이전에 작성된 것으로 본래 go-ole를 이용해서 HWP 자동화 코드 작성은 어떻게 접근하는지 확인하실 수 있습니다. 기록 차원에서 남겨놓습니다. 윗쪽 코드들만 참조하시고 아래의 코드들은 무시하셔도 됩니다.


HWP 문서 작업을 자동화하려면 일단 HWP를 실행하여 Go언어로 HWP 프로그램에 뭔가 요청을 할 수 있는 상태가 되어야 합니다. 그 예제가 아래와 같습니다.

package main

import (
    "github.com/go-ole/go-ole"
    "github.com/go-ole/go-ole/oleutil"
)

func main() {
    // OLE 시스템 초기화
    err := ole.CoInitialize(0)
    if err != nil {
        panic(err)
    }
    defer ole.CoUninitialize()

    // HWP COM 객체 생성
    hwpCom, err := oleutil.CreateObject("HWPFrame.HwpObject")
    if err != nil {
        panic(err)
    }
    defer hwpCom.Release()

    // IDispatch 요청 및 반환
    hwp, err := hwpCom.QueryInterface(ole.IID_IDispatch)
    if err != nil {
        panic(err)
    }
    defer hwp.Release()
} 

위의 코드에서 OLE 시스템을 초기화, HWP COM 객체(object)를 생성하고, hwp로 선언된 IDispatch를 받아오는 것까지 일단 HWP를 실행하여 HWP와 연결된 상태라고 보시면 됩니다. 여기서 다루는 Go언어 HWP 자동화에서는 저 코드는 기본적으로 반드시 들어갑니다. hwp로 선언된 IDispatch로 한컴 오토메시션에 정의된 함수들을 실행하고, 값을 받아오거나 입력하거나 하게 되는 겁니다.

근데 위의 코드만 작성해서 실행하면 화면에 HWP가 보이지 않습니다. 작업관리자에 들어가서 보시면 분명 실행되어 있을텐데 보이지 않을 겁니다. 백그라운드에서 실행되었기 때문입니다. 


화면에 HWP 문서창이 나타나게 하는 방법은 아래의 코드가 위에서 보인 예제 코드의 main 함수 안에 들어가 있어야 합니다.

// HWP 화면 띄우기
// XHwpWindows 객체 가져오기
xHwpWindows, err := oleutil.GetProperty(hwp, "XHwpWindows")
if err != nil {
panic(err)
 }
defer xHwpWindows.Clear()

// 창 객체 가져오기
window := oleutil.MustGetProperty(xHwpWindows.ToIDispatch(), "Item", 0).ToIDispatch()
defer window.Release()

// 창의 가시성 설정
_, err = oleutil.PutProperty(window, "Visible", true)
if err != nil {
panic(err)
 } 

  • 간략히 설명을 드리면,  HWP 문서창"들"을 관리하는 xHwpWindows라는 객체를 GetProperty 메서드를 이용해 받아옵니다. xHwpWindows 객체는 xHwpWindow라는 HWP 문서창 객체를 하나 또는 여럿 가지고 있게 됩니다. 
  • MustGetProperty 메서드를 이용해서 첫 번째(0) Item으로 있는 문서창 객체를 가져옵니다. 위의 예제에서는 MustGetProperty를 이용했는데, GetProperty를 이용하고 에러 체크를 해도 됩니다.
  • 마지막으로 문서창 객체에는 문서 작업 창을 화면에 보일지 여부를 정하는 Visible이라는 Bool형의 변수가 있습니다. 이를 PutProperty 메서드를 이용하여 true 값을 입력합니다.

Go언어로 HWP를 다루다 보면 go-ole 패키지의 3가지 메서드로 거의 모든 것을 다루게 되는데, 그 중 2가지가 위에서 나왔습니다. 

  • 값을 받아오는 GetProperty
  • 값을 입력하는 PutProperty
  • 함수를 실행하는 CallMethod는 다른 예제에서 다루도록 하겠습니다.


최종적으로 위의 코드들를 합쳐 놓으면 아래와 같습니다.

package main

import (
	"github.com/go-ole/go-ole"
	"github.com/go-ole/go-ole/oleutil"
)

func main() {
	// OLE 시스템 초기화
	err := ole.CoInitialize(0)
	if err != nil {
		panic(err)
	}
	defer ole.CoUninitialize()

	// HWP COM 객체 생성
	hwpCom, err := oleutil.CreateObject("HWPFrame.HwpObject")
	if err != nil {
		panic(err)
	}
	defer hwpCom.Release()

	// IDispatch 인터페이스 요청 및 반환
	hwp, err := hwpCom.QueryInterface(ole.IID_IDispatch)
	if err != nil {
		panic(err)
	}
	defer hwp.Release()

	// HWP 화면 띄우기 시작
	// XHwpWindows 객체 가져오기
	xHwpWindows, err := oleutil.GetProperty(hwp, "XHwpWindows")
	if err != nil {
		panic(err)
	}
	defer xHwpWindows.Clear()

	// 창 객체 가져오기
	window := oleutil.MustGetProperty(xHwpWindows.ToIDispatch(), "Item", 0).ToIDispatch()
	defer window.Release()

	// 창의 가시성 설정
	_, err = oleutil.PutProperty(window, "Visible", true)
	if err != nil {
		panic(err)
	}
	// HWP 화면 띄우기 끝
}
 

여기까지가 Go언어로 HWP를 실행하고 문서 작업창을 화면에 보이는 예제입니다.


잡담.

파이썬을 할 줄 알고, 파이썬으로 동일한 작업을 하는 예제를 보신 분들 위의 Go언어 예제를 보시면 "그냥 파이썬으로 해야겠다" 생각하실 수 있으실 겁니다. 그도 그럴 것이 위와 동일한 작업을 하는 파이썬 코드는 아래처럼 아주 단순합니다.

import win32com.client as win32

hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject")
hwp.XHwpWindows.Item(0).Visible = True

가만히 살펴보면 Go언어로 작성된 예제 코드의 상당 부분은 에러를 체크하거나 defer로 종료 시 해야 할 것들이 매번 들어가 있습니다.

"Go언어로 하지 말고, 파이썬으로 하세요." 하는 글이 될 수 있는 같습니다. 하지만, 업무 자동화 프로그램이란 것이 개인적으로 사용할 때도 있지만, 남들에게도 공유해야 시너지가 날 경우가 많습니다. 이때에는 실행 파일을 만들어서 주는 것이 좋습니다. 프롤로그에서 언급했듯이 저도 파이썬을 주로 사용하고 있지만 pyinstaller로 실행 파일을 만드는 것은 선호하지 않습니다. (pandas 쓰고 뭐하면 용량이 수백 MB가 되곤 하니..)

일단 go-ole 등으로 어떻게 다루는 지 보이기 위해 위와 같이 길게 코드를 작성했습니다. 요즘에는 하나하나 메서드로 만들어 놓아서 파이썬만큼 짧을 코드로 다룰 수 있게 하는 패키지 작업하고 있습니다. 제가 얼마나 자주 글을 올릴지 모르겠지만, 대략 10번째 글을 올릴 때 쯤 되면 비공개 git으로 작업 중인 패키지를 공개하지 않을까 싶습니다.  


댓글 쓰기

0 댓글
* Please Don't Spam Here. All the Comments are Reviewed by Admin.