python程序:pdf文件分割工具

支持兩種分割方式

1.可將pdf文件按固定頁數(shù)分割,例如:100頁的PDF文件,按固定頁數(shù)30進(jìn)行分割,則實(shí)際分割為1-30,31-60,61-90,91-100


微信圖片_20210418221623.png

2.可將pdf文件按指定頁碼分割,例如:100頁的PDF文件,按指定頁碼20,50,100進(jìn)行分割,則實(shí)際分割為1-20,21-50,51-100


微信圖片_20210418221803.png

分割成功后,輸出到源文件同目錄下的新目錄中(新目錄與源文件名相同)

3.完整代碼如下:

from PyPDF2 import PdfFileReader, PdfFileWriter
import PySimpleGUI as sg
import os
import math
import re
import pyperclip

global_option = 1

# 按指定固定頁數(shù)分割PDF
def pdfSplitOp1(input_path_file, output_path, file_size):
    try:
        fine_name = os.path.splitext(os.path.basename(input_path_file))[0]
        pdf = PdfFileReader(input_path_file, False)
        idx = 0
        for page in range(pdf.getNumPages()):
            # 初始化
            if((page % file_size) == 0):
                idx = idx + 1
                pdf_writer = PdfFileWriter()
                output_path_file = os.path.join(output_path, '{}-{}.pdf'.format(fine_name, idx))
            pdf_writer.addPage(pdf.getPage(page))
            with open(output_path_file, 'wb') as out:
                pdf_writer.write(out)
        return 'success'
    except Exception as e:
        return repr(e)

# 按指定頁碼分割PDF
def pdfSplitOp2(input_path_file, output_path, list_number):
    try:
        fine_name = os.path.splitext(os.path.basename(input_path_file))[0]
        pdf = PdfFileReader(input_path_file, False)
        idx = 0
        start_page = 0
        for num in list_number:
            idx = idx + 1
            end_page = int(num)
            pdf_writer = PdfFileWriter()
            output_path_file = os.path.join(output_path, '{}-{}.pdf'.format(fine_name, idx))
            for page in range(start_page, end_page):
                pdf_writer.addPage(pdf.getPage(page))
            with open(output_path_file, 'wb') as out:
                pdf_writer.write(out)
            start_page = int(num)
        return 'success'
    except Exception as e:
        return repr(e)

# 提示對(duì)話框,用戶知悉即可
def infoDialog(info):
    sg.popup('', info, '',
             title='提示',
             custom_text='  知道了  ',
             background_color='gray',
             text_color='black',
             button_color='#9FB8AD')

# 繼續(xù)執(zhí)行對(duì)話框,用戶點(diǎn)擊下一步可繼續(xù)執(zhí)行
def nextDialog(info):
    return sg.popup('', info, '',
                    title='詢問',
                    custom_text=('  分割  ', '  取消  '),
                    background_color='gray',
                    text_color='black',
                    button_color='#9FB8AD')

def openFolderDialog(info):
    return sg.popup('', info, '',
                    title='詢問',
                    custom_text=('  打開  ', '  不用  '),
                    background_color='green',
                    text_color='black',
                    button_color='#9FB8AD')

# 錯(cuò)誤對(duì)話框,用戶知悉異常詳細(xì)信息
def exceptionDialog(info):
    return sg.popup('', info, '',
             title='異常',
             custom_text=('  知道了  ', '  復(fù)制異常信息  '),
             background_color='red',
             text_color='black',
             button_color='#9FB8AD')

# 檢查固定頁數(shù)填寫值是否符合格式要求
def checkFileSize(fileSize):
    if re.match(r"^\+?[1-9][0-9]*$", fileSize) is None:
        return False
    else:
        return True

# 檢查指定頁碼填寫值是否符合格式要求
def checkSizeList(sizeList):
    print(sizeList)
    if re.match(r"^([0-9]+)(,([0-9]+))*$", sizeList) is None:
        return False
    else:
        return True

# 設(shè)置應(yīng)用程序的主題
sg.theme('DarkAmber')

layout = [
    [sg.Text('1. 請(qǐng)選擇PDF文件')],
    [sg.FileBrowse('選擇...', size=(10, 1), file_types=(('PDF Files', '*.pdf'),)),
     sg.Input(size=(100, 1), key='_INPUT_PATH_FILE_')],
    [sg.Text('_'*30)],
    [sg.Text('2. 請(qǐng)選擇分割方式')],
    [sg.Radio('固定頁數(shù)', 'S1', enable_events=True, key='_OP01_', default=True),
     sg.Radio('指定頁碼', 'S1', enable_events=True, key='_OP02_')],
    [sg.Text('按固定頁數(shù)', key='_INFO1_'),
     sg.Input('', size=(16, 1), key='_INFO2_'),
     sg.Text('進(jìn)行分割(例如:100頁的PDF文件,按固定頁數(shù)30進(jìn)行分割,則實(shí)際分割為1-30,31-60,61-90,91-100)', size=(80, 1), key='_INFO3_')],
    [sg.Button('分割PDF文件', size=(16,1), key='_SPLIT_PDF_'),
     sg.Button('退出', size=(16,1), key='_CANCEL_')]
]

