인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

류한준님의 프로필 이미지
류한준

작성한 질문수

직장인에게 꼭 필요한 파이썬-아래아한글 자동화 레시피

표 삽입하기

엑셀 그래프와 테이블을 한글 각페이지에 삽입하기

해결된 질문

작성

·

34

1

안녕하세요 강의를 보면서 한글을 하나씩 건드려보며 재미있게 공부하고 있습니다

 

엑셀에 데이터 입력하기, 한글에 누름틀, 필드 등으로 데이터 입력하기 등 매우 흥미로운 주제이면서 나도 자동화에 쓸 수 있다는 희망이 보이는 강의입니다.

 

하지만 확실히 강의로 따라하는 것과 실제 예제에 응용은 쉽지 않다는게 느껴져 해결될 기대를 하며 질문을 남겨봅니다

 

파일 형태을 확인하실 수 있도록 파일링크를 첨부드립니다
https://docs.google.com/spreadsheets/d/1JsP1BPtFzFXMTtUcjR3k0Qhhs6W7L-ZU/edit?usp=sharing&ouid=115890287739826344876&rtpof=true&sd=true

 


하고자 하는 자동화는 아래와 같습니다

  1. 엑셀에 있는 그래프를 한글 각 페이지에 붙여넣기

    1. 붙여 넣을 때는 각 페이지의 마지막 글자를 찾고 두칸 아래에 붙여넣기

  2. 엑셀에 있는 테이블 형식의 데이터를 한글 각 페이지에 붙여넣기

    1. 붙여 넣을 때는 각 페이지의 마지막 그림(1에서 붙인 그래프)를 찾고 두칸 아래에 붙여넣기



테이블이 출력되면 각 행별로 가장 높은 숫자를 찾아 보고서 워딩을 작성해야 하는데

 

현재는 파이썬으로 요리조리(??) 작성하여 각 테이블을 순환하면서 높은 수치를 뽑아 워딩을 엑셀에 정리한 후 해당 엑셀을 메일머지로 각 페이지 마다 자동으로 작성되게는 했습니다.

 

여기서 더 나아가 그래프, 테이블까지 보고서에 자동으로 붙이면 자동화에 좀 더 가깝지 않을까 하여 질문남겨봅니다

 

엑셀의 테이블을 순환하면서 복사하고 한글에 붙인다는 개념만 잡아두었고 어떻게 접근해야될지 모르겠습니다. 좋은 의견 기다리겠습니다 감사합니다~!

 

답변 2

1

일코님의 프로필 이미지
일코
지식공유자

한준님, 안녕하세요?
덕분에 유쾌한 금요일을 보냈습니다.

 

기대하신 것보다 복잡한 코드를 보여드리는 것 같아 우려스런 마음이 있습니다만,
막상 아래아한글 파트는 코드 전체에서 열 줄 정도로,
엑셀 차트오브젝트나, 특정 범위를 선택하는 코드가 대부분이기는 하네요.

 

우선 짧은 시연화면을 먼저 보여드립니다.

녹화_2025_01_04_00_35_32_213.gif

한/글에서 그림이나 표의 크기를 조절하는 코드를 빼기 위해 용지의 위아래 여백을 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_valuesgubun_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 C

for문 안에서 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/

감사하게도 보통 하루 안에 상세한 답변을 달아주시고,
열정적인 커뮤니티 분들이 더 빠르게 답변을 달아주시기도 해서
저도 종종 방문합니다.

 

답변이 도움이 되었길 바랍니다.
그리고 분명히 충분한 답변이 아니라는 것도 짐작이 갑니다.
추가로 질문 남겨주세요ㅎ

 

즐거운 주말 보내세요~^^

1

안녕하세요, 인프런 AI 인턴입니다.

류한준님께서 말씀하신 엑셀의 그래프와 테이블을 한글 문서의 각 페이지에 자동으로 삽입하는 작업은 조금 복잡하지만, 적절한 라이브러리를 사용하여 충분히 구현할 수 있는 작업입니다.

기본적인 방향:

  1. 엑셀과 한글 파일 열기:

    • pandasopenpyxl 혹은 win32com 패키지를 사용하여 엑셀 파일을 열고 데이터를 읽습니다.
    • pywin32 라이브러리를 사용하여 한글 문서를 제어할 수 있습니다.
  2. 그래프 자동화 삽입:

    • 엑셀에서 그래프를 이미지로 저장하고, 한글 문서에 삽입합니다. matplotlib를 사용하여 그래프를 시각화하고 저장하는 방법도 고려해 볼 수 있습니다.
    • 한글 문서에서 각 페이지의 마지막 위치를 찾는 방법은 기본적으로 문서의 끝을 탐색하여 그래프를 배치하는 것입니다.
  3. 테이블 데이터의 삽입 및 보고서 작성:

    • 엑셀 데이터프레임을 읽어와 분석한 후, 한글 문서에 테이블 형식을 그대로 복사하여 붙입니다. win32com 라이브러리를 사용하여 엑셀 데이터의 스타일을 유지하며 붙여넣기 할 수 있습니다.
    • 테이블의 마지막 위치를 기준으로 새로운 데이터를 붙여 넣으려면, 현존하는 그래프의 위치를 기준으로 오프셋을 설정하여 다음 내용이 붙도록 합니다.

관련 자료:

각종 데이터 삽입 및 리포트 자동화 목적으로 위의 예제들이 도움이 되리라 생각됩니다. 더 나아가, 자동화 작업을 보다 효율적으로 수행하고 싶다면, 파이썬의 다양한 라이브러리를 활용한 스크립트를 조합하는 방식을 시도해 보세요.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

류한준님의 프로필 이미지
류한준

작성한 질문수

질문하기