09. 워드 파일 다루기

송지윤·2025년 8월 1일

Python

목록 보기
16/20

Word 프로그램이 설치돼있어야함

python-docx 라이브러리

파이썬에는 워드 파일을 처리하기 위한 다양한 라이브러리가 존재한다. 현업에서 주로 사용하고 문서의 단락, 테이블, 이미지, 스타일 등을 적용할 수 있는 python-docx 라이브러리르 살펴본다.
python-docx는 서드 파티 라이브러리이므로 추가로 설치해야 한다. 라이브러리명은 python-docx 이므로 pip 명령으로 설치할 때는 라이브러리(패키지)명을 사용하고, 모듈명은 docx이므로 코드 내부에서 import 할 때는 docx라는 모듈명을 사용한다.
라이브러리 설치 여부 확인

pip show python-docx

python-docx 라이브러리의 주요 객체

  • Document : 워드 문서 전체를 의미한다. Document 객체는 문서의 문단에 해당하는 Paragraph 객체의 리스트를 포함한다.
  • Paragraph : 문서의 단락에 해당한다. 사용자가 워드 문서를 입력할 때 Enter 또는 Return 키를 누를 때마다 새로운 문단이 시작한다. Paragraph 객체는 하나 이상의 Run 객체의 리스트를 포함한다.
  • Run : 동일한 스타일을 가지는 연속적인 텍스트를 의미한다. 글꼴, 크기, 색상, 다른 여러 스타일 정보들을 포함하며, 텍스트 스타일이 바뀔 때마다 새로운 Run 객체가 필요하다.

워드 문서 읽기

워드 문서로부터 데이터를 읽어오는 단계는 다음과 같다.
1. 모듈을 임포트한다.

import docx
  1. 전체 워드 문서를 읽어온다. Document 객체는 워드 문서를 의미하기 때문에 가장 먼저 생성해야 한다. docx 모듈의 Document() 생성자 함수를 사용하여 인자 값으로 주어진 워드 파일이 객체의 형태로 메모리에 로딩된다.
doc = docx.Document('file_name.docx')
  1. Document 객체에 존재하는 단락(paragraphs) 정보를 가져온다. Document 객체가 가진 속성 중 paragraphs 속성은 문서의 단락에 해당하는 객체 목록을 순서대로 나열한다. 리스트 형식의 단락들을 하나씩 접근하려면 paragraphs 객체[인덱스 번호] 형식을 사용한다.
    이렇게 단락에 접근하려면 워드 문서에 몇 개의 단락이 있는지 알아야만 하고, 단락의 개수만큼 인덱스 번호를 증가시키면서 사용해야 한다. 이런 경우 반복문을 사용하면 효율적이다. 반복문을 사용하면 단락의 개수를 일일이 명시하지 않아도 되고, 워드 문서가 변경되더라도 파이썬 코드는 변경하지 않아도 된다. 더불어 단락이 많아졌을 때 반복해서 기술해야 하는 코드도 줄어든다.
doc.paragraphs[0].text
doc.paragraphs[1].text
doc.paragraphs[2].text

# 반복문
for item in doc.paragraphs :
	print(item.text)
  1. Document 객체의 속성들을 사용하여 다양한 작업을 수행한다.
  • core_properties : 문서의 핵심 속성에 대한 읽기/쓰기 액세스를 제공하는 CoreProperties 객체
  • paragraphs : 문서의 단락에 해당하는 인스턴스 목록을 문서 순서로 나열하는 Paragraph 객체
  • sections : 문서으 ㅣ각 섹션에 대한 액세스를 제공하는 Sections 객체
  • settings : 문서에 대한 문서 수준 설정에 대한 액세스를 제공하는 Settings 객체
  • styles : 문서의 스타일에 대한 액세스를 제공하는 Styles 객체
  • tables : 문서의 테이블에 해당하는 Table 객체의 리스트, 문서의 테이블 순서대로 리스트가 만들어지며, 문서의 최상위 수준에 나타나는 테이블만 리스트에 나타난다. 테이블 셀 안에 중첩된 테이블은 나타나지 않는다.
import docx

document = docx.Document('word_read_test.docx')
print('Document 객체 :', document)

# 0번째 단락 읽어오기
print('Document 의 제목 : ', document.paragraphs[0].text)
# 반복문으로 단락의 개수 변경 여부와 상관없이 단락의 개수만큼 반복
for item in document.paragraphs :
    print(item.text)
print('=' * 50)

# 테이블 가져오기
table = document.tables[0]

# table 의 행 반복하면서 cell 문자열 출력
# for i in range(len(table.rows)) :
#     print(table.rows[i].cells[0].paragraphs[0].text)
#     # 첫 번째 행의 첫번째 셀의 첫번째 단락 읽어오기
# for i in range(len(table.rows)) :
#     print(table.rows[i].cells[1].paragraphs[0].text)
# for i in range(len(table.rows)) :
#     print(table.rows[i].cells[2].paragraphs[0].text)

