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

qja8919님의 프로필 이미지
qja8919

작성한 질문수

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

불특정 파일을 순회하면서 찾고 표안에 글넣기

해결된 질문

작성

·

67

·

수정됨

1

안녕하세요. 강의를 들으며 자동화를 진행하고 있는데, 한 가지 질문이 있습니다.

저는 특정 문서가 아니라 여러 다른 문서에서 사용자의 정보를 자동으로 입력하는 코드를 작성하고 싶습니다. 예를 들어, 자주 입력하는 항목인 이름, 성별, 전화번호를 딕셔너리에 저장하고, 서로 다른 양식의 문서를 불러왔을 때 해당 항목이 존재하면 입력란의 오른쪽이나 아래쪽 공백을 확인하여 자동으로 채워 넣기를 희망합니다.

이런 작업이 기술적으로 가능한지 궁금하며 가능하다면 어떻게 하는것이 좋을지 조언을 구하고 싶습니다. 감사합니다.

답변 2

1

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

qja8919님 안녕하세요?^^

좋은 질문 남겨주셔서 감사합니다.

 

우선 어느 정도 규칙(일종의 경계조건)이 있다면?

구현 자체는 크게 어렵지 않습니다.

 

아주아주 일반적인 경우에도 잘 돌아가는 코드를 짜는 건

코딩의 영역이라기보다는, 문제정의 역량이 중요한 듯 합니다^^;

 

하여튼 간단한 예를 한 번 들어보겠습니다.

 

제게 아래와 같은 데이터가 있고,

