블로그

일코

[pyhwpx] 한/글 자동화 문의 및 요청의 90%는 ㅇㅇ 관련이었어요.

안녕하세요? 일코입니다. 유튜브와 블로그를 운영하면서 받았던 문의 중 90%는바로 "표"에 관한 내용들이었습니다.표는 비단 행정뿐만 아니라,한/글을 통해 작성되는 문서에서 가장 많이 쓰이는 컨트롤이죠.그런데 기존의 한/글 오토메이션 API를 통해 표를 읽어오거나, 표를 작성하는 메서드는다소 큰 진입장벽이 있었습니다. 예를 들어 비교적 최근 만든 pyhwpx에서5행5열의 표를 만들고 "글자처럼 취급"을 적용하는 코드는아래 세 줄이면 되지만,from pyhwpx import Hwp hwp = Hwp() hwp.create_table(5, 5, treat_as_char=True) 그런데,기존 오토메이션API를 통해 동일한 표를 직접 생성하려면무려 아래의 코드를 작성해야 합니다.(한/글 오토메이션API에 관심있으신 분은, 차근차근 읽어보셔도 좋습니다.)import win32com.client as win32 hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject") hwp.XHwpWindows.Item(0).Visible = True hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule") rows = 5 # 행 갯수 cols = 5 # 열 갯수 width_type = 0 # 너비: 단에 맞춤 height_type = 0 # 높이: 자동 height = 0 # height 기본값 초기화 treat_as_char = True # 글자처럼 취급 pset = hwp.HParameterSet.HTableCreation hwp.HAction.GetDefault("TableCreate", pset.HSet) # 표 생성 시작 pset.Rows = rows pset.Cols = cols pset.WidthType = width_type # 너비 지정(0:단에맞춤, 1:문단에맞춤, 2:임의값) pset.HeightType = height_type # 높이 지정(0:자동, 1:임의값) sec_def = hwp.HParameterSet.HSecDef hwp.HAction.GetDefault("PageSetup", sec_def.HSet) total_width = (sec_def.PageDef.PaperWidth - sec_def.PageDef.LeftMargin - sec_def.PageDef.RightMargin - sec_def.PageDef.GutterLen - hwp.MiliToHwpUnit(2)) pset.WidthValue = hwp.MiliToHwpUnit(total_width) # 표 너비 if height and height_type == 1: # 표높이가 정의되어 있으면 total_height = (sec_def.PageDef.PaperHeight - sec_def.PageDef.TopMargin - sec_def.PageDef.BottomMargin - sec_def.PageDef.HeaderLen - sec_def.PageDef.FooterLen - hwp.MiliToHwpUnit(2)) pset.HeightValue = hwp.MiliToHwpUnit(height) # 표 높이 pset.CreateItemArray("RowHeight", rows) # 행 m개 생성 each_row_height = total_height - hwp.MiliToHwpUnit(rows) for i in range(rows): pset.RowHeight.SetItem(i, each_row_height) # 1열 pset.TableProperties.Height = total_height pset.CreateItemArray("ColWidth", cols) # 열 n개 생성 each_col_width = total_width - hwp.MiliToHwpUnit(3.6 * cols) for i in range(cols): pset.ColWidth.SetItem(i, each_col_width) # 1열 # pset.TableProperties.TreatAsChar = treat_as_char # 글자처럼 취급 pset.TableProperties.Width = total_width # hwp.MiliToHwpUnit(148) # 표 너비 적용 hwp.HAction.Execute("TableCreate", pset.HSet) # 코드 실행 # 글자처럼 취급 여부 적용(treat_as_char) ctrl = hwp.CurSelectedCtrl or hwp.ParentCtrl pset = hwp.CreateSet("Table") pset.SetItem("TreatAsChar", treat_as_char) ctrl.Properties = pset결과는 위와 동일합니다 고작 표 하나를 만들기 위해질릴만큼 길고 복잡한 저 API코드를 작성해야 한다는 사실을 알게 되면(특히 회사원들) 어느 누가 한/글 자동화를 시도할까 싶었습니다.전부 언급할 수도 없는 상당한 분량의 백그라운드 지식을 알려주는 것도 큰 부담이었습니다.아래아한글 API의 구조와 실행방법, 파라미터셋 사용법,파라미터셋의 서브아이템셋을 정의해야 하는 경우와 정의방법,암호같은 API 문서를 읽는 방법..ㅜ 작년말에 금융감독원 연수원에서 아래아한글 자동화 강의요청을 해 주셨거든요.시간은 짧고, 할 말은 많고, 저런 무지막지한 API 코드 보여주면 재미가 없을 것 같아서현업에 쓰일 법한 함수들을 묶어서 시연 위주로 보여드렸는데,그게 계기가 되어,아래아한글 보고서작성 자동화를 위한pyhwpx라는 파이썬모듈을 개발하게 되었습니다.하여튼 이제는 나름의 버전업을 거듭해서0.8 근처까지 왔는데요. 아직 갈 길이 멉니다.그럼에도 create_table, table_to_df나,table_from_data, get_into_nth_table, 특히 put_field_text는한/글 보고서 취합 및 작성 자동화나 엑셀연동에 진심인 분들에게는정말 파워풀한 메서드일 거라고 자부합니다.개발기간도 아직 짧은 편이고, 다소 조악해 보일 수 있습니다.하지만, 정말 수백 건의 문의와 의뢰를 받고 일일이 회신을 드렸던 모든 경험을pyhwpx 모듈에 하나씩 녹여내고 있습니다.pyhwpx 사용법도 알려주세요! - 인프런현재는 블로그와 인프런 QnA에 pyhwpx 짧은 메서드 사용법 위주로 포스팅하고 있지만,오는 2월부터는 작은 프로젝트나, 의뢰 / 문의내용을 토대로pyhwpx의 활용방법도 차근차근 영상과 포스팅으로 풀어볼 예정입니다.업무자동화에 관심이 있는 파이썬 초보 분들, 특히 직장인 분들많은 관심 부탁드립니다^^ 감사합니다.행복한 하루 되세요!

