고객별 보고서 자동화, 자산 리포트와 이메일 초안 만들기

고객 명단을 나누고, 자산 금액을 계산하고, PDF를 저장한 뒤 메일에 첨부한다. 같은 양식으로 반복하는 일이라면 고객별 보고서 생성과 이메일 초안 준비까지 한 번에 처리할 수 있다.

이 글의 예제는 가상 고객 3명의 자산 6행으로 실제 실행했다. 정상 자료에서는 PDF 3개와 첨부 메일 초안 3개가 나왔다. 한 고객의 가격을 비우자 그 고객의 전체 총액은 미확정으로 표시됐고, 메일 초안도 만들지 않았다.

입력 파일과 코드를 함께 제공한다. 같은 자료로 결과를 확인한 뒤, 금액 하나를 바꿔 해당 고객의 리포트만 달라지는지 시험해볼 수 있다. 실제 고객 자료·시세·납품 사례를 사용한 글은 아니다.

어떤 업무를 어디까지 자동화했나

이번에 끝낼 일은 고객별 자산 현황 PDF와 검토할 이메일 초안을 준비하는 것이다. 자산을 추천하거나 시장 전망을 쓰는 과정은 넣지 않았다. 보유 수량과 입력 가격으로 평가금액·비중을 계산한다.

입력은 고객 명단과 자산 내역, 두 파일이다. 결과는 고객별 폴더에 나뉘어 저장된다. 가격이 빠진 고객은 별도로 표시하므로 담당자는 완성된 파일과 보류한 파일을 구별할 수 있다.

사람이 반복하던 단계 예제에서 처리하는 일 사람이 확인할 것
고객별 자료 나누기 고객 ID로 행 분리 ID와 수신자 연결
금액·비중 계산 수량과 단가로 계산 기준일·통화·누락
PDF 만들기 같은 양식으로 개별 생성 고객명·금액·표
메일에 파일 붙이기 해당 고객 PDF를 첨부한 초안 저장 수신자·첨부파일
발송 이번 예제에서는 실행하지 않음 실제 운영의 승인·발송 방식

계산 규칙이 정해져 있어 실행할 때마다 AI에 금액 계산을 맡길 필요는 없다. AI는 코드를 만들거나 수정하는 데 도움을 줄 수 있고, 반복 실행은 같은 규칙으로 처리하면 된다. 이 예제 실행에는 AI API 키가 필요 없다.

고객 이름보다 ID부터 맞춘다

두 사람의 이름이 같아도 자산을 합쳐서는 안 된다. 그래서 고객 명단과 자산 내역은 이름이 아닌 C001 같은 고객 ID로 연결한다. 고객 명단에는 ID·표시 이름·이메일을 적는다.

자산 파일은 엑셀에서도 열 수 있는 CSV다. CSV는 표의 행과 열을 텍스트로 저장한 파일이며, 이번 프로그램이 .xlsx를 직접 읽는 것은 아니다. 제공 파일의 열 이름을 유지하고 CSV UTF-8로 저장하면 된다.

아래는 정상 입력의 핵심 값이다. 모든 단가는 실제 시세가 아닌 가상 값이고, 통화는 원화로 고정했다. 현금은 수량에 금액, 단가에 1원을 넣었다.

고객 ID 가상 자산 수량 단가 기대 평가금액
C001 가람 예시 주식 10 100,000원 1,000,000원
C001 가람 예시 현금 2,000,000 1원 2,000,000원
C002 나래 예시 펀드 20 50,000원 1,000,000원
C002 나래 예시 현금 500,000 1원 500,000원
C003 다온 예시 채권 2 100,000원 200,000원
C003 다온 예시 현금 100,000 1원 100,000원

계산식은 수량 × 단가다. 자산별 평가금액을 원 단위로 반올림한 뒤 고객별로 합산한다. 비중은 이 금액을 고객의 총액으로 나눈다. 가람 고객의 주식은 100만원 ÷ 300만원이므로 표시 비중은 33.3%다.

코드는 십진수 계산을 위한 Python의 Decimal을 사용한다. 계산 방식과 별개로 어떤 단가·기준일을 입력했는지가 맞아야 한다. 다른 날짜의 가격이 섞이거나 통화가 KRW가 아니면 이번 예제는 생성을 중단한다.

실행하니 리포트 3개와 메일 초안 3개가 나왔다

