支持兩種分割方式
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()