본문 바로가기

Python 개발일지: 회사문서 PDF를 엑셀로 변환하는 프로그램 개발

[월요일]

반응형

저에게 PDF를 엑셀로 변환하는 프로그램을 개발하라는 미션이 주어졌습니다. 우선 기본 알고리즘을 설계해야 했습니다. 

- 배경: 두산 에너빌리티, 한국수력원자력공사에서 수신받은 PDF 문서들을 엑셀에 정리해야 하는 작업이 있습니다. 문제는 PDF 하나당 기본적으로 70페이지가 넘는 데다가, 처리해야 하는 PDF 문서들이 많다는 점입니다. 이 작업을 사람이 일일이 하다 보면 최소 3일이 걸릴 정도로 시간이 많이 걸립니다. 이 작업을 프로그램으로 자동화하면 상당한 시간을 아낄 수 있습니다. 

- 기본 알고리즘: "PDF 문서의 텍스트를 읽어들여서, 요건번호와 텍스트를 분리한 후 엑셀의 각 위치에 입력하자."

즉, 문자열을 다루는 알고리즘이기 때문에 문자열 처리에 용이한 언어를 선택해야 한다고 생각했습니다. 따라서 개발 언어는 파이썬, 개발 환경은 Visual Studio Code으로 정했습니다.
두 양식 중 두산 에너빌리티 문서가 더 간단해 보여서, 두산 문서를 먼저 해결하기로 결정했습니다. 파이썬에는 PDF를 열어서 텍스트를 추출하는 라이브러리 "fitz", Excel 파일을 생성하고 텍스트를 입력하는 라이브러리 "openpyxl"이 있습니다. 이를 활용하여, 한 페이지의 문서 내용을 "요건 번호 - 텍스트 내용"으로 분류하는 알고리즘 및 코드를 작성했습니다. 
다른 인턴님이 새로운 라이브러리 "pdfminer"를 찾아주셔서, 이를 활용한 새로운 코드를 작성했습니다. 기존의 코드는 한 페이지에 대해서만 적용 가능한 코드였던 반면, 새롭게 작성한 코드는 전체 페이지에 적용 가능한 코드였습니다.

 

<코드1: 내 코드>

import fitz  # PyMuPDF
import openpyxl

def pdf_to_excel(pdf_path, excel_path):
    # PDF 파일 열기
    pdf_document = fitz.open(pdf_path)
    
    # 새 엑셀 파일 생성
    workbook = openpyxl.Workbook()
    sheet = workbook.active
    
    row = 1  # 두 번째 행부터 시작
    
    # PDF 페이지 순회
    for page_num in range(len(pdf_document)):
        page = pdf_document.load_page(page_num)
        text = page.get_text("text")
        
        # 문장을 줄 단위로 분리
        lines = text.split('\n')

        # 전처리: 머리말 지우기
        del lines[:5]

        print(lines)

        newlines = []
        digits=[]
        for i, line in enumerate(lines):
            if len(line) > 0 and line[0].isdigit():
                digits.append(line)
            else:
                if lines[i-1][0].isdigit() or i == 0:
                    newlines.append(line)
                else:
                    newlines[-1] += '\n' + line


        print('\n\n'.join(newlines))

        # 엑셀 파일에 입력
        for digit, line in zip(digits, newlines):
            if line.strip():  # 빈 줄이 아니면
                sheet.cell(row=row, column=1).value = digit.strip()
                sheet.cell(row=row, column=2).value = line.strip()
                row += 1


    # 엑셀 파일 저장
    workbook.save(excel_path)
    print(f"PDF 내용을 {excel_path} 파일에 저장했습니다.")

# 함수 실행 예시
pdf_path = r"PDF파일경로.pdf"
excel_path = r"엑셀경로.xlsx"
pdf_to_excel(pdf_path, excel_path)

 

 

 

<코드2: 다른 인턴분 코드>

from pdfminer.high_level import extract_text
from pdfminer.layout import LAParams
import pandas as pd
import re

pdf_file_path = r"C:\Users\SAMSUNG\OneDrive\Desktop\pdftoexcel\PDF참고자료1.pdf"

start_page = 4
end_page = 120

print("start")
print(pdf_file_path)

# PDF 파일에서 텍스트 추출
text = extract_text(pdf_file_path, laparams=LAParams(), page_numbers=range(start_page, end_page))
print(text)

# 추출한 텍스트 출력
my_list = text.split('\n')
del_list = ["DOOSAN", "Z11056-614PS-001C (Rev02)", "Document No.(Revision No.)", "Material Purchase Specification", ""]

my_list = [item for item in my_list if item not in del_list]
my_list = [item for item in my_list if item != ""]
my_list = [item for item in my_list if item[0:4] != "Page"]

str_list = []
num_list = []

tmp = ""
for i in range(len(my_list)):
    cur = my_list[i]
    if cur[0].isdigit() and len(cur) >= 2 and cur[1] == ".":

        if tmp != "":
            str_list.append(tmp)
            tmp = ""

        split_list= my_list[i].split(" ")
        num_list.append(split_list[0])

        for i in range(1,len(split_list)):
            tmp+=split_list[i] + " "


    else:
        tmp += cur

if tmp != "":
    str_list.append(tmp)

# 비정상적인 문자 제거 함수
def remove_illegal_characters(text):
    # 허용되지 않는 문자 제거 (예: ASCII 범위 외 문자 및 특정 제어 문자)
    return re.sub(r'[^\x20-\x7E]', '', text)

# str_list에서 비정상적인 문자 제거
str_list = [remove_illegal_characters(s) for s in str_list]

# num_list와 str_list의 길이가 동일한지 확인하고, 맞추기
if len(num_list) > len(str_list):
    str_list.extend([""] * (len(num_list) - len(str_list)))
elif len(str_list) > len(num_list):
    num_list.extend([""] * (len(str_list) - len(num_list)))

for i in range(len(num_list)):
    print(num_list[i] + ": " + str_list[i])

# 데이터프레임 생성
df = pd.DataFrame({'No': num_list, 'Document': str_list})

# 엑셀 파일로 저장
excel_file_path = r"C:\Users\SAMSUNG\OneDrive\Desktop\Exceltest1.xlsx"
df.to_excel(excel_file_path, index=False)

print("end")

반응형

'Python 개발일지: 회사문서 PDF를 엑셀로 변환하는 프로그램 개발' 카테고리의 다른 글

[금요일]  (0) 2024.07.13
[목요일]  (0) 2024.07.13
[화요일]  (0) 2024.07.13