해결된 질문
작성
·
174
·
수정됨
1
안녕하세요, 일코님.
강사로서 콘텐츠를 만드는 모습과 수업의 열정에 저도 한 수 배웁니다.
강의를 들으면서 제 상황과 함께 몇 가지 문의드립니다.
요새 Langchain과 엮어서 hwp 파일을 자동화하는 프로그램을 만들고 있습니다.
LLM 활용하여 업무를 효율화 하는 콘테스트 같은 것에 참여하는데 한글 파일을 수정해야하는 난관이 있어서 수업을 듣게 되었어요.
개발 기간이 한 달 남짓 남은 상황이라서, 질문으로 가장 효과적인 방법을 알 수 있을까하여 강사님께 조언을 요청드립니다.
(hwp 5.0 파일 전체 구조를 분석할 시간이 안되네요..)
질문 3가지 드립니다.
제가 개발하고 있는 프로세스는 이렇습니다.
보고서나 기획안을 작성해야 할 문장을 길게 받는다.
프롬프팅을 해서 LLM에 넣어서 리턴을 받는다.
대제목, 중제목, 소제목으로 포맷팅하여 HWP파일에 끼워 넣어서 export한다.
현재 FastAPI로 개발을 하고 있고, HWP 파일에 끼워 넣기 전 단계까지는 어떻게 개발이 끝난 상황입니다.
대제목의 갯수, 중제목의 갯수, 소제목과 내용은 배열로 받든 JSON 형태로 받든 규격화된 형태로 받아서 제가 일일이 끼워 넣을 예정입니다.
현재 제가 가지고 있는 양식에 내용을 채워 넣으려고 합니다. (양식이 이것 외에 여러 개 입니다.)
누름틀로 자동화하는 강좌도 영상과 글로 보았고, 파일 내용을 읽어오는 것도 배웠는데
회사 로고나 도표가 함께 섞여있는 복잡한 문서를 처리하기에는 예제 대비 너무 어려운 상황입니다.
양식이 정해진 파일을 읽어와서,
해당 문자열 위치에 다시 규격화해서 넣을 수 있는 가장 효과적인 방법을 찾고 있습니다.
ㅁ, ㅇ, - 등은 제가 넣을 때 임의로 삽입해서 넣으려고 합니다.
여기에서 저 특정 부분(대제목, 중제목, 소제목, 내용 모두)의 위치에 LLM에서 받은 문자열을 규격화해서 넣으려고 하는데, 가장 좋은 방법은 무엇일까요? (폰트와 글자 크기가 전부 다름)
txt파일이나 마크다운 파일 같은 것은 특정 파일 포인터를 읽거나, 원래 가지고 있는 문자열을 대충 정리해서 밀어 넣으면 정리가 가능했는데, hwp 파일은 이 자체가 워낙 규격화가 특이하게 되어있어서 분석이 어렵습니다.
제가 처리할 양식이 5개가 됩니다. 그 중에는 도표가 많은 것도 있고, 저 위에 있는 것 처럼 단순한 것도 있습니다.
어떻게 해야지 기존의 양식을 분석하고, 해당 부분에 문자열이나 문구를 정확하게 삽입할 수 있을까요?
현재 한글 프로그램을 실행시킨 이후에 그 내부에서 작업을 하는 것처럼 보이는데요. (크롬을 크롬드라이버로 자동화하는 것처럼) 하나의 양식을 여러 클라이언트에서 요청 받아서 생성을 완료하고 리턴해주려면 어떤 방식이 좋을까요?
예) 누름틀로 모든 영역을 다 분리해놓은 상태에서 하나 클라이언트를 띄우고, 해당 문서에 내용을 모두 바꾼 뒤에 다른 이름으로 저장하고 해당 파일을 return?
혹시 좋은 예제나 방법이 있을까 하여 여쭤봅니다.
가장 위의 2가지 질문은 같은 계열의 질문입니다만, 혹시나하여 첫 번째 질문에 예제를 같이 넘겨드립니다.
선배 개발자님이자, 강사님의 고견 여쭙습니다.
감사합니다. 답변 기다리겠습니다.
답변 2
2
주말코딩님 안녕하세요?^^
(유튜브채널도 구독하고 있습니다ㅎ)
먼저 간단히 답변 드려보면, (혹시 제가 헛다리 짚고 있으면 다시 알려주세요^^;)
이 부분은 방법이 다양한데,
우선 제목, 일자, 작성부서 요소가 들어있는 첫머리 부분은
누름틀이나 셀필드로 완성해 두시는 게 제일 편할 듯 합니다.
폰트나 줄간격 같은 것까지 미리 설정해 두고요.
이어서 본문 부분은
동적으로 문단 갯수가 바뀌므로 누름틀을 쓰지 마시고
문단 첫 글자를 보고 스타일을 자동으로 매기는 코드를 짜는 게 제일 쉬울 듯 합니다.
예를 들어
숫자.
으로 시작하면 "대제목" 스타일
□
으로 시작하면 "중제목" 스타일,
이런 방식으로요.
(스타일은 각 양식별로 문서 안에 미리 정의가 되어 있어야 하고요.)
예시를 보여드리면
위 영상에서 사용한 코드는 다음과 같습니다.
import re
import datetime as dt
from pyhwpx import Hwp
hwp = Hwp()
hwp.put_field_text(
{
"제목": "주말코딩의 예시문서",
"날짜": dt.datetime.today().strftime("(%Y. %m. %d.)"),
"작성부서": "주말코딩팀",
}
)
p = 0
while hwp.set_pos(0, p, 0):
hwp.MoveSelLineEnd()
line = hwp.get_selected_text()
if line.startswith("\r\n"): # 표나 그림 등
pass
elif re.match(r"\d+?\. ", line): # 1. 2. 11. 등
hwp.set_style("대제목")
elif line.startswith(r"□ "):
hwp.set_style("중제목")
elif line.startswith(r"○ "):
hwp.set_style("소제목")
elif line.startswith(r"※ "):
hwp.set_style("주석")
else:
pass
p += 1
예제 파일은 아래의 것을 사용하였습니다. (다운받아 테스트해보실 수 있습니다.)
https://drive.google.com/file/d/1Fvaja8T3rsHf90z6sbtbjzfObD0StWoc/view?usp=sharing
제 경우는 위와 같은 방식으로
가장 마지막 순서에 일괄 스타일처리를 하는 방법을 선호합니다.
hwp.set_font라는 메서드가 마련돼 있기는 하지만,
모든 것을 코드로 처리하기는 사실 버겁습니다. 느리고요.
적절히 한/글의 스타일 기능을 섞어서 처리하시면 되겠습니다.
그리고 기존 문서의 특정 위치를 찾아가는 것은 어렵습니다.
만약 표라면, 특정 셀(보통 A1)에 셀필드를 주고,
본문 어딘가라면 빈 누름틀을 삽입해 두거나,
좌표(List, Para, Pos)를 저장해 두고
문서 끝에서부터 삽입/수정하시는 방법도 있습니다.
그런데 경우도 많고, 방법도 다양하므로
상황에 맞는 방법을 선택하는 것이 좋습니다^^;
(사실 저도 거의 매번 다른 방법을 씁니다..)
문제나 상황을 조금만 더 구체적으로 알려주시면 정확한 답변을 드릴 수 있을 것 같습니다.
사실 저도 이것 때문에 자주 고민합니다.
제 기준에서, 잘 구조화된 문서라 함은
위계와 패턴이 일정하고 무엇보다 예외가 없는 문서인데
(그러면 글머리나 스타일이든, 개요번호나 개요수준이든, 잡아서 구조화하기 쉬우니까요..)
하물며 공문서나 교육부 시험지를 봐도 그런 문서가 많지는 않습니다.
이 부분은 저도 명쾌한 답변을 드리기 어렵고,
샘플문서를 보여주시면 소견을 말씀드릴 수는 있을 듯 합니다.
죄송합니다.
맞아요. 한글 프로그램을 실행해야 합니다.
웹에서 서빙하시는 경우라면, 말씀하신 대로
클라이언트 요청시마다
멀티프로세싱으로 백그라운드에서 한/글 인스턴스를 하나씩 열어서
원본 서식파일을 복사해서 사본을 연 후에
필드작업 등을 완료하면 저장하고,
한/글을 닫고, 파일을 보내는 방식으로 처리하시면 됩니다.
예제랄 만한 걸 갖고 있지는 않은데
구체적으로 추가질문 남겨주시면
답변 드리겠습니다.
도움이 되었으면 좋겠습니다.
행복한 하루 되세요^^
혹시 공개하기 조금 어려운 부분이 있으시다면
martinii.fun@지메일로 메일 보내주시면
회신 드리겠습니다.
안녕하세요, 일코님.
이메일로 연락드리려다가 비슷한 상황을 겪는 수강생 분들이 있을까하여 여기에 재 질문 드립니다!
누름틀로 하고 내용 자동화까지는 했습니다만, 스타일 설정이 안되어서요.
내용을 보면 선택 자체는 되는 것 같은데 그냥 통과해버립니다.
스타일 설정이 코드가 돌긴 하는데 왜 적용이 안되는지를 모르겠습니다.
혹시 의심해볼만한 다른 환경이나 증상이 있을까요?
스타일 이름은 정상적으로 지정해서 오류가 발생하지는 않습니다.
심지어 매칭이 잘못된 것인가하여 마지막 else에 스타일 지정을 해봤는데도 그냥 통과합니다.
내부 라이브러리 코드를 보니, 일반 정수형 (스타일번호)로도 파라미터를 처리하길래 넣어봤는데 안됩니다.. 😅
답변 기다리겠습니다...^^
혹시 글머리를 "개요번호" 같은 요소로 추가하고 계시다면, get_select_text 메서드 대신 아래처럼 시도해 보시기 바랍니다.
line = hwp.GetHeadingString()
일코님! 답변 감사합니다.
메서드를 바꾸기 전과 동일한 증상으로 나옵니다.
분명히 본문을 훑긴하는데, 스타일 변경이 안되네요..
그리고 저기 startswith 부분이 틀린 코드가 녹화됐는데,
한글본문에서 다시 ㅁ, ㅇ으로 매칭되도록 변경해서 시도해봤습니다.
저 코드는 잘못된 상태네요.
바꿔도 동작은 되지 않고 있습니다..
1
안녕하세요, 인프런 AI 인턴입니다.
주말코딩님, 질문 주셔서 감사합니다. 아래아한글(hwp) 파일의 특정 부분에 문자열을 삽입하고, 기존 양식을 분석하여 자동화하는 방법에 대한 고민이 깊으신 것 같네요.
선생님 지난번에 질문했던 학생이 해답을 찾아서 보고⁉ 올립니다.” 에서 비슷한 상황에 대한 해답을 찾으신 것을 공유한 적이 있습니다. 이 경우는 이미지를 글자 위에 겹쳐서 찍는 코드를 파이썬으로 구현한 사례로, hwp 파일 내에서 특정 위치에 내용을 삽입하는 방법과 관련된 내용입니다. 코드 내용은 아래와 같습니다:
import win32com.client as win32
hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject")
hwp.XHwpWindows.Item(0).Visible = True
hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")
file_path = os.path.join(os.getcwd(), "문서양식/테스트문서.hwp")
hwp.Open(file_path)
img_path = r"추가하길원하는이미지경로.png"
hwp.InsertPicture(img_path, Embedded=True)
hwp.FindCtrl() # 이미지 선택 (커서에서 인접한 개체 선택)
hwp.HAction.GetDefault("ShapeObjDialog", hwp.HParameterSet.HShapeObject.HSet) # 액션 초기화
hwp.HParameterSet.HShapeObject.TextWrap = hwp.TextWrapType("InFrontOfText") # 글 위로 배치
hwp.HParameterSet.HShapeObject.TreatAsChar = 0 # 글자처럼 취급 해제
hwp.HAction.Execute("ShapeObjDialog", hwp.HParameterSet.HShapeObject.HSet) # 실행
이 코드는 이미지를 한글 문서에 삽입하고 원하는 위치에 배치하는 방법을 제시합니다. 특정 부분에 문자열을 삽입하는 경우에도 유사한 방식으로 hwp 객체 모델을 활용하여 구현할 수 있을 것입니다.
또한, “문서”를 참조하고 활용하는 방법이 궁금합니다.에서는 한글 오토메이션 개발과 관련된 API 문서(예: ActionObject.pdf, HwpAutomation.pdf)를 참조하고 활용하는 방법에 대한 자세한 설명이 있습니다. 이 내용은 hwp API와 관련된 문서를 참고하여 개발하는 과정에서 활용할 수 있는 여러 팁과 상세 설명을 제공합니다.
제시된 내용과 유사한 상황을 처리하는 방법에 대한 정보는 주말코딩님의 프로젝트에도 도움이 될 수 있을 것 같습니다. hwp 파일 내 특정 부분에 자동으로 내용을 삽입하고, 기존 양식을 분석하는 작업에 참고하시면 좋을 것 같습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
일코님, 정성스러운 답변 너무 감사드립니다. 예제 코드와 영상 예시까지 주시다니, 감동 받았습니다.
역시 혼자 끙끙 앓고 있는 것보다 질문을 올리기를 잘했다는 생각이 듭니다.
결국 최종 문자열을 리턴받을 때 제목별로 구별이 가능하게 틀을 만들고 넣은 뒤에 스타일을 변경해야겠네요.
일단 문자열을 문서에 쓰는 것부터 해보고 스타일일 해봐야겠습니다.
우선 간단한 양식은 말씀주신 대로 한 사이클을 돌려보고 정상적으로 파일 다운로드가 되는지 해보고 고민이 있으면 이메일로 별도로 문의를 드리겠습니다..!
날씨가 많이 덥습니다. 코로나와 건강에 유의하시고 좋은 하루 보내세요.
감사합니다.