# 테이블 개수만큼 중첩 반복문 작성
for table in document.tables :
    # 하나의 table 내 row의 개수만큼 반복
    for i in range(len(table.rows)) :
        # 하나의 row 내에서 cell(열)의 개수만큼 반복
        for x in range(len(table.rows[i].cells)) :
            # 하나의 cell 내에서 paragraphs 의 개수만큼 반복
            for y in range(len(table.rows[i].cells[x].paragraphs)) :
                # 각 단락의 text 출력
                print(table.rows[i].cells[x].paragraphs[y].text)

print("=" * 50)

워드 문서 쓰기

워드 문서를 생성하고 데이터를 기록하는 단계
1. 모듈을 import 한다.

from docx import Document
  1. 워드 문서 전체를 의미하는 Document 객체를 생성한다.
document = Document()
  1. 문서에 구문을 추가하려면 document 객체의 add_heading() 메소드나 add_paragraph() 메소드를 사용한다. add_heading() 메소드의 첫 번째 인자 값으로는 삽입하고자 하는 텍스트를 넘겨주고, 두 번째 인자 값으로는 숫자를 넘기는데, 0은 제목, 1은 Heading1, 2는 Heading2 등의 텍스트로 표시된다. 0부터 9까지의 값을 넣을 수 있으며 숫자가 적을수록 큰 글자로 표기되고 숫자가 클수록 작은 글자로 표기된다.
document.add_heading('안녕하세요 워드 0', 0)
document.add_heading('안녕하세요 워드 1', level=1)
document.add_heading('안녕하세요 워드 2', level=2)
document.add_paragraph('안녕하세요 워드 3').alignment = align.CENTER
  1. 문서에 단락을 추가할 때 볼드나 이탤릭 등 텍스트 처리 효과를 설정할 수 있다. 이때는 add_run() 메소드를 함께 사용해야 한다. 먼저 document 객체의 add_paragraph() 메소드를 사용하여 문서에 구문을 추가하고, paragraph 객체의 add_run() 메소드를 사용하여 스타일을 설정한다.
paragraph = document.add_paragraph()
paragraph.add_run(datas[0]).bold = True
paragraph.add_run(datas[1]).italic = True
  1. 이미지를 추가하려면 document 객체의 add_picture() 메소드를 사용한다. add_picture() 메소드의 인자 값으로 추가할 이미지를 지정하고, width 인자 값으로 Inches 객체를 넘겨준다. Inches 객체를 사용하여 이미지의 높이와 너비를 인치로 설정한다. Inches 객체를 사용하기 위해 docx.shared.Inches를 먼저 import해야 한다. (1인치 == 2.64cm)
import docx.shared import Inches
document.add_picture('python.png', width=Inches(1.25))
  1. 테이블을 추가할 수도 있다. document 객체의 add_table() 메소드를 사용한다. 하나의 행과 3개의 열로 구성된 표를 생성하려면 rows와 cols에 값을 지장한다.
table = document.add_table(rows=1, cols=3)

table 객체의 rows와 columns를 사용하여 테이블에 딕셔너리 형태의 data를 입력하려면, 다음과 같이 코드르 작성한다.

data = {'id':1, 'items':'갤럭시', 'price':100}

테이블의 첫 번째 행의 셀들을 가져온다.

headings = table.rows[0].cells

각 셀에 텍스트를 넣는다. 이때 셀은 테이블의 헤딩이 된다. 헤딩은 테이블의 첫 번째 행을 의미한다. 테이블 열의 제목이 된다.

headings[0].text = 'Id'
headings[1].text = 'Items'
headings[2].text = 'Price'

헤딩 뒤에 새 행을 추가하고 데이터 딕셔너리에서 값을 가져와서 행의 열(cell) 값들을 채운다.

row = table.add_row().cells

딕셔너리로부터 키를 주고 값을 가져온 후, 행의 첫 번째 열부터 텍스트값으로 삽입한다.

row[0].text = str(data['id'])
row[1].text = str(data['items'])
row[2].text = str(data['price'])
  1. 문서를 저장한다. save() 메소드의 인자값으로는 생성할 워드 파일의 이름을 지정한다.
document.save('docTest.docx')

워드 문서 생성

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH as align

document = Document()

# Title 텍스트로 표시, 0은 제목, 1은 Heading1, 2는 Heading2 텍스트로 표시
document.add_heading('파이썬 워드 문서 만들기', level=0)
document.add_heading('가운데 정렬').alignment = align.CENTER

datas = ['워드 목록 1'
         ,'워드 목록 2'
         ,'워드 목록 3']

for data in datas :
    document.add_paragraph(data, style='List Bullet')