```python

my_info = {
    "이름": "일코",
    "성별": "남",
    "생일": "1983. 2. 26.",
    "취미": "코딩",
    }

qja님의 예시처럼 2행4열 또는 4행2열 등의 표가 있다고 가정해보겠습니다.

아래의 샘플문서는 여기에서 다운받으실 수 있습니다. [링크]

image.png

 

① 가장 먼저 생각해볼 것은, "어느 표에 넣을 것인가?"

문서 안의 표들을 순회하면서

"이 표가 내가 데이터를 집어넣을 표가 맞구나!" 하는 여부를 파악해야 하는데

방법은 다양하겠지만, 표 안의 텍스트를 추출했을 때,

["이름", "성별", "생일", "취미"]라는 문자열 리스트가 포함되어 있는지를 파악해야 할 것 같습니다.

 

표 안의 텍스트를 추출하는 방법은 간단한데요.

예를 들어 아래와 같은 표가 있다면,

image.png

(나중엔 첫 번째 표와 세 번째 표에 텍스트를 넣게 되겠죠?)

 

pyhwpx를 사용하신다고 가정하고,

문서 안의 모든 표를 순회하면서 리스트를 가져오는 방법은

content_list = []
i = 0
while hwp.get_into_nth_table(i):
    hwp.SelectCtrlFront()
    content_list.append(
        hwp.get_selected_text(as_="list")
    )
    i += 1

print(content_list)

이런 방식으로 코드를 짜서 실행해보시면

결과는 아래와 같이 나옵니다.

['이름', '성별', '생일', '취미']
['이름', '나이', '취미']
['이름', '성별', '생일', '취미']
['이름', '휴대폰번호', '운전면허증번호', '주민등록번호', '여권번호']
녹화_2024_09_25_00_13_08_103.gif

 

참고로, 판다스 데이터프레임을 다루는 게 더 편하시면,

hwp.table_to_df(n) 메서드를 사용하실 수도 있습니다.

try:
    i = 0
    while True:
        print(hwp.table_to_df(i))
        i += 1
except:
    print("끝!")
녹화_2024_09_25_00_18_15_440.gif

추출한 표 리스트 중 set로 변환한 결과가 {"이름", "성별", "생일", "취미"}와 동일한지를 비교하면,

(혹은 sorted 함수로 정렬한 두 리스트의 결과가 동일한지?)

삽입할 표의 인덱스를 를 고르는 과정은 완성된 것 같네요.

다음 과정은,

 

② 어느 셀에 데이터를 넣을 것인가?

이것도 크게 어렵지는 않을 것 같아요.

대신 순서가 섞여 있을 수도 있고,

2행4열이나, 4행2열이나, 혹은 극단적으로

image.png

이런 가능성도 상정하면 일괄로 넣는 것보다는

"이름" 셀을 찾고 이름 우측셀과 하단셀 중에 빈 곳에 이름값을 넣고,

"성별"을 찾은 다음에도 우측셀과 하단셀 중 빈 셀에 성별값을 넣고..

이걸 반복하면 될 것 같아요.

 

③이 때 놓치기 쉬운 예외가 하나 있는데,

아래와 같은 경우에는

image.png

이름 셀에서 하단 셀이 비어 있는지 체크하려고 아래로 이동하면

(실제로는 안 내려갈테니까, )

다시 위로 돌아오는 코드는 적절히 조건절을 써서 처리해줘야겠죠?

무작정 올라가버리면 "성별" 셀로 이동해버리게 되잖아요... 삽입도 틀어지겠죠.

이런 부분은 예외처리를 해 줘야 할 것 같네요.

다행히 hwp.TableRightCell()이나 hwp.TableLowerCell() 등 이동 명령어 대부분은

이동에 실패할 경우 False를 리턴하니까 이 리턴값을 활용하면 될 거예요.

(만약 우측셀과 하단셀 둘 다 비어있다면? 혹은 둘 다 채워져 있다면? 그건 더 고민해봅시다. 우선패스)

 

③ 그럼 위 검토내용을 바탕으로 코드를 완성해보겠습니다.

제가 너무 상황설정을 단순하게 한 건가 싶어요.. 추가로 궁금한 점이 있으면 댓글 남겨주세요^^

 

우선 아래와 같이 코드를 짜보았습니다.

(제가 역량이 부족해서, 코드가 막 간결하거나 아름답지는 않네요ㅜ)

녹화_2024_09_25_01_34_39_926.gif
my_info = {
    "이름": "일코",
    "성별": "남",
    "생일": "1983. 2. 26.",
    "취미": "코딩",
}

i = 0
hwp.MoveDocBegin()
hwp.FileNewTab()
hwp.switch_to(0)
while hwp.get_into_nth_table(i):
    hwp.SelectCtrlFront()
    if sorted(hwp.get_selected_text(as_="list")) == sorted(my_info.keys()):
        table_unfilled = hwp.GetTextFile(format="HWP", option="saveblock")
        hwp.switch_to(1)
        hwp.SetTextFile(table_unfilled, format="HWP")
        for key in my_info.keys():
            hwp.find(key, direction="AllDoc")
            # 아래 먼저 탐색
            hwp.TableCellBlock()
            if hwp.TableLowerCell():
                if not hwp.get_selected_text():
                    hwp.insert_text(my_info[key])
                else:
                    hwp.TableUpperCell()
                    hwp.TableRightCell()
                    if not hwp.get_selected_text():
                        hwp.insert_text(my_info[key])
            else:
                hwp.TableRightCell()
                if not hwp.get_selected_text():
                    hwp.insert_text(my_info[key])
                
        hwp.SelectCtrlFront()
        table_filled = hwp.GetTextFile(format="HWP")
        hwp.Delete()
        hwp.switch_to(0)
        hwp.Delete()
        hwp.SetTextFile(table_filled, format="HWP")
    i += 1
hwp.switch_to(1)
hwp.close()

도움이 되었으면 좋겠습니다.

 

 

막상 이런 코드를 qja8919님의 업무에 활용하시려면

뭔가 더 구체적인 사례나 예외처리를 생각하셔서

코드를 보완하셔야 할 듯 해요.

 

 

절대 부담 갖지 마시고, 질문 많이 남겨주세요~~

행복한 하루 되세요^^

 

1

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

여러 다른 문서에서 사용자의 정보를 자동으로 입력하고 싶어 하신다면, 특정 키워드(예: 이름, 성별, 생일, 취미 등)를 찾아 해당 키워드의 옆이나 아래에 데이터를 채워 넣는 방식으로 프로그래밍이 가능합니다.

강의 중에서는 SetPos()GetText(), 그리고 PutFieldText()와 같은 주요 함수들을 사용하여 텍스트를 데이터 필드에 삽입하는 방법을 설명하고 있습니다. 여러 문서에서 특정 데이터를 자동으로 삽입하려면, 아래와 같은 절차를 따르는 것이 좋습니다:

  1. 문서 불러오기 및 좌표 탐색: 각 문서를 불러오고, 특정 키워드(예를 들어 “이름”)를 검색하여 좌표를 찾습니다.
  2. 좌표 이동 및 데이터 삽입: 찾은 좌표를 기준으로, 해당하는 입력란의 오른쪽이나 아래쪽으로 이동하여 데이터를 입력합니다.
  3. 여러 문서 순회: 원하는 여러 문서를 반복적으로 읽고 데이터를 채워 넣을 수 있습니다.

기초적인 코드를 예시로 제공해 드리겠습니다:

import win32com.client as win32  # 한글 자동화 라이브러리
import os

# 한글 인스턴스 생성 및 Visible 설정
hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
hwp.XHwpWindows.Item(0).Visible = True
hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")

# 한글 파일 목록 불러오기
file_directory = "./hwp_files"
file_list = [file for file in os.listdir(file_directory) if file.endswith('.hwp')]

# 데이터 딕셔너리 설정
user_data = {
    "이름": "홍길동",
    "성별": "남자",
    "전화번호": "010-1234-5678"
}

def find_and_insert_data(hwp, keyword, data):
    hwp.InitScan(window=1, Range=range(0xff))  # 스캔 초기화
    scan_state = 1
    while scan_state:
        scan_state, text = hwp.GetText()
        if keyword in text:
            hwp.MoveLeft(select=True)
            hwp.MoveRight()
            hwp.Run("SelectAll")  # 키워드 선택
            hwp.PutFieldText("{%s}" % keyword, data)  # 데이터 입력
            break

# 각 파일에 대해 수행
for file_name in file_list:
    file_path = os.path.join(file_directory, file_name)
    hwp.Open(file_path)
    
    for keyword, data in user_data.items():
        find_and_insert_data(hwp, keyword, data)

    hwp.Save()  # 파일 저장

hwp.Quit()

중요: 위 코드는 기본적인 예시로, 각 문서의 양식에 따라 추가적인 조정이 필요할 수 있습니다.

제가 언급한 내용과 관련하여 자동화 과정에서 특정 항목을 찾고 데이터를 삽입하는 과정은 매우 유용하며, 여러 문서에서 일관된 데이터를 입력하는 자동화 작업을 하기에 적합합니다.

다음은 관련 질문 URL입니다:
몇가지 팁으로 파이썬으로 한글 작업을 자동화하기

질문이 더 있으시면 언제든지 물어보세요. 좋은 결과 있으시길 바랍니다.

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

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

링크가 자바 관련이에요ㅜ

그래도 갈길이 너무 멀지는 않은 것 같아요.

답변 수준이 날로 좋아집니다.

인턴님 화이팅!

 

qja8919님의 프로필 이미지
qja8919

작성한 질문수

질문하기