업무 자동화pyhwpx아래아한글hwppython일상의코딩일코파이썬create_table한컴오피스업무자동화

일코

[python+hwp] 글머리 기호의 모양만 수준별로 바꾸는 파이썬 코드

문단 글머리 기호를 추출하고자 합니다.원래 목적은 문단별 글머리 기호가 다르고 문단별로 각각 다른 폰트를 적용이 목적입니다.GetHeadingString()을 써보니코드를 적용해서 커서를 옮겨도 문서를 최초 불러온 커서의 위치의 글머리 기호를 불러오네요..이유를 몰겟습니다. ㅠㅠ아래는 테스트 코드입니다.(후략)https://www.inflearn.com/questions/809257이 문제는 예를 들어서 설명하는 게 여러모로 좋을 것 같습니다.아래는 제가 임의로 만들어본 예시문서입니다.위와 같은 문서에서 제1수준(숫자로 시작하고 "." 으로 끝나는 문단기호)에는 "진하게(Bold)"를 적용하고제4수준("가나다" 등 문자로 시작하고 ")" 으로 끝나는 문단기호)에는 "기울임(Italic)"을 적용해보겠습니다.import win32com.client as win32 def 한글_시작(): hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject") # 한/글 실행 hwp.XHwpWindows.Item(0).Visible = True # 백그라운드 해제 hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule") # 보안모듈 등록 return hwp def 진하게(): if not hwp.CharShape.Item("Bold"): # 진하게 적용되어 있지 않으면 hwp.Run("CharShapeBold") # 진하게 적용 def 이탤릭(): if not hwp.CharShape.Item("Italic"): # 이탤릭이 적용되어 있지 않으면 hwp.Run("CharShapeItalic") # 이탤릭 적용 if __name__ == '__main__': hwp = 한글_시작() hwp.Run("FileOpen") hwp.Run("MoveDocBegin") # 문서 시작점으로 이동해서 hwp.Run("MoveParaEnd") # 문단 끝으로 이동 para_num = 0 # 0번째 문단에서부터 while True: # 한문단씩 이동하면서 if hwp.GetPos() == (0,0,16): # 0번째 문단으로 돌아오면(!!) # 추가설명 : SetPos 입력시 문서범위를 벗어나서 이동을 시도하면 # 커서가 문서시작위치(0,0,16)로 돌아옵니다. # 이를 이용해 while 문 종료조건을 잡아보았습니다. break # while문 종료 hwp.SetPos(0, para_num, -1) # para_num번째 문단 끝(-1)으로 이동 para_head = hwp.GetHeadingString() # 글머리 추출 # 글머리가 숫자로 시작하고 "."으로 끝나면 if para_head[:-1].isdigit() and para_head.endswith("."): 진하게() # 글머리가 문자로 시작하고 ")"로 끝나면 elif para_head[:-1].isalpha() and para_head.endswith(")"): 이탤릭() # 글머리가 없거나 기타 글머리인 경우 else: pass # 넘어감 para_num += 1 # 다음 문단으로 이동해서 위의 코드 반복주석을 나름 꼼꼼히 달아보았는데,혹시 잘 납득이 안 가는 부분이 있으면댓글로 알려주시기 바랍니다^^실행화면은 아래와 같습니다.우리의 의도대로제1수준은 진하게, 제4수준은 이탤릭이 적용되는 것을 확인하실 수 있습니다.<부연>크게 어렵지 않고, 짧은 코드이긴 하지만..위와 같은 경우에는(여러 개의 한/글 파일을 변경하는 게 아니라면) 기왕이면 코딩을 사용하지 않고,Ctrl-K-N을 통해 문단번호의 글자모양 기본값을 통해문단수준별로 직접 변경하는 게 훨씬 안정적일 것 같기는 합니다^^; 

업무 자동화파이썬아래아한글업무자동화한컴오피스