小編給大家分享一下Python中如何使用pypdf2合并、分割、加密pdf文件,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Python是一種編程語言,內(nèi)置了許多有效的工具,Python幾乎無所不能,該語言通俗易懂、容易入門、功能強大,在許多領(lǐng)域中都有廣泛的應(yīng)用,例如最熱門的大數(shù)據(jù)分析,人工智能,Web開發(fā)等。
朋友需要對一個pdf文件進行分割,在網(wǎng)上查了查發(fā)現(xiàn)這個pypdf2可以完成這些操作,所以就研究了下這個庫,并做一些記錄。首先pypdf2是python3版本的,在之前的2版本有一個對應(yīng)pypdf庫。
可以使用pip直接安裝:
pip install pypdf2
官方文檔: pythonhosted.org/PyPDF2/
里面主要有這幾個類:
PdfFileReader 。
該類主要提供了對pdf文件的讀操作,其構(gòu)造方法為:
PdfFileReader(stream, strict=True, warndest=None, overwriteWarnings=True)
第一個參數(shù)可以傳入一個文件流,或者一個文件路徑。后面三個參數(shù)都是用來設(shè)置警告的處理方式,直接使用默認的即可。
得到實例之后,就可以對pdf進行一些操作了。主要的有以下幾個操作:
decrypt(password):如果pdf文件加密的話,可以使用該方法對其解密。
getDocumentInfo():檢索pdf文件的一些信息。其返回值為一個DocumentInformation 類型,直接輸出的話會得到類似下面的信息:
{'/ModDate': "D:20150310202949-07'00'", '/Title': '', '/Creator': 'LaTeX with hyperref package', '/CreationDate': "D:20150310202949-07'00'", '/PTEX.Fullbanner': 'This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/MacPorts 2014_6) kpathsea version 6.2.0', '/Producer': 'pdfTeX-1.40.15', '/Keywords': '', '/Trapped': '/False', '/Author': '', '/Subject': ''}getNumPages():這個會pdf文件中的頁數(shù)。
getPage(pageNumber):會得到pdf文件中對應(yīng)的pageNumber頁數(shù)的頁面對象,返回值為PageObject實例。在得到PageObject實例之后就可以將其加添、插入等操作。
getPageNumber(page):與上面的方法對立,可以傳入PageObject實例,然后得到該實例是pdf文件中第幾頁的。
getOutlines(node=None, outlines=None):檢索文檔中出現(xiàn)的文檔大綱。
isEncrypted:記錄該pdf是否加密。如果文件本身加密,即使在使用解密decrypt方法之后,還是會返回true。
numPages:pdf總共的頁數(shù),相當于訪問getNumPages()的只讀屬性。
PdfFileWriter 。
該類支持對pdf文件進行寫操作,通常是使用PdfFileReader讀取一些pdf數(shù)據(jù),然后使用該類進行一些操作。
創(chuàng)建該類的實例時不需要參數(shù)。
其主要的方法有:
addAttachment(fname, fdata):向pdf添加文件。
addBlankPage(width=None, height=None):給pdf添加一個空白頁到最后,如果沒有指定大小就使用當前Weiter中pdf最后一頁的大小。
addPage(page):添加page到pdf中,通常這個page是由上面的Reader獲取的。
appendPagesFromReader(reader, after_page_append=None):將reader中的數(shù)據(jù)拷貝到當前的Writer實例中,并且如果指定after_page_append的話,最后還有回掉該函數(shù)并且將writer中的數(shù)據(jù)傳入其中。
encrypt(user_pwd, owner_pwd=None, use_128bit=True):將pdf進行加密,其中官方說userpwd是允許用戶使用一些限制的權(quán)限打開pdf文件,也就是使用該密碼的話可能會有一些限制,但是本人并沒有在文檔中找到設(shè)置權(quán)限的內(nèi)容。而ownerpwd則是允許用戶無限制的使用。第三個參數(shù)是是否使用128位加密。
getNumPages():得到pdf頁數(shù)。
getPage(pageNumber):得到對應(yīng)頁數(shù)的Page,是一個PageObject對象,可以使用上面的addPage方法將page進行添加。
insertPage(page, index=0):將page添加到pdf中,index指定的是被插入的位置。
write(stream):將該Writer中的內(nèi)容寫入到文件中。
PdfFileMerger。
該類用來合并pdf文件,該類的構(gòu)造方法有一個參數(shù):PdfFileMerger(strict=True),注意這里的參數(shù)后面會介紹:
常用方法:
addBookmark(title, pagenum, parent=None):給pdf添加一個書簽,title是書簽的標題,pagenum是該書簽指向的頁面。
append(fileobj, bookmark=None, pages=None, import_bookmarks=True):將指定的fileobj文件添加到文件的末尾,bookmark是贖前,pages可以使用(start, stop[, step])或者一個 Page Range來設(shè)定將fileobj中的指定范圍的頁面進行添加。
merge(position, fileobj, bookmark=None, pages=None, import_bookmarks=True):與append方法類似,不過可以使用position參數(shù)指定添加的位置。
write(fileobj):將數(shù)據(jù)寫入到文件中。
使用的時候可以創(chuàng)建一個PdfFileMerger實例,然后使用append或者merge將想要融合的pdf文件依次添加進去,最后使用write保存即可。
def merge_pdf():
# 創(chuàng)建一個用來合并文件的實例
pdf_merger = PdfFileMerger()
# 首先添加一個Week1_1.pdf文件
pdf_merger.append('Week1_1.pdf')
# 然后在第0頁后面添加ex1.pdf文件
pdf_merger.merge(0, 'ex1.pdf')
# 添加書簽
pdf_merger.addBookmark('這是一個書簽', 1)
# 將其寫入到文件中
pdf_merger.write('merge_pdf.pdf')下面看一下PdfFileMerger(strict=True)中的這個參數(shù):
官方對這個參數(shù)的解釋:
strict (bool) – Determines whether user should be warned of all problems and also causes some correctable problems to be fatal. Defaults to True.
確定是否應(yīng)該警告用戶所有問題,并且還會導致一些可糾正的問題。
剛開始感覺這個參數(shù)就是用來是否警告用戶一些錯誤的,直接使用默認即可,但是當本人嘗試合并帶中文的pdf時,出現(xiàn)了如下錯誤:
Traceback (most recent call last):
File "I:\python3.5\lib\site-packages\PyPDF2\generic.py", line 484, in readFromStream
return NameObject(name.decode('utf-8'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc8 in position 10: invalid continuation byte
During handling of the above exception, another exception occurred:
PyPDF2.utils.PdfReadError: Illegal character in Name Object在源碼包中使用utf解碼的時候出錯了,嘗試修改此處源碼,讓其使用gbk,但是還出現(xiàn)了其他的錯誤。最后發(fā)現(xiàn)當把構(gòu)造函數(shù)中的strict設(shè)置為False時,控制臺會打印下面的錯誤:
PdfReadWarning: Illegal character in Name Object [generic.py:489]
但是兩個文件成功的合并了,并且大概看了下合并后的文件有時好又是壞,同樣的代碼運行多次,有時候能夠正常處理中文,但有時候中文亂碼。
除了列出的方法還有一些其他的方法,比如添加書簽、添加鏈接等等,可以參考官方文檔。
對pdf進行合并、分割、加密。
整合出來了加密、解密、合并、根據(jù)頁數(shù)進行分割、根據(jù)份數(shù)進行分割的樣例:
使用注意:如果時中文文件,運行結(jié)果可能會出現(xiàn)亂碼,但是多運行幾次,中間有正常顯示中文的問題。具體原因還不清楚,但就是這么玄學。。。
代碼傳送門
# @Time : 2018/3/26 23:48
# @Author : Leafage
# @File : handlePDF.py
# @Software: PyCharm
# @Describe: 對pdf文件執(zhí)行合并、分割、加密操作。
from PyPDF2 import PdfFileReader, PdfFileMerger, PdfFileWriter
def get_reader(filename, password):
try:
old_file = open(filename, 'rb')
except IOError as err:
print('文件打開失敗!' + str(err))
return None
# 創(chuàng)建讀實例
pdf_reader = PdfFileReader(old_file, strict=False)
# 解密操作
if pdf_reader.isEncrypted:
if password is None:
print('%s文件被加密,需要密碼!' % filename)
return None
else:
if pdf_reader.decrypt(password) != 1:
print('%s密碼不正確!' % filename)
return None
if old_file in locals():
old_file.close()
return pdf_reader
def encrypt_pdf(filename, new_password, old_password=None, encrypted_filename=None):
"""
對filename所對應(yīng)的文件進行加密,并生成一個新的文件
:param filename: 文件對應(yīng)的路徑
:param new_password: 對文件加密使用的密碼
:param old_password: 如果舊文件進行了加密,需要密碼
:param encrypted_filename: 加密之后的文件名,省卻時使用filename_encrypted;
:return:
"""
# 創(chuàng)建一個Reader實例
pdf_reader = get_reader(filename, old_password)
if pdf_reader is None:
return
# 創(chuàng)建一個寫操作的實例
pdf_writer = PdfFileWriter()
# 從之前Reader中將數(shù)據(jù)寫入到Writer中
pdf_writer.appendPagesFromReader(pdf_reader)
# 重新使用新密碼加密
pdf_writer.encrypt(new_password)
if encrypted_filename is None:
# 使用舊文件名 + encrypted 作為新的文件名
encrypted_filename = "".join(filename.split('.')[:-1]) + '_' + 'encrypted' + '.pdf'
pdf_writer.write(open(encrypted_filename, 'wb'))
def decrypt_pdf(filename, password, decrypted_filename=None):
"""
將加密的文件及逆行解密,并生成一個無需密碼pdf文件
:param filename: 原先加密的pdf文件
:param password: 對應(yīng)的密碼
:param decrypted_filename: 解密之后的文件名
:return:
"""
# 生成一個Reader和Writer
pdf_reader = get_reader(filename, password)
if pdf_reader is None:
return
if not pdf_reader.isEncrypted:
print('文件沒有被加密,無需操作!')
return
pdf_writer = PdfFileWriter()
pdf_writer.appendPagesFromReader(pdf_reader)
if decrypted_filename is None:
decrypted_filename = "".join(filename.split('.')[:-1]) + '_' + 'decrypted' + '.pdf'
# 寫入新文件
pdf_writer.write(open(decrypted_filename, 'wb'))
def split_by_pages(filename, pages, password=None):
"""
將文件按照頁數(shù)進行平均分割
:param filename: 所要分割的文件名
:param pages: 分割之后每個文件對應(yīng)的頁數(shù)
:param password: 如果文件加密,需要進行解密操作
:return:
"""
# 得到Reader
pdf_reader = get_reader(filename, password)
if pdf_reader is None:
return
# 得到總的頁數(shù)
pages_nums = pdf_reader.numPages
if pages <= 1:
print('每份文件必須大于1頁!')
return
# 得到切分之后每個pdf文件的頁數(shù)
pdf_num = pages_nums // pages + 1 if pages_nums % pages else int(pages_nums / pages)
print('pdf文件被分為%d份,每份有%d頁!' % (pdf_num, pages))
# 依次生成pdf文件
for cur_pdf_num in range(1, pdf_num + 1):
# 創(chuàng)建一個新的寫實例
pdf_writer = PdfFileWriter()
# 生成對應(yīng)的文件名稱
split_pdf_name = "".join(filename)[:-1] + '_' + str(cur_pdf_num) + '.pdf'
# 計算出當前開始的位置
start = pages * (cur_pdf_num - 1)
# 計算出結(jié)束的位置,如果是最后一份就直接返回最后的頁數(shù),否則用每份頁數(shù)*已經(jīng)分好的文件數(shù)
end = pages * cur_pdf_num if cur_pdf_num != pdf_num else pages_nums
# print(str(start) + ',' + str(end))
# 依次讀取對應(yīng)的頁數(shù)
for i in range(start, end):
pdf_writer.addPage(pdf_reader.getPage(i))
# 寫入文件
pdf_writer.write(open(split_pdf_name, 'wb'))
def split_by_num(filename, nums, password=None):
"""
將pdf文件分為nums份
:param filename: 文件名
:param nums: 要分成的份數(shù)
:param password: 如果需要解密,輸入密碼
:return:
"""
pdf_reader = get_reader(filename, password)
if not pdf_reader:
return
if nums < 2:
print('份數(shù)不能小于2!')
return
# 得到pdf的總頁數(shù)
pages = pdf_reader.numPages
if pages < nums:
print('份數(shù)不應(yīng)該大于pdf總頁數(shù)!')
return
# 計算每份應(yīng)該有多少頁
each_pdf = pages // nums
print('pdf共有%d頁,分為%d份,每份有%d頁!' % (pages, nums, each_pdf))
for num in range(1, nums + 1):
pdf_writer = PdfFileWriter()
# 生成對應(yīng)的文件名稱
split_pdf_name = "".join(filename)[:-1] + '_' + str(num) + '.pdf'
# 計算出當前開始的位置
start = each_pdf * (num - 1)
# 計算出結(jié)束的位置,如果是最后一份就直接返回最后的頁數(shù),否則用每份頁數(shù)*已經(jīng)分好的文件數(shù)
end = each_pdf * num if num != nums else pages
print(str(start) + ',' + str(end))
for i in range(start, end):
pdf_writer.addPage(pdf_reader.getPage(i))
pdf_writer.write(open(split_pdf_name, 'wb'))
def merger_pdf(filenames, merged_name, passwords=None):
"""
傳進來一個文件列表,將其依次融合起來
:param filenames: 文件列表
:param passwords: 對應(yīng)的密碼列表
:return:
"""
# 計算共有多少文件
filenums = len(filenames)
# 注意需要使用False 參數(shù)
pdf_merger = PdfFileMerger(False)
for i in range(filenums):
# 得到密碼
if passwords is None:
password = None
else:
password = passwords[i]
pdf_reader = get_reader(filenames[i], password)
if not pdf_reader:
return
# append默認添加到最后
pdf_merger.append(pdf_reader)
pdf_merger.write(open(merged_name, 'wb'))
def insert_pdf(pdf1, pdf2, insert_num, merged_name, password1=None, password2=None):
"""
將pdf2全部文件插入到pdf1中第insert_num頁
:param pdf1: pdf1文件名稱
:param pdf2: pdf2文件名稱
:param insert_num: 插入的頁數(shù)
:param merged_name: 融合后的文件名稱
:param password1: pdf1對應(yīng)的密碼
:param password2: pdf2對應(yīng)的密碼
:return:
"""
pdf1_reader = get_reader(pdf1, password1)
pdf2_reader = get_reader(pdf2, password2)
# 如果有一個打不開就返回
if not pdf1_reader or not pdf2_reader:
return
# 得到pdf1的總頁數(shù)
pdf1_pages = pdf1_reader.numPages
if insert_num < 0 or insert_num > pdf1_pages:
print('插入位置異常,想要插入的頁數(shù)為:%d,pdf1文件共有:%d頁!' % (insert_num, pdf1_pages))
return
# 注意需要使用False參數(shù),可能會出現(xiàn)中文亂碼的情況
m_pdf = PdfFileMerger(False)
m_pdf.append(pdf1)
m_pdf.merge(insert_num, pdf2)
m_pdf.write(open(merged_name, 'wb'))
if __name__ == '__main__':
# encrypt_pdf('ex1.pdf', 'leafage')
# decrypt_pdf('ex1123_encrypted.pdf', 'leafage')
# split_by_pages('ex1.pdf', 5)
split_by_num('ex2.pdf', 3)
# merger_pdf(['ex1.pdf', 'ex2.pdf'], 'merger.pdf')
# insert_pdf('ex1.pdf', 'ex2.pdf', 10, 'pdf12.pdf')以上是“Python中如何使用pypdf2合并、分割、加密pdf文件”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計公司行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
分享題目:Python中如何使用pypdf2合并、分割、加密pdf文件-創(chuàng)新互聯(lián)
文章起源:http://www.yijiale78.com/article6/ddcdog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、移動網(wǎng)站建設(shè)、搜索引擎優(yōu)化、標簽優(yōu)化、網(wǎng)站策劃、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容