
직장인에게 꼭 필요한 파이썬-아래아한글 자동화 레시피
₩99,000
17시간만
30%
₩69,300
초급 / Python, 한컴오피스
4.9
(44)
파이썬으로 아래아한글을 다루는 기본사용법과 예제를 소개합니다. 텍스트와 움짤로 빠르게 이해하고, 실습은 동영상으로 따라하면서 아래아한글 자동화의 기초를 재미있게 익혀봅시다.
초급
Python, 한컴오피스
안녕하세요?
일상의코딩 블로그를 운영중인 일코입니다.
업무자동화와 관련한 콘텐츠 제작 및 강의 등을 하고 있습니다.
업무자동화 교재를 몇 권 읽고 난 후,
자기업무를 코딩으로 자동화할 때는
새롭고 생소한 난관에 거의 무조건 빠지게 될 겁니다.
실무의 세상은 너무 다양하고, 또 예측하기 힘드니까요.
그래서 멘토링이 필요한 때가 분명히 찾아온다고 생각합니다.
제한적인 교재나 영상의 한계에 갇히지 마시고
본인의 무한한 상상력을 코드로 옮길 수 있도록
생각의 장벽을 허물어드릴 수 있는
가치있는 코칭과 멘토링을 제공해드리겠습니다.
저는 파이썬-아래아한글 및 엑셀 자동화 7년차, 현재는 프리랜서이며
300여 건의 크고작은 자동화 프로젝트를 진행해 왔습니다.
특히 공공기관 행정업무나, 학교, 학원 등
아래아한글과 엑셀을 주로 다루는 분야에서
업무를 효율적이고 빠르게 처리하기 위한 프로그램을 주로 제작해 왔으며
최근에는 스마트스토어, 쿠팡윙스, 카카오쇼핑하기 등의 서비스에서
다양한 정보를 크롤링하고 자동으로 보고서를 제작하는 서비스를 제공하고 있습니다.
여러분이 당면한 문제에 대해
언제든 자유롭게 상담요청 해주시기 바랍니다.
저도 온 마음으로 여러분의 문제를 경청하고
미약하지만 제 수준에서 도움드릴 수 있는 부분을 찾아보겠습니다.
감사합니다.
질문&답변
스크립트 매크로 초기화 하고 싶습니다.
kun님 안녕하세요?1. 아래와 같은 방법으로 우회하면 가능합니다. 아래아한글 프로그램을 통해 해당 파일을 hwpx 포맷으로 저장한다.확장자를 zip으로 바꾸고 압축을 해제한다.Scripts 폴더의 sourceScripts 파일을 삭제한다.다시 zip 포맷으로 압축한 후, 확장자를 hwpx로 바꾼다.다시 아래아한글 프로그램을 통해 원래 포맷으로 변환한다. 2. 팝업을 띄우지 않는 방법은 해당 팝업은 [Y/N] 타입으로 hwp.SetMessageBoxMode(0x20)코드를 미리 실행하여 "No"를 자동선택할 수 있습니다. 파이썬으로는 zipfile 등의 모듈로 압축해제 및 압축시 문제없이 해결이 됨을 확인하였습니다. 아래는 후다닥 작성해본 관련 주피터노트북 파일입니다.문서스크립트를 제거할 hwp 파일들이 있는 폴더 안에 넣고셀 하나씩 실행하시면 됩니다. [노트북 파일] 추가 문의 있으시면 자유롭게 댓글 남겨주시기 바랍니다.행복한 하루 되세요^^
질문&답변
표안의 특정 필드에 있는 이미지를 복사하여 한글 외부에 저장하기
혹시 "복사"란 게 파일로 저장하기를 말씀하시는 건가요?혹시 다른 문서에 붙여넣기하거나 "클립보드"로 복사하는 등 다른 작업이라면 추가댓글 남겨주세요ㅎ 우선은 해당 한/글 문서를 열어놓은 상태로아래 코드를 실행해서 아래아한글을 실행해줍니다.from pyhwpx import Hwp hwp = Hwp()우선, 이미지를 저장하려면 어찌됐든 "찾아가서", "저장" 해야 합니다.다행히 각각 셀필드가 있다고 하시니① hwp.move_to_field("이미지가들어있는필드명")을 실행하셔서 필드로 커서를 옮기신 후에,② hwp.SelectCtrlFront()명령어로 이미지를 선택합니다. (셀 하나에 이미지 하나라면 사실 ②는 생략하셔도 됩니다.)③ hwp.save_image(f"./{필드명}.png") 명령어로 이미지를 저장합니다. 만약에 클립보드로 복사하시겠다면 hwp.save_image 대신 hwp.Copy()를 실행하시면 되고, 다른 문서에 붙여넣으시려면 hwp.Copy() 대신 아래처럼 # 위 코드로 이미지를 선택한 상태에서 img = hwp.GetTextFile("HWP", option="saveblock:true") # 붙여넣기할 문서의 셀에 커서를 둔 채로 hwp.SetTextFile(img, "HWP")이런 식으로 클립보드를 쓰지 않고, 문자열로 붙여넣기도 가능합니다. 혹시 추가질문 있으시면 댓글을 남겨주세요.제가 다소 막연하게 이해한 부분이 있는 것 같아서^^;막연한 설명을 붙이기보다는, 추가댓글을 읽고 구체적으로 회신을 드리겠습니다. 행복한 하루 되세요!!!~
질문&답변
하위의 여러 폴더 중 특정폴더의 사진만 추출하기
안녕하세요?어려운 코드는 아니지만, 두 가지 주제로 분리해서 설명을 드려야 할 것 같습니다. ① 하위 폴더의 모든 파일과 경로를 파이썬으로 가져오기현재 폴더의 파일이나 폴더 목록은 os.listdir() 로 간편하게 구할 수 있지만,하위 폴더의 파일 목록까지 한 번에 구하고 싶으시다면 os.walk() 라는 함수를 쓰시는 것이훨씬 간편합니다. 예를 들어 하위폴더와 파일목록이 아래와 같을 때(사진) 아래와 같은 함수를 정의하여 실행하면(경로명 키를 가진 dict를 정의했습니다. 각 값은 해당 경로의 jpg 파일의 절대경로 리스트입니다.)import os def get_jpg_files_by_directory(root_dir="."): jpg_dict = {} for dirpath, _, filenames in os.walk(root_dir): jpg_files = [os.path.abspath(os.path.join(dirpath, f)) for f in filenames if f.lower().endswith(".jpg")] if jpg_files: # 파일이 있는 폴더만 추가 jpg_dict[dirpath] = jpg_files return jpg_dict결과는 아래와 같습니다.>>> jpg_files_dict = get_jpg_files_by_directory() >>> print(jpg_files_dict) { '.\\sub1': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\A-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\A-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\A-3.jpg' ], '.\\sub1\\sub2': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\B-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\B-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\B-3.jpg' ], '.\\sub1\\sub2\\sub3': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\C-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\C-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\C-3.jpg' ], '.\\sub1\\sub2\\sub3\\sub4': [ 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\sub4\\D-1.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\sub4\\D-2.jpg', 'C:\\Users\\user\\Desktop\\콘텐츠예제\\이미지경로\\sub1\\sub2\\sub3\\sub4\\D-3.jpg' ] } 위와 같은 데이터구조를 만들면,하위경로별로 각각의 key가 있고 그 안에 값으로 jpg파일 리스트가 있으므로순차적으로 이미지를 삽입하기 쉽습니다. (물론 더 효율적인 좋은 방법이 있을 수도 있습니다.) ② 아래아한글에 이미지 넣기아래아한글 API가 다소 복잡하므로, 저는 최근에 거의 항상 pyhwpx 모듈을 이용해서간단한 명령어들을 처리하고 있습니다.pyhwpx 모듈에 대한 구체적인 설명은 위키독스(링크)에서 확인하실 수 있습니다. pyhwpx에서는hwp.create_table(rows, cols, treat_as_char)로 간편하게 표를 생성하고,hwp.insert_picture(img) 메서드로 셀 안에서 이미지를 삽입하실 수 있습니다. 아래는 pyhwpx를 통해 위 이미지 목록을 간단히 hwp 파일에 삽입하는 예시코드입니다.(사진)for k in jpg_files_dict.keys(): hwp.set_font(Height=25) # 글자크기를 25로 hwp.insert_text(k) # 경로명 삽입 hwp.BreakPara() # 엔터 hwp.create_table(rows=1, cols=1, treat_as_char=True) # 1x1의 글자취급표 생성 for img in jpg_files_dict[k]: # 경로명 키를 순회하면서 hwp.insert_picture(img) # 경로 내의 jpg파일 삽입 hwp.TableAppendRow() # 아래에 새 셀 생성 hwp.Run("TableSubtractRow") # 마지막에 생성된 빈 셀은 제거 hwp.MoveDown() # 표 아래로 내려가서 hwp.BreakPage() # Ctrl-Enter(페이지 나누기)이런 식으로 활용하실 수 있습니다.라인별 주석을 참고해주시기 바랍니다. 엑셀 파일에 경로가 명시되어 있다면 해당 엑셀파일을 판다스 등으로 가져오셔서os.walk나 위 dict 자료 대신 활용하시면 더 간편할 것입니다.부디 도움이 되었길 바랍니다. 추가 질문은 댓글로 남겨주세요.사실, 질문이 조금 두루뭉실한 느낌입니다. 샘플 데이터가 있으면 확실하게 코드로 보여드릴 수 있는데,아시겠지만ㅜ 제가 똑똑한 편이 아니어서ㅎㅎㅎ질문 자체를 이해하는 것도 상당한 에너지가 필요하네요ㅜ행복한 하루 보내시기 바랍니다!
질문&답변
누름틀 적용항목 vs 엑셀항목 간의 순서관련 질문
현우님 안녕하세요!!ㅎ연휴에도 이렇게 열심이신 걸 보면, 보통 분이 아니신데요?ㅎ 질문에 답변을 먼저 드리면,필드와 메일머지는 굉장히 유사하게 작동합니다. 다만, 엑셀에서 값을 가져올 때, 칼럼명을 빼고 값만 가져오는 경우에는말씀하신 것처럼, 작동할 수 있습니다. 이미 메일머지를 통해 값을 입력하는 개념을 잘 알고 계시니저를 포함하여 많은 업무자동화 전문가들이 즐겨 사용하는간편한 방법을 하나 미리 알려드리고자 합니다.강의에서 알려드린 코드는 밑바닥까지 직접 구현한 관계로 굉장히 복잡한데요,원리만 이해하시면 됩니다. 실제로는 이렇게 복잡하게 코딩하지 않습니다ㅜ 죄송 우선은 pywin32를 설치하셨던 것과 동일하게,터미널에서 pip install pyhwpx 명령어로 pyhwpx 모듈을 설치해주시기 바랍니다.(사진)혹은 주피터노트북의 아무 셀에서%pip install pyhwpx라고 한 번만 실행하셔도 됩니다. 설치를 완료하셨으면, 다시 주피터노트북으로 돌아가셔서기존에 입력하셨던 아래 코드를 실행하지 마시고import win32com.client as win32 hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject") hwp.XHwpWindows.Item(0).Visible = True hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule") 아래의 코드를 대신 실행해보시기 바랍니다.from pyhwpx import Hwp hwp = Hwp()이렇게 아래아한글을 실행해도 대부분의 코드는 동일하게 사용하실 수 있지만,hwp.PutFieldText의 작동방식이 더 간편해지고,hwp.open 실행시, 전체경로를 입력하지 않아도 되는 등몇 가지 기능보완 및 편의기능이 추가되어 있습니다. 그럼 pyhwpx의 PutFieldText 활용예시를 몇 가지 보여드리겠습니다. 1. 엑셀파일 그대로 삽입만약 삽입할 데이터가 들어있는 엑셀파일이 깔끔하게 메일머지 형태로 정리되어 있는 경우hwp.PutFieldText(엑셀파일명)을 실행하면 엑셀의 값이 필드 안에 고스란히 들어가게 됩니다.(사진)질문 주셨던 것처럼, 엑셀문서 B열에 사이에 "별명" 칼럼이 끼어 있지만, 필드에 "별명"이 없으므로 누락되었습니다.이 방법이 제일 간편하다면 간편하지만, 파이썬 단에서 조금도 값을 수정할 수 없으므로미리 엑셀파일 안에 모든 값이 완벽하게 작성되어 있어야 합니다. 2. 엑셀파일을 판다스데이터프레임으로 불러온 후 삽입기왕 파이썬을 시작하셨다면, 꼭 pandas를 공부해보시는 걸 강력히 추천드립니다.엑셀파일을 다루는 것뿐만 아니라, 굉장히 방대한 데이터 처리 기능을 제공하므로비단 아래아한글이나 엑셀 업무자동화 뿐만 아니라 통계나 차트, 각종 분석 등 고급 업무에공부시간이 아깝지 않을 만큼 활용하실 수 있는, 파이썬의 가장 인기있는 라이브러리 중 하나입니다.하여튼, 엑셀파일을 판다스 데이터프레임으로 불러와서가공을 거친 후 삽입도 가능합니다.import pandas as pd df = pd.read_excel("엑셀파일.xlsx") # 데이터프레임 생성 df["특기"] = df["특기"] + "내기" hwp.PutFieldText(df)(사진)이런 방식으로 엑셀파일경로 문자열 대신 데이터프레임(df) 객체를 직접 집어넣을 수도 있습니다. 만약, 필드가 하나만 있고, 데이터프레임에서 특정 행만 넣고 싶은 경우는 아래처럼 실행하시면 됩니다.hwp.PutFieldText(df.iloc[[2]])(사진) iloc 활용방법df.iloc 는 "데이터프레임의 i번째 location"이라는 뜻입니다.i번째 행의 데이터만 골라서 넣겠다는 뜻입니다. 이게 굉장히 유용한 경우가 있는데요.메일머지로는 엑셀의 행 하나하나를 별도의 파일로 저장하는 것이 불가능합니다. 그런데 파이썬으로는 좀 더 세부적인 수준에서 필드를 다룰 수 있으므로,예를 들어 엑셀행이 500개가 있다고 할 때, 500개의 파일을 별도로 생성하는 것이 가능합니다.아래처럼 for문 안에서 실행하시면 됩니다.for i in range(len(df)): hwp.PutFieldText(df.iloc[[i]]) hwp.SaveAs(f"{df["이름"][i]}.hwp")(사진) 엑셀파일경로나 df 뿐만 아니라,파이썬의 리스트나 딕셔너리, 혹은 딕셔너리안의 리스트 자료형도동일하게 pyhwpx의 PutFieldText 기능을 통해 삽입 가능하므로아마 생각하시는 거의 모든 작업은 필드를 통해 가능할 것으로 생각됩니다. 처음 질문 주셨던, "특정 칼럼만 골라서 필드에 삽입" 하는 기능은win32com으로 구현하기에는 굉장히 까다로운 부분이 있는데데이터프레임이나, PutFieldText의 내장기능을 활용하면이렇게 간편하게도 구현할 수 있다는 점을 보여드리고 싶었습니다.답변이 되었을지 모르겠습니다^^;; 하여튼 질문 주셨던 것처럼, 특정 칼럼을 배제하려면딕셔너리 자료형으로 추출을 해서, 특정 칼럼명을 배제하거나아니면 처음부터 특정칼럼을 빼고 리스트로 만들거나........하여튼 상당히 까다롭습니다ㅜ 매번 이걸 코딩하기도 어렵고요. 가급적 위에 제안드린 방식을 한 번 검토해보시고실무에 적용하시는 걸 추천드립니다. 또 자동화하시면서, 혹은 자동화하시고자 하는 업무 관련하여 질문이 있으면언제든 편하게 추가질문 남겨주시기 바랍니다!!!! 감사합니다. 남은 연휴 잘 보내시기 바랍니다.행복한 하루 되세요^^
질문&답변
pyinstaller 로 exe 파일을 만들면 환경구축이 안되어있는 PC 에서 실행 불가
sam님, 안녕하세요! 반갑습니다^^회신이 조금 늦었습니다 죄송합니다 현재 이 부분 때문에 코드를 손을 봐야 하는데ㅜ 아직 진행을 못 하고 있습니다.급한대로 익셉션이 나지 않는 방법을 알려드려봅니다.먼저 밝혀둘 것은, 익셉션은 보안모듈 등록 때문에 발생하고 있습니다ㅜㅜㅜㅜ죄송합니다. ① pyinstaller 실행시 바이너리 첨부컴파일하실 때 FilePathCheckerModule.dll 파일을 소스코드와 동일한 폴더에 복사하신 후--add-binary="filePathCheckerModule.dll:." 옵션을 추가해주시기 바랍니다.예를 들면 아래처럼요.pyinstaller -F -w --add-binary="FilePathCheckerModule.dll:." source.py ② FilePathCheckerModule.dll 파일 동봉위 방법으로도 간혹 오류가 나는 경우가 있습니다. (권한문제일까요? 원인을 모르겠습니다ㅜ)그런 경우에는 FilePathCheckerModule.dll 파일을 실행파일과 같이 배포해보시기 바랍니다.만약 동봉하여 배포했음에도 오류가 발생한다면, 사용자 폴더(예를 들어 c:\Users\User\ )에다 FilePathCheckerModule.dll 파일을 복사해보세요.하지만 대~~부분의 경우에는 ①번 방법으로 해결될 것입니다. ③ 극단적인 방법 : 보안모듈 등록하지 않기처음에 hwp 객체를 만드실 때, hwp = Hwp(register_module=False) 라고 초기화하시면익셉션이 발생하는 부분의 코드를 실행하지 않습니다.대신 보안모듈이 등록되지 않으므로 보안승인팝업이 뜨게 됩니다.딱 한 번만 "모두 허용"을 눌러주면 되니 큰 문제가 되지는 않을 듯 합니다. 저도 깔끔하게 잘 되는 모듈을 만들어서 배포를 하고 싶은데오류가 쉽게 고쳐지지 않아 죄송한 마음이 큽니다.혹시 위 방법 중 성공하는 방법이 있다면 공유해주시면 감사하겠습니다. 벌써 설 연휴가 시작되었습니다.행복한 하루, 편안한 명절연휴 보내시기 바랍니다.감사합니다.
질문&답변
주피터노트북 코드로 한글파일 열수 없다고 나오는데.....
현우님 안녕하세요?먼저, 질문에 답변을 드리면1. 항상 절대경로 사용아래아한글을 파이썬으로 조작할 때는,주피터노트북이나 파이썬 콘솔의 현재 위치를 인식하지 않습니다.그래서 기본적으로 항상 경로를 입력할 때는 전체경로를 입력해주어야 합니다.이미지를 삽입할 때도, win32com으로 엑셀파일을 다룰 때도 마찬가지입니다. 전체 경로를 입력하지 않으면 해당파일이 아래아한글 설치폴더에 있다고 가정하고 탐색하므로 오류가 나버립니다ㅜ 제일 간편한 방법은 os나 pathlib 등 경로를 다루는 모듈을 쓰는 것입니다. 예를 들어 아래와 같이 입력해보시면, 현재 주피터노트북 위치의 문서를 오류 없이 여실 수 있습니다ㅎimport os # win32com 대신 pyhwpx라는 모듈을 사용하실 수 있는데,이 경우에는 상대경로를 인식하므로, 파일명만 입력하셔도 됩니다.강의 후반부에 pyhwpx를 다루는 예제도 소개드리고 있으니, 참고하시기 바랍니다. 코딩프로그램 사용법ㅜ죄송한 부분입니다. 개인적으로는 여러가지를 써보시고가장 취향에 맞는 하나를 고르시게 하고 싶은 의도였는데그게 어려운 부분이 될 줄은 생각하지 못했습니다. 개인적으로는 파이참 유료버전을 오랫동안 써 왔습니다.파이참에서는 유료버전만 주피터노트북 지원을 하니까요.간단한 코드결과를 확인하거나 할 때는 터미널에서 ipython을 실행하기도 하고요. 파이참과 별개로 무료로 주피터노트북을 사용할 수 있는 다른 옵션이 두 가지가 있는데,하나는 vscode를 쓰는 것이고, 다른 하나는 웹브라우저에서 원조 주피터노트북을 쓰는 것입니다. vscode나 커서IDE는 편리한 기능도 많고, 코파일럿 등 AI 기능지원도 강력하고무엇보다 주피터노트북을 무료로 사용할 수 있는데다, 굉장히 다양한 단축키를 제공하고 있어서처음엔 생소하고, 복잡하게 느껴질 수 있지만, 두세 달 진득하게 사용해보시면코딩을 이렇게 편하게 할 수 있게 지원을 잘 해주는구나 하고 느끼시는 지점이 올 것입니다. 음, 결론은 몇 가지를 체험해보시고 제일 느낌이 좋은 에디터 하나를 주력으로 잡으시는 걸 추천드립니다.최근 대세는 단연코 vscode나, 이를 포팅한 cursor IDE이므로, 이들을 쭉 써보시면 좋겠습니다. 첨언드리면우리같은 코알못이 코딩에 발을 들이는 것 자체가, 대단한 용기가 필요한 일이라고 생각합니다. 그리고. 업무를 더 잘 하고 싶거나, 더 빠르고 정확하게 마치고 싶은 분들이 이 강의를 찾아주시는 거라고 생각하기 때문에, 어떤 코딩 실력에 상관없이 존경스럽기도 하고, 대단하다는 마음도 듭니다.코딩은 아직도, 하면 할수록 어려운 문제를 만납니다. 시간이 지나면서 더 어려워지고 고민이 많아지기도 합니다. 근데 처음엔 오죽할까요^^; 개인적으로 현우님께서 어떤 업무를 하시는지, 또 어떤 업무를 자동화하고 싶으신지 알고 싶기도 합니다. 미흡한 상태로 강의를 공개해놔서, 충분히 원하시는 지식을 얻지 못하실까봐 걱정되기도 하고요.괜찮으시다면 댓글로, 담당하시는 업무 관련한 짤막한 코멘트를 남겨주시거나, 자주 질문글을 남겨주세요. 최대한 상세하게 답글이나 예시 소스코드를 제공해드리겠습니다. 그리고 주피터노트북이나 파이썬에 익숙해지기 전에는 코딩이 더딥니다. 차라리 수작업으로 하고 말지 하는 생각도 들고요. 그런 때는 잠시 코딩 공부를 쉬셔도 괜찮다고 생각합니다. 다만, 꼭 코드에디터를 사용하지 않고도, 이러이런 상황에선 대략 이런 코드를 써야겠지? 하는 연습을 틈틈이 하시다 보면 분명히, 숨쉬듯 자연스럽게 내 생각을 코드로 옮길 수 있는 시점이 찾아올 것입니다. 그 지점부터 코딩실력이 빠르게 향상될 것입니다.당장은 아니겠지만, 그렇다고 너무 먼 미래도 아닐 거고요. 내일 이맘때쯤 업무자동화나 코딩의 고수가 되어있을 현우님을 진심으로 응원합니다. 행복한 하루, 즐거운 설연휴 보내시기 바랍니다. 감사합니다.
질문&답변
녹화된 스크립트매크로를 파이썬에서 활용하는 방법 내용이 안보입니다.
혜진님 안녕하세요!해당 영상(?)이 제 실수로 제거가 되어버렸나봅니다ㅜㅜㅜㅜ본 내용은 아래 포스팅을 기반으로 하였으므로, (영상 내용도 이와 동일합니다)먼저 참고해주시고ㅜ조만간 복구해놓겠습니다. 감사합니다! 행복한 하루 되세요^^
질문&답변
엑셀 그래프와 테이블을 한글 각페이지에 삽입하기
한준님, 안녕하세요?덕분에 유쾌한 금요일을 보냈습니다. 기대하신 것보다 복잡한 코드를 보여드리는 것 같아 우려스런 마음이 있습니다만,막상 아래아한글 파트는 코드 전체에서 열 줄 정도로,엑셀 차트오브젝트나, 특정 범위를 선택하는 코드가 대부분이기는 하네요. 우선 짧은 시연화면을 먼저 보여드립니다.(사진)한/글에서 그림이나 표의 크기를 조절하는 코드를 빼기 위해 용지의 위아래 여백을 15 정도로 줄여두었습니다. 참고하시기 바랍니다. 코드는 크게 두 부분으로 나누었습니다. 하나씩 보여드리면, 1. 차트이미지 삽입하는 코드import xlwings as xw from pyhwpx import Hwp # 한글 인스턴스 생성 hwp = Hwp() # 활성화된 Excel 앱과 워크북 가져오기 excel = xw.apps.active wb = excel.books[0] # 워크시트 내 차트를 순회하며 처리 for ws in wb.sheets: shapes = ws.api.Shapes # 모든 도형 가져오기(단, 모든 도형이 차트라는 가정!!) for i in range(1, shapes.Count + 1): # 모든 도형을 순회하면서 shape = shapes.Item(i) # 도형을 선택하고 if shape.Type == 3: # 3 == 선택한 도형이 차트(ChartObject)이면 shape.CopyPicture() # 그림으로 복사하기 실행 후에 hwp.goto_page(i) # 한/글 문서의 i페이지 시작점으로 이동해서 hwp.MovePageEnd() # 페이지 끝으로 커서를 옮기고 hwp.BreakPara() # 엔터 한 번 친 후에 hwp.Paste() # 차트 이미지 붙여넣기 hwp.BreakPara() # 엔터주석을 읽어보시면 어느 정도 이해가 되실 거라고 생각합니다^^;코드를 따라 치지 마시고, 한 줄, 혹은 두 줄씩 기억해서 직접 작성해보시면더 빠르게 익숙해지실 겁니다. 그리고 아래는 표를 붙여넣는 코드입니다. 2. 엑셀 범위를 한/글 표로 붙여넣는 코드이 부분이 조금 까다롭게 느껴질 수 있는데, 아래에 부연설명을 붙이겠습니다.# 엑셀 열기 ws = wb.sheets[0] # 첫 번째 시트 선택 # A열에서 값이 "구 분"인 셀의 행번호 수집하기 a_values = ws.range(ws.cells(1,1), ws.cells(len(ws.used_range), 1)).value gubun_rows = [i+1 for i, val in enumerate(a_values) if val == "구 분"] # 엑셀범위 복사 및 한/글에 표로 붙여넣는 코드 for idx, row in enumerate(gubun_rows, start=1): # 수집한 행번호를 순회하면서 init_cell = ws.range(f"A{row}") # "구 분" 셀로 이동해서(표의 좌측상단) end_cell = init_cell.end("right").end("down") # 우측하단 끝 셀주소를 찾고 table_range = ws.range(init_cell, end_cell) # 해당 범위를 table_range.copy() # 복사함 hwp.goto_page(idx) # 한/글 문서의 idx페이지 시작점으로 이동한 후 hwp.MovePageEnd() # 커서를 해당페이지 끝으로 이동 hwp.Paste() # 표 붙여넣기 # 표 너비를 본문에 맞춤 i = 0 while hwp.get_into_nth_table(i): # 문서의 i번째 표로 진입한 후 hwp.set_table_width() # 표 너비를 본문 너비에 맞춤 i += 1 # 다음 표로 이동간결하게나마 라인별로 주석을 달아보았는데,제 생각에 가장 어렵게 느껴질 부분은 역시 a_values와 gubun_rows를 구하는 부분이 아닌가 싶습니다.이 문법들은 어떤 깊은 원리가 있다기보다, "우리, 이런 동작은 이런 코드로 약속하자" 식의 문법이라서익숙해지는 것 말고는 왕도가 없는 듯 합니다. ws.range(ws.cells(1,1), ws.cells(len(ws.used_range), 1)).value①우선 ws.range 객체는 워크시트의 셀 범위를 자유롭게 선택할 수 있는데, 사용법이 아래 두 가지입니다.하나는 ws.range("A1:B5").values 이런 식으로 엑셀의 셀 범위 문법을 문자열로 그대로 쓰는 방법과,다른 하나는 ws.range(ws.cells(1,1), ws.cells(2,5))식으로 cells객체를 두 개 넣는 방법입니다.항상 고정된 범위를 선택해야 하는 경우라면 첫번째 방법인 문자열 방식이 훨씬 직관적이지만,지금 우리 경우처럼 특정 셀을 찾아야 하거나, 순회하는 경우에는 두 번째 방법이 코딩하기 쉽습니다. ②그리고 len(ws.used_range) 코드가 들어가 있는 이유는,A열 전체에서 "구 분"이라는 데이터를 찾으려는 목적인데 ws.Range("A:A") 라고 지정해버리면 셀이 100만개나 선택이 되어버리기 때문에 다소 느립니다.그래서 "사용한 범위"의 행 갯수만 세서 A1:A100 정도 내에서만 탐색을 하기 위해"워크시트 사용범위의 행 길이"인 len(ws.used_range)를 탐색범위로 지정한 것입니다. [i+1 for i, val in enumerate(a_values) if val == "구 분"]①enumerate가 조금 생소하실 수 있겠습니다.enumerate는 리스트나 문자열 등 순회 가능한 객체를 for문에 넣었을 때,해당 인덱스의 아이템만 꺼내는 게 아니라, 아이템의 인덱스번호를 같이 리턴해줍니다.아래는 enumerate의 예시입니다.>>> a = ["A", "B", "C"] >>> for i in a: >>> print(i) ... A B C >>> for idx, val in enumerate(a): >>> print(idx, val) ... 0 A 1 B 2 Cfor문 안에서 enumerate 함수는 정말 많이 사용됩니다. 익혀 두시면 큰 도움이 될 것입니다.그러면, A열의 값들이 들어 있는 a_values 리스트 안에서값이 "구 분"인 주소의 행번호(인덱스)만 따로 추출하려면아래와 같이 for문을 작성하면 됩니다.gubun_list = [] for i, val in enumerate(a_values): # if val == "구 분": gubun_list.append(i + 1) # 파이썬인덱스는 0부터, 엑셀행은 1부터 시작하니까 +1 위처럼 네 줄로 짤 수도 있고요.파이썬의 "리스트 컴프리헨션"이라는 문법 덕분에위 네 줄을 간결하게 한 줄로 짤 수 있습니다."리스트컴프리헨션"은 "리스트 안에 for문을 포함(comprehension)하는 문법입니다.타 프로그래밍언어 유저들이 파이썬에서 가장 부러워하는 간결한 문법 세 가지로문자열 인덱싱, f-스트링 및 리스트&딕셔너리 컴프리헨션을 꼽는다고 합니다.그래서 최종 코드에는 아래처럼 리스트컴프리헨션을 써서 한 줄로 적었습니다.gubun_list = [i + 1 for i, val in enumerate(a_list) if val == "구 분"] 혹시 잘 이해가 안 되시거나 어렵게 느껴지는 부분이 있다면추가로 질문 남겨주세요.전적으로 제 설명력 부족 탓입니다ㅜ 마치며엑셀 관련 코드를 짤 때는, 셀이나 범위, 현재 선택위치 등을 생각하면서제법 까다롭게 시행착오를 거쳐야 하는 경우가 많지만,대부분 매크로 녹화를 통해 큰 틀의 코드가 잡힙니다.그리고 VBA와 파이썬 코드는 비슷한 부분이 있어서녹화한 엑셀매크로를 그대로 조금만 수정하면 잘 돌아가는 파이썬 코드를 금방 얻을 수 있습니다.아래아한글도 비슷합니다. 대부분은 스크립트매크로 녹화를 통해특정 수작업이나 프로세스에 대응되는 액션을 찾아내고,그 외에 매크로 녹화가 안 되는 액션이나, 필드, 이미지 삽입 같은 특수한 메서드는 API문서에서 검색하는 방식으로코드를 완성합니다.요즘은 한글개발자포럼이라고,한컴 개발자 분들이 직접 답변을 달아주는 고마운 사이트가 하나 생겼습니다.https://forum.developer.hancom.com/ 감사하게도 보통 하루 안에 상세한 답변을 달아주시고,열정적인 커뮤니티 분들이 더 빠르게 답변을 달아주시기도 해서저도 종종 방문합니다. 답변이 도움이 되었길 바랍니다.그리고 분명히 충분한 답변이 아니라는 것도 짐작이 갑니다.추가로 질문 남겨주세요ㅎ 즐거운 주말 보내세요~^^
질문&답변
api 버그를 활용한 서체 일괄체크에서 글자색 모두 바꾸기가 안되서 문의드립니다
재영님 안녕하세요?한글2024에서는 버그픽스가 되었나봅니다.대신 아래 코드를 참고해주시기 바랍니다.""" `hwp.set_pos(lst, para, pos)`는 (hwp.SetPos와 달리) 이동에 실패시 False를 리턴합니다. 그래서 아래처럼 while문 조건으로 사용 가능합니다. """ from pyhwpx import Hwp hwp = Hwp() lst = 0 # 본문에서부터 while hwp.set_pos(lst,0,0): # 모든 영역을 다니면서 hwp.SelectAll() # 전체선택 hwp.set_font(TextColor="Black") # 글자색 검정 lst += 1 # 다음 영역으로시연화면은 아래와 같습니다.(사진)도움이 되었길 바랍니다.강의 본문도 수정해 두도록 하겠습니다. 감사합니다.행복한 하루 되세요^^
질문&답변
한/글 API 가이드 링크
아이고, 수정해 두겠습니다.수정된 링크는 아래와 같습니다.https://developer.hancom.com/hwpautomation행복한 하루 되시기 바랍니다^^
2024. 01. 27.
3
[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
・
아래아한글
・
hwp
・
python
・
일상의코딩
・
일코
・
파이썬
・
create_table
・
한컴오피스
・
업무자동화
2023. 03. 09.
1
[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을 통해 문단번호의 글자모양 기본값을 통해문단수준별로 직접 변경하는 게 훨씬 안정적일 것 같기는 합니다^^;
업무 자동화
・
파이썬
・
아래아한글
・
업무자동화
・
한컴오피스
2022. 12. 28.
3
첫 포스팅을 작성해봅니다.
안녕하세요?반갑습니다. 일코입니다.이 블로그에서는 제 강의에서 미흡했던 일부 설명을 보충하는 포스팅을 틈틈이 적어보려고 합니다.제 아래아한글 강의에서는 통합개발환경으로 파이참이라는 프로그램을 활용하고 있습니다.파이참에는 유용한 단축키가 참 많지만, 그 중에도 제가 가장 많이 사용하는 단축키는Shift-Alt-E 입니다. 커서가 위치한 라인, 또는 선택한 라인들을 콘솔에 보내서 실행해주는 기능을 합니다.업무자동화 특성상 한/글이나 엑셀, 혹은 브라우저를 같이 열어놓고코드 한 줄 한 줄의 결과를 즉시 확인할 수 있기 때문에 아주 유용하게 쓰입니다.강의 영상에도 대부분 파이참을 화면 왼쪽에, 한/글이나 엑셀을 화면 오른쪽에 분할해서 띄워놓고코드를 일부 작성한 후에 실행하고 싶은 라인만 선택한 후에 Shift-Alt-E를 통해 결과를 확인합니다.보조모니터 없이 14인치 노트북으로 강의안을 만들기 때문에오밀조밀하게 작은 화면에서 이것저것 하려다 보니 이런 작업환경을 만들게 되었습니다. 제 강의를 따라하시는 여러분들도 한쪽에는 강의안을다른 한쪽에는 파이참과 한/글(또는 엑셀)을 띄워놓고 저와 비슷한 화면에서 작업하시면,실습하기 더욱 수월하실 겁니다. 이번 포스팅은 여기서 마치겠습니다.
업무 자동화
・
일코
・
회사원코딩
・
일상의코딩
・
아래아한글
・
업무자동화
・
파이참
・
작업환경
・
분할
・
실행방법
・
실습