window = sg.Window('PDF分割工具', layout)

while True:
    event, values = window.read()
    if event == '_OP01_':
        # 選擇了按固定頁數(shù)分割
        global_option = 1
        window['_INFO1_'].update('按固定頁數(shù)')
        window['_INFO2_'].update('')
        window['_INFO3_'].update('進(jìn)行分割(例如:100頁的PDF文件,按固定頁數(shù)30進(jìn)行分割,則實(shí)際分割為1-30,31-60,61-90,91-100)')
    elif event == '_OP02_':
        # 選擇了按指定頁碼分割
        global_option = 2
        window['_INFO1_'].update('按指定頁碼')
        window['_INFO2_'].update('')
        window['_INFO3_'].update('進(jìn)行分割(例如:100頁的PDF文件,按指定頁碼20,50,100進(jìn)行分割,則實(shí)際分割為1-20,21-50,51-100)')
    elif event == '_SPLIT_PDF_':
        # 點(diǎn)擊了分割PDF按鈕
        # 校驗(yàn)輸入信息
        inputPathFile = values['_INPUT_PATH_FILE_']
        try:
            pageCount = PdfFileReader(inputPathFile, False).getNumPages()
        except FileNotFoundError:
            # 源文件不存在
            info = '源文件不存在,請(qǐng)選擇需要分割的PDF文件。'
            infoDialog(info)
            continue
        if(1 == global_option):
            # 如果選擇了按指定頁碼分割
            fileSize = values['_INFO2_']
            # 檢查參數(shù)
            if checkFileSize(fileSize):
                # 如果參數(shù)格式正確
                iFileSize = int(values['_INFO2_'])
                if(iFileSize >= pageCount):
                    # 如果參數(shù)值不正確
                    info = '設(shè)置的固定頁數(shù)(%s)不能大于或等于源文件的總頁數(shù)(%s)' % (iFileSize, pageCount)
                    infoDialog(info)
                    continue
                else:
                    # 如果參數(shù)值正確,提示是否執(zhí)行分割
                    fileCount = math.ceil(pageCount / iFileSize)
                    info = '源文件總計(jì)%s頁,每份文件%s頁,可以分割成%s份文件。\r\n\r\n是否分割PDF文件?' % (pageCount, iFileSize, fileCount)
                    rtn = nextDialog(info)
                    if(rtn is not None and '分割' == rtn.strip()):
                        # 點(diǎn)擊了分割按鈕
                        # 執(zhí)行分割文件
                        inputPathFile = values['_INPUT_PATH_FILE_']
                        inputPath = os.path.abspath(os.path.dirname(inputPathFile) + os.path.sep + ".")
                        inputFile = os.path.splitext(os.path.basename(inputPathFile))[0].split('.')[0]
                        outputPath = '{}\\{}'.format(inputPath, inputFile)
                        # 創(chuàng)建輸出文件夾,先判斷是否存在,存在則不創(chuàng)建,不存在則新建,使用源文件名稱作為文件夾名稱
                        try:
                            if(not os.path.exists(outputPath)):
                                os.mkdir(outputPath)
                        except OSError:
                            # 創(chuàng)建輸出文件夾失敗
                            rtn = exceptionDialog('創(chuàng)建輸出文件夾失敗!\r\n\r\n異常信息:%s' % OSError)
                            if (rtn is not None and '復(fù)制異常信息' == rtn.strip()):
                                pyperclip.copy(exceptionInfo)
                                continue
                            else:
                                continue
                        rtn = pdfSplitOp1(inputPathFile, outputPath, iFileSize)
                        if('success' == rtn):
                            rtn = openFolderDialog('分割成功!\r\n\r\n是否打開文件夾?\t\t\t\t\t')
                            if(rtn is not None and '打開' == rtn.strip()):
                                os.system("explorer.exe %s" % outputPath)
                            else:
                                continue
                        else:
                            exceptionInfo = rtn
                            rtn = exceptionDialog('執(zhí)行失?。r\n\r\n異常信息:%s' % exceptionInfo)
                            if (rtn is not None and '復(fù)制異常信息' == rtn.strip()):
                                pyperclip.copy(exceptionInfo)
                                continue
                            else:
                                continue
                        continue
                    elif(rtn is not None and '取消' == rtn.strip()):
                        # 點(diǎn)擊了取消按鈕
                        continue
                    else:
                        # 點(diǎn)擊了標(biāo)題欄的關(guān)閉(X)
                        continue
            else:
                # 如果參數(shù)格式不正確
                info = '請(qǐng)輸入正確的固定頁數(shù)(大于等于1的整數(shù))。'
                infoDialog(info)
                continue
        elif(2 == global_option):
            # 如果選擇了按指定頁碼分割
            sizeList = values['_INFO2_']
            # 檢查參數(shù)格式,是否按英文逗號(hào)分割數(shù)字
            if checkSizeList(sizeList):
                # 將其轉(zhuǎn)為列表list
                listSize = sizeList.split(",")

                # 校驗(yàn)參數(shù)值是否正確
                valFlg = True
                start_num = 1
                for num in listSize:
                    if (int(num) < start_num):
                        # 如果參數(shù)值不正確,校驗(yàn)數(shù)值是否正確:一個(gè)比一個(gè)大
                        valFlg = False
                        info = '指定頁碼需大于1,且越來越大。'
                        infoDialog(info)
                        break
                    elif (int(num) > pageCount):
                        # 如果參數(shù)值不正確,最大的數(shù)不能大于pageCount
                        valFlg = False
                        info = '最大的指定頁碼不能超過總頁數(shù)({})。'.format(pageCount)
                        infoDialog(info)
                        break
                    start_num = int(num) + 1
                start_num = 1
                if(valFlg):
                    #如果參數(shù)值正確,則允許分割
                    # 提示是否執(zhí)行分割
                    splitInfo = []
                    for num in listSize:
                        splitInfo.append(str(start_num) + '-' + str(num))
                        start_num = int(num) + 1
                    info = '源文件總計(jì)%s頁,可以分割成%s份文件:%s。\r\n\r\n是否分割PDF文件?' % (pageCount, len(listSize), splitInfo)
                    rtn = nextDialog(info)
                    if(rtn is not None and '分割' == rtn.strip()):
                        # 點(diǎn)擊了分割按鈕
                        # 執(zhí)行分割文件
                        inputPathFile = values['_INPUT_PATH_FILE_']
                        inputPath = os.path.abspath(os.path.dirname(inputPathFile) + os.path.sep + ".")
                        inputFile = os.path.splitext(os.path.basename(inputPathFile))[0].split('.')[0]
                        outputPath = '{}\\{}'.format(inputPath, inputFile)
                        # 創(chuàng)建輸出文件夾,先判斷是否存在,存在則不創(chuàng)建,不存在則新建,使用源文件名稱作為文件夾名稱
                        try:
                            if(not os.path.exists(outputPath)):
                                os.mkdir(outputPath)
                        except OSError:
                            # 創(chuàng)建輸出文件夾失敗
                            rtn = exceptionDialog('創(chuàng)建輸出文件夾失?。r\n\r\n異常信息:%s' % OSError)
                            if (rtn is not None and '復(fù)制異常信息' == rtn.strip()):
                                pyperclip.copy(exceptionInfo)
                                continue
                            else:
                                continue
                        rtn = pdfSplitOp2(inputPathFile, outputPath, listSize)
                        if('success' == rtn):
                            rtn = openFolderDialog('分割成功!\r\n\r\n是否打開文件夾?\t\t\t\t\t')
                            if(rtn is not None and '打開' == rtn.strip()):
                                os.system("explorer.exe %s" % outputPath)
                            else:
                                continue
                        else:
                            exceptionInfo = rtn
                            rtn = exceptionDialog('執(zhí)行失??!\r\n\r\n異常信息:%s' % exceptionInfo)
                            if (rtn is not None and '復(fù)制異常信息' == rtn.strip()):
                                pyperclip.copy(exceptionInfo)
                                continue
                            else:
                                continue
                        continue
                    elif(rtn is not None and '取消' == rtn.strip()):
                        # 點(diǎn)擊了取消按鈕
                        continue
                    else:
                        # 點(diǎn)擊了標(biāo)題欄的關(guān)閉(X)
                        continue
            else:
                # 如果參數(shù)格式不正確
                info = '請(qǐng)輸入正確的指定頁碼(如:3,10,27)。'
                infoDialog(info)
                continue
    elif event == sg.WIN_CLOSED or event == '_CANCEL_':
        break

window.close()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 接觸過PDF文件的人應(yīng)該對(duì)PDF文件都會(huì)有一些了解的,對(duì)于PDF文件而言,很多時(shí)候,大家需要提取一整篇PDF文件中...
    職場(chǎng)達(dá)人分享閱讀 916評(píng)論 0 0
  • 我們?cè)谌粘5霓k公中,將一個(gè)pdf文件分割成多個(gè)pdf是經(jīng)常需要做的事情,不足為奇。但是小編看到網(wǎng)上分割pdf文件的...
    追思人別後閱讀 484評(píng)論 0 0
  • 夜鶯2517閱讀 128,103評(píng)論 1 9
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,822評(píng)論 28 54
  • 兔子雖然是枚小碩 但學(xué)校的碩士四人寢不夠 就被分到了博士樓里 兩人一間 在學(xué)校的最西邊 靠山 兔子的室友身體不好 ...
    待業(yè)的兔子閱讀 2,765評(píng)論 2 9

友情鏈接更多精彩內(nèi)容