# 새 라인을 추가, 볼드와 이텔릭 등 테스트 처리
paragraph = document.add_paragraph()
paragraph.add_run(datas[0]).bold = True
paragraph.add_run(datas[1]).italic = True
paragraph.add_run(datas[2])

document.add_paragraph('파이썬 로고 이미지').alignment = align.CENTER
document.add_picture('python.jfif')
document.save('word_write_result.docx')

  1. docx 모듈을 import할 때 Document 객체의 이름을 모듈명 없이 사용하려면 from 구문으로 import 한다.
from docx import Document
  1. 정렬을 위한 WD_ALIGN_PARAGRAP을 align이라는 에일리어스 설정하면서 import 한다.
from docx.enum.text import WD_ALIGN_PARAGRAPH as align
  1. 워드 문서 자체를 의미하는 Document 객체를 생성한다.
document = Document()
  1. 헤딩 문자열은 제목으로 추가하고, 구문을 가운데 정렬로 추가한다.
document.add_heading('파이썬 워드 문서 만들기', level=0)
document.add_heading('가운데 정렬').alignment = align.CENTER
  1. 구문에 기록할 내용을 datas 리스트에 만든다.
datas = ['워드 목록 1'
         ,'워드 목록 2'
         ,'워드 목록 3']
  1. datas 리스트로부터 하나씩 꺼내어 문서에 구문으로 삽입하는데, List Bullet 형태의 글머리표를 추가한다.
for data in datas :
    document.add_paragraph(data, style='List Bullet')
  1. 볼드와 이탤릭 등 텍스트 스타일을 가지는 구문을 추가한다.
paragraph = document.add_paragraph()
paragraph.add_run(datas[0]).bold = True
paragraph.add_run(datas[1]).italic = True
paragraph.add_run(datas[2])
  1. 이미지를 추가한다.
document.add_picture('python.jfif')
  1. word_write_result.docx 라는 이름으로 저장한다.
document.save('word_write_result.docx')

케이스 스터디 - 워드 작업

파이썬으로 현업에서 사용할 수 있는 간단한 케이스 스터디를 진행한다. 이 예제는 한 회사의 신입사원들 정보 중에서 신입 사원이 속한 팀과 교육의 필요 여부를 판단하여, 각 팀별로 실시하는 교육 정보를 담고 있는 워드 파일을 각 사원의 이름으로 생성하는 업무를 프로그램으로 작성한다. 작성 할 워드 파일은 다음과 같다.

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH as align

from word_test.word_write import paragraph

datas = [
    {'사번' : '11111', '이름' : '홍길동', '부서' : '경영지원팀', '교육 여부' : True},
    {'사번' : '22222', '이름' : '전우치', '부서' : '경영지원팀', '교육 여부' : False},
    {'사번' : '33333', '이름' : '이순신', '부서' : '개발팀', '교육 여부' : True},
    {'사번' : '44444', '이름' : '신사임당', '부서' : '개발팀', '교육 여부' : False},
    {'사번' : '55555', '이름' : '또치', '부서' : '개발팀', '교육 여부' : True},
    {'사번' : '66666', '이름' : '고길동', '부서' : '클라우드팀', '교육 여부' : False},
    {'사번' : '77777', '이름' : '둘리', '부서' : '클라우드팀', '교육 여부' : True},
    {'사번' : '88888', '이름' : '도우너', '부서' : '클라우드팀', '교육 여부' : False}
]

teams = {
    '경영지원팀' : ['엑셀 기본', '엑셀로 작업하기'],
    '개발팀' : ['파이썬 핵심', '파이썬 데이터 분석'],
    '클라우드팀' : ['클라우드 아키텍처', '멀티 하이브리드 환경 이해']
}

for person in datas :
    # 한 사원의 정보 중에서 교육 여부가 True인 사람만 선택
    if person['교육 여부'] :
        # 워드 문서 생성
        document = Document()
        # 사원의 이름을 가져온다
        name = person['이름']
        # 워드 문서에 단락 추가 가운데 정렬
        document.add_heading('신입 사원 교육 정보', level=0).alignment = align.CENTER
        # 워드 문서에 단락 추가
        document.add_paragraph('안녕하세요 {0}님'.format(name))
        document.add_paragraph('귀하의 부서에서는 아래 교육을 진행합니다.').alignment = align.CENTER
        # 부서명
        dept = person['부서']
        # 부서명으로 teams 에서 부서 교육 내용 가져오기
        for team in teams[dept] :
            # teams의 키 값을 dept로 바로 넣어줌
            paragraph = document.add_paragraph()
            paragraph.add_run(team).bold = True
        document.add_paragraph('감사합니다.').alignment = align.RIGHT

        # 파일의 내용을 저장. 사원의 이름으로 파일명 생성
        document.save('신입사원교육_{0}.docx'.format(name))

0개의 댓글