정상 샘플을 실행한 결과는 다음과 같다. 합계는 입력표의 정답과 대조했다.

고객 총 평가금액 생성 결과
가람 C001 3,000,000원 PDF 1개·이메일 초안 1개
나래 C002 1,500,000원 PDF 1개·이메일 초안 1개
다온 C003 300,000원 PDF 1개·이메일 초안 1개
가상 고객 가람의 실제 생성 리포트. 총 평가금액 300만원과 두 자산의 비중이 표시된다.

위 이미지는 생성한 PDF를 그대로 이미지로 변환한 것이다. 디자인 목업이 아니다. 가람 고객 PDF를 열면 고객 ID·기준일·금액·계산 범위를 함께 볼 수 있다.

이메일은 .eml 파일로 저장했다. 메일의 제목·수신자·본문·첨부파일이 담긴 형식이다. Python의 이메일 예제처럼 메시지와 첨부를 구성하되, 전송 기능은 넣지 않았다.

가람 고객의 초안에는 가람 고객 PDF 하나만 들어간다. 검증에서는 수신자 주소를 대조하고, 첨부된 PDF의 바이트가 생성한 원본과 같은지도 확인했다. 파일 이름만 맞추는 것으로 끝내지 않은 것이다.

가격 하나를 비우면 어떻게 될까

정상 입력에서 다온 고객의 채권 가격만 지운 파일도 실행했다. 이때 확인 가능한 현금은 10만원이지만, 채권 가치까지 0원이라고 계산하면 안 된다.

결과는 확인된 자산 소계 10만원·전체 총액 미확정이다. 채권 행에는 가격 누락을 표시했고 자산 비중도 산정에서 제외했다. 다온 고객의 메일 초안은 만들지 않았다. 다른 두 고객의 초안은 정상적으로 생성됐다.

가격 누락 테스트에서 생성한 다온 고객의 점검용 PDF. 전체 총액 미확정과 발송 보류가 표시된다.

점검용 PDF까지 없애버리면 무엇을 고쳐야 하는지 찾기 어렵다. 그래서 누락 내용을 보여주는 파일은 남겼다. 검토할 파일이 있다는 것과 보낼 준비가 됐다는 것은 다르다.

이번에는 11개 테스트를 실행했다. 정상 합계·다른 고객 정보의 혼입·수신자와 첨부 일치·가격 누락·중복 고객과 자산·미등록 고객·잘못된 날짜와 숫자·통화 등을 확인했다. 코드의 검사 기록도 실습 묶음에 넣었다. 이 결과가 실제 고객 시스템의 모든 오류를 검증했다는 뜻은 아니다.

0원과 빈칸도 구별한다. 명시적으로 가격 0을 넣으면 값 0으로 계산하고, 빈칸이면 미확인으로 처리한다. 실제 업무에서는 가격 0 자체가 유효한지 판단하는 규칙을 추가할 수도 있다.

같은 파일로 직접 실행해보기

실습 코드·입력·정상 및 누락 결과 ZIP과 실행 안내 PDF를 준비했다. 압축 안에는 sample 폴더와 실제 생성 결과를 모은 examples 폴더가 있다. Python 실행이 익숙하지 않다면 먼저 결과 PDF 두 종류를 비교해봐도 좋다.

Python 3.11 환경에서 확인했다. 압축을 풀고 sample 폴더에서 터미널을 연 뒤 아래 명령을 순서대로 실행한다. 첫 설치에는 인터넷이 필요하며, 이후 이 프로그램은 로컬 파일로 동작한다.

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python build_reports.py --output result-normal

Windows에서는 앞의 두 줄을 py -3 -m venv .venv, .venv\Scripts\python.exe -m pip install -r requirements.txt로 실행하고, 이후 .venv/bin/python 대신 .venv\Scripts\python.exe를 쓴다. Windows 실행 자체는 이번에 검증하지 않았다.

정상 결과 폴더에는 고객별 PDF와 메일 초안, 전체 검토 목록인 review-manifest.json이 생긴다. 마지막 출력의 pdf_count와 draft_count가 각각 3인지 확인한다. sent_count는 0이다.

가격 누락 파일은 별도 결과 폴더로 실행한다.

.venv/bin/python build_reports.py --holdings data/holdings-missing-price.csv --output result-missing
.venv/bin/python test_reports.py

