안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다.
코딩유치원에서는 파이썬 기초부터 사무자동화, 웹크롤링, 데이터 분석 등의 다양한 패키지까지 초보자도 알기 쉽도록 내용을 정리해 놓았습니다.
업무는 물론 투자에도 도움이 될만한 전자공시시스템(DART)나 텔레그램(Telegram) 관련 패키지도 배울 수 있으니 많은 관심 부탁드립니다.
오늘은 파이썬으로 pdf 파일을 다루는 법에 대해서 공부해보겠습니다.
<목차>
1. PyPDF2란?
2. 페이지 추출
3. PDF 분할
4. PDF 회전
5. PDF 병합
1. PyPDF2란?
PyPDF2는 이름에서 직관적으로 알 수 있듯이 Python으로 PDF 문서를 다룰 수 있게 해주는 라이브러리입니다.
참고로 설치는 아래의 코드 한 줄을 커맨드 창에 입력해주시면 됩니다. 대소문자에 주의해주세요!
pip install PyPDF2
아래의 링크는 PyPDF2 공식 문서이며, 그 안에는 여러 기능들이 있지만 이번 시간에는 코딩유치원 컨셉에 맞게 최대한 쉽고 가장 자주 사용할 만한 기능 위주로 설명드리겠습니다.
https://pythonhosted.org/PyPDF2/
PyPDF2 Documentation — PyPDF2 1.26.0 documentation
pythonhosted.org
PyPDF2는 크게 3가지 클래스)로 나눌 수 있습니다.
1) 원하는 작업을 하기 위해 pdf 파일을 불러올 때 사용하는 PdfFileReader
2) 회전, 추출, 분리 등의 페이지 단위 작업을 할 때 사용하는 PdfFileWriter
(참고로, 회전은 한번에 하는 것이 아니라, 페이지 하나씩 돌려서 새로운 pdf에 붙여넣는 방식입니다)
3) 여러 pdf 파일을 하나의 pdf로 병합할 때 사용하는 PdfFileMerger
<2023.02.11 - PyPDF2 버전 3.0.1 기준 변경 사항>
PdfFileReader → PdfReader
PdfFileWriter → PdfWriter
PdfFileMerger → PdfMerger
지금부터는 위에서 배운 PyPDF2 모듈들을 이용해서 우리가 자주 사용하는 기능들을 구현해보겠습니다.
2. 페이지 추출
가장 처음으로 원하는 페이지를 추출해보겠습니다.
저는 쉬운 이해를 위해서 테스트용 PDF를 만들어서 사용하였으나, 여러분들은 각자의 PDF 파일을 사용하시면 되는 점 참고바랍니다.
테스트 PDF 파일 1.pdf에서 2번째 페이지만 추출해서 따로 저장해보겠습니다.
<코드>
# step1.관련 모듈 import
from PyPDF2 import PdfFileReader, PdfFileWriter
# step2.기존 pdf 불러오기
pdfReader = PdfFileReader("테스트 PDF 파일 1.pdf", "rb")
# step3.새로 만들 pdf 객체 생성
pdfWriter = PdfFileWriter()
# step4.기존의 1번 페이지를 가져와서 새로만든 pdf에 붙여넣기
pdfWriter.addPage(pdfReader.getPage(1))
# step5.1번 페이지가 붙여진 새로운 pdf 파일을 현재 경로('./')에 원하는 이름으로 저장
pdfWriter.write(open("./추출한 테스트 PDF 파일.pdf", "wb"))
<코드> PyPDF2 (ver 3.0.0 이상)
* 변경점
addPage(page_number) → add_page(page_number)
.getPage(page_number) → .pages[page_number]
# step1.관련 모듈 import
from PyPDF2 import PdfReader, PdfWriter
# step2.기존 pdf 불러오기
pdfReader = PdfReader("테스트 PDF 파일 1.pdf", "rb")
# step3.새로 만들 pdf 객체 생성
pdfWriter = PdfWriter()
# step4.기존의 1번 페이지를 가져와서 새로만든 pdf에 붙여넣기
pdfWriter.add_page(pdfReader.pages[1])
# step5.1번 페이지가 붙여진 새로운 pdf 파일을 현재 경로('./')에 원하는 이름으로 저장
with open("./추출한 테스트 PDF 파일.pdf", "wb") as output_file:
pdfWriter.write(output_file)
<결과물>
3. PDF 분할
다음으로 구현해 볼 기능은 페이지를 분할하는 것입니다.
페이지 추출과 거의 비슷하지만 2가지가 다릅니다.
1) 기존 PDF의 페이지 수를 파악해서 for문으로 한 페이지씩 처리
- numPages 함수로 기존 PDF 파일의 전체 페이지 수 파악
- getPage( ) 함수로 지정한 PDF 페이지 한 장 가져오기
2) 마지막 저장 시, f 문자열 포매팅 개념을 이용해서 pageNum 변수를 파일명에 반영
<코드>
# step1.관련 모듈 import
from PyPDF2 import PdfFileReader, PdfFileWriter
# step2.기존 PDF 불러오기
pdfReader = PdfFileReader("테스트 PDF 파일 1.pdf", "rb")
# 페이지 하나씩 받아와서 저장하는 반복문
for pageNum in range(pdfReader.numPages):
# step3.새로 만들 pdf 객체 생성 (계속 누적되지 않기 위해 for문 안으로 넣음)
pdfWriter = PdfFileWriter()
# step4.기존 PDF에서 한 페이지씩 가져오기
page = pdfReader.getPage(pageNum)
# step5.위에서 가져온 페이지를 새로 만든 PDF에 붙여넣기
pdfWriter.addPage(page)
# step6.새로운 PDF 파일을 해당 경로('./')에 원하는 이름으로 저장
# (이름을 계속 다르게 해주기 위해서 f 문자열 포매팅 개념을 이용)
pdfWriter.write(open(f"./분할한 PDF 파일 {pageNum+1}.pdf", "wb"))
<코드> PyPDF2 (ver 3.0.0 이상)
* 변경점
pdfReader.numPages → len(pdfReader.pages)
addPage(page_number) → add_page(page_number)
.getPage(page_number) → .pages[page_number]
# step1.관련 모듈 import
import os
from PyPDF2 import PdfReader, PdfWriter
# step2.기존 PDF 불러오기
pdfReader = PdfReader("테스트 PDF 파일 1.pdf", "rb")
# 페이지 하나씩 받아와서 저장하는 반복문
for pageNum in range(len(pdfReader.pages)):
# step3.새로 만들 pdf 객체 생성 (계속 누적되지 않기 위해 for문 안으로 넣음)
pdfWriter = PdfWriter()
# step4.기존 PDF에서 한 페이지씩 가져오기
page = pdfReader.pages[pageNum]
# step5.위에서 가져온 페이지를 새로 만든 PDF에 붙여넣기
pdfWriter.add_page(page)
# step6.분할된 PDF 파일을 저장할 폴더 생성
output_dir = "./분할된_PDF"
os.makedirs(output_dir, exist_ok=True)
# step7.새로운 PDF 파일을 생성한 폴더에 저장
# (이름을 계속 다르게 해주기 위해서 f 문자열 포매팅 개념을 이용)
with open(f"{output_dir}/분할한 PDF 파일 {pageNum+1}.pdf", "wb") as output_file:
pdfWriter.write(output_file)
<결과물>
4. PDF 회전
위에서 배운 PDF 분할에서 딱 2가지만 달라졌습니다.
1) rotate( ) 함수로 회전
2) pdfWriter가 for문 밖으로 나감 (기존의 pdf를 회전시키고 새로운 PDF에 계속 붙여넣어 주어야하기 때문)
이 부분에 유의하시면서 아래의 코드를 보시면 좋을 것 같습니다.
# step1.관련 모듈 import
from PyPDF2 import PdfFileReader,PdfFileWriter
# step2.기존 pdf 불러오기
pdfReader = PdfFileReader(open("테스트 PDF 파일 1.pdf","rb"))
# step3.새로 만들 pdf 객체 생성
pdfWriter = PdfFileWriter()
# 페이지 하나씩 받아와서 돌린 후, 붙여넣는 반복문
for pageNum in range(pdfReader.numPages):
# step4.기존 PDF에서 한 페이지씩 가져오기
page = pdfReader.getPage(pageNum)
# step5.시계 방향으로 90도 회전 (반시계로 90도 회전은 270 입력하면 됨)
page.rotateClockwise(90)
# step6.회전된 페이지 새로운 PDF에 붙여넣기
pdfWriter.addPage(page)
# step7.새로운 pdf 파일을 해당 경로('./')에 원하는 이름으로 저장
pdfWriter.write(open('./회전한 테스트 PDF 파일.pdf', 'wb'))
<코드> PyPDF2 (ver 3.0.0 이상)
* 변경점
rotateClockwise( ) → rotate( )
pdfReader.numPages → len(pdfReader.pages)
addPage(page_number) → add_page(page_number)
.getPage(page_number) → .pages[page_number]
# step1.관련 모듈 import
from PyPDF2 import PdfReader, PdfWriter
# step2.기존 pdf 불러오기
pdfReader = PdfReader("데이터 자격시험 일정_2022.pdf", "rb")
# step3.새로 만들 pdf 객체 생성
pdfWriter = PdfWriter()
# 페이지 하나씩 받아와서 돌린 후, 붙여넣는 반복문
for pageNum in range(len(pdfReader.pages)):
# step4.기존 PDF에서 한 페이지씩 가져오기
page = pdfReader.pages[pageNum]
# step5.시계 방향으로 90도 회전 (반시계로 90도 회전은 270 입력하면 됨)
page.rotate(90)
# step6.회전된 페이지 새로운 PDF에 붙여넣기
pdfWriter.add_page(page)
# step7.새로운 pdf 파일을 해당 경로('./')에 원하는 이름으로 저장
with open('./회전한 테스트 PDF 파일.pdf', 'wb') as output_file:
pdfWriter.write(output_file)
<결과물>
4. PDF 병합
병합은 앞서 배운 분할과 회전에 비해서 매우 간단합니다.
PdfFileWriter가 아니라 PdfFileMerger를 import 해준 점만 주의 하시면 아래 코드 이해하시는데에 어려움 없으시리라 생각합니다.
<코드>
# step1.관련 모듈 import (Writer 대신 Merger를 사용하는 것에 주의!)
from PyPDF2 import PdfFileReader, PdfFileMerger
# step2.기존 pdf 불러오기
pdfReader1 = PdfFileReader(open("테스트 PDF 파일 1.pdf","rb")) # 3장
pdfReader2 = PdfFileReader(open("테스트 PDF 파일 2.pdf","rb")) # 2장
# step3.새로 만들 pdf 객체 생성 (병합용)
pdfMerger = PdfFileMerger()
# step4.PDF 하나씩 가져와서 차례대로 병합
pdfMerger.append(pdfReader1)
pdfMerger.append(pdfReader2)
# step5.새로운 pdf 파일을 해당 경로('./')에 원하는 이름으로 저장
pdfMerger.write("./병합한 테스트 PDF 파일.pdf")
<코드> PyPDF2 (ver 3.0.0 이상)
* 변경점
PdfReader와 PdfMerger 클래스 외에는 따로 변경점 없음
# step1.관련 모듈 import (Writer 대신 Merger를 사용하는 것에 주의!)
from PyPDF2 import PdfReader, PdfMerger
import os
# 분할된 PDF 파일이 저장된 폴더 경로
output_dir = "./분할된_PDF"
# step2.기존 pdf 불러오기 - with 구문 사용
with open(f"{output_dir}/분할한 PDF 파일 1.pdf", "rb") as file1, \
open(f"{output_dir}/분할한 PDF 파일 2.pdf", "rb") as file2:
pdfReader1 = PdfReader(file1) # 3장
pdfReader2 = PdfReader(file2) # 2장
# step3.새로 만들 pdf 객체 생성 (병합용)
pdfMerger = PdfMerger()
# step4.PDF 하나씩 가져와서 차례대로 병합
pdfMerger.append(pdfReader1)
pdfMerger.append(pdfReader2)
# step5.새로운 pdf 파일을 해당 경로('./')에 원하는 이름으로 저장
with open("./병합한 테스트 PDF 파일.pdf", "wb") as output_file:
pdfMerger.write(output_file)
# 자원 해제
pdfMerger.close()
<결과물>
오늘 준비한 내용은 여기까지입니다.
관련 내용을 한 번에 다 넣으려다 보니 글이 길어졌네요.
다음에 시간을 내어서 Tkinter와 연동해서 간단하게 GUI 기반의 PDF 변환 프로그램을 만들어 보겠습니다.
오늘도 공부하시느라 고생 많으셨습니다~
'파이썬 패키지 > PDF' 카테고리의 다른 글
[Python/PyMuPDF] 파이썬으로 PDF 문서에서 특정 텍스트 형광펜으로 표시하기 (1) | 2024.03.10 |
---|