누락 테스트는 PDF 3개·메일 초안 2개·보류 1개가 기대 결과다. 이미 존재하는 결과 폴더를 지정하면 중단한다. 다시 실행할 때는 result-normal-2처럼 새 폴더 이름을 사용하면 이전 고객 파일과 섞이지 않는다.

설치 중 모듈을 찾지 못하면 같은 .venv의 Python으로 설치와 실행을 했는지 확인한다. 열 이름 오류가 나면 제공 CSV의 첫 줄과 비교한다. ID를 새로 만들었다면 고객 명단과 자산 파일 양쪽에 같은 값이 있어야 한다.

AI에게 내 업무에 맞춰 바꿔달라고 요청한다면, 아래처럼 기대 결과까지 함께 전달할 수 있다.

첨부한 가상 고객별 리포트 예제를 읽고 구조를 먼저 설명해줘.
고객 ID별로 자료를 분리하고, 합계와 첨부파일이 맞는지 확인해줘.
가격이 없는 고객은 총액을 확정하거나 메일 초안을 만들지 말아줘.
정상 3건과 누락 1건의 기대 결과를 유지하면서 수정해줘.
실제 고객 자료와 이메일 발송 기능은 이번 범위에 넣지 말아줘.

실제 고객 업무로 옮길 때 남는 일

여기까지 자동화한 것은 반복 계산·문서 생성·첨부 준비다. 업무에서 쓰려면 고객 원장과 가격 자료를 어디서 가져오는지, 같은 고객 ID가 유지되는지, 담당자가 어떤 기준으로 검토하는지를 먼저 정해야 한다.

샘플은 가상 수신자 주소인 @example.invalid만 허용한다. 실제 주소를 넣으면 생성을 중단하도록 만들었다. 실무 발송을 붙이는 작업에는 수신자 관리, 승인 기록, 중복 발송 방지, 실패 시 재처리와 접근 권한이 별도로 필요하다.

시간 절감은 아직 비교하지 않았다. 코드가 실행되는 시간 외에도 자료를 준비하고, 오류를 수정하고, 결과를 읽는 시간이 남는다. 같은 고객 수와 같은 입력으로 수작업·자동화의 전체 작업 시간을 재야 효과를 말할 수 있다.

먼저 가람 고객의 주식 수량을 10에서 12로 바꿔보세요. 새 결과 폴더에서 가람의 합계만 320만원이 되고 나래 150만원·다온 30만원은 유지되는지 확인하면 된다. 이렇게 작은 변경부터 예상과 결과를 맞춰보는 것이 실무 적용의 시작이다.

다른 자동화 후보와 비교하려면 업무 자동화 우선순위, 입력 형식부터 정리해야 한다면 샘플 파일 준비로 이어갈 수 있다. 파일 정리 자체를 실습하려면 CSV 업무 도구를 참고하면 된다.

검증 기준

  • 마지막 업데이트일: 2026-09-13
  • 실행 검증일: 2026-09-08
  • 확인 환경: macOS 26.5.2·Python 3.11.5·ReportLab 5.0.1·pypdf 6.18.0. 가상 고객 3명·자산 6행의 정상 및 가격 누락 입력을 실제 실행하고 11개 테스트와 생성 PDF 화면을 확인했다.
  • 확인 범위: PDF·로컬 이메일 초안 생성과 내용 대조. 실제 고객 자료·거래·메일 발송 및 수신·수작업 대비 시간 절감은 검증하지 않았다. 모든 자산과 가격은 가상이며 투자 추천 자료가 아니다.
  • 주요 근거: Python 이메일 메시지·첨부 예제, Python Decimal, ReportLab 문서 구성
  • 출처 적용 범위: 위 공식 문서는 코드 구성과 계산 도구의 동작 근거이며, 금융 업무 적합성이나 투자 판단을 보증하지 않는다.

직접 만든 실습 자료와 새 도구 소식

AI 도구로 만든 실습 자료, 달라진 기능과 강의 소식을 준비하고 있습니다. 발송을 시작하면 안내해 드려요. 먼저 확인 메일에서 본인 이메일을 확인해 주세요.

신청하기 전에 첫 소식 미리보기에서 내용과 자료를 확인해 보세요.

질문이나 의견을 남겨주세요

이름을 입력하지 않아도 돼요. ‘깜짝 놀란 올빼미’ 같은 별명이 자동으로 붙어요.