2021-06-23

Python 操作 PDF

相關(guān)介紹

1)Python 操作 PDF 會用到兩個(gè)庫,分別是:PyPDF2 和 pdfplumber
其中 PyPDF2 可以更好的讀取、寫入、分割、合并PDF文件,而 pdfplumber 可以更好的讀取 PDF 文件中內(nèi)容和提取 PDF 中的表格
由于這兩個(gè)庫都不是 Python 的標(biāo)準(zhǔn)庫,所以在使用之前都需要單獨(dú)安裝
安裝命令如下:

pip install PyPDF
pip install pdfplumber

批量拆分

1)PDF 拆分成幾個(gè)小的 PDF
大致思路:讀取 PDF ,以每個(gè) step 為間隔將 PDF 存成每一個(gè)小的文件塊,
將小的文件塊重新保存為新的 PDF 文件
示例代碼:

import  PyPDF2
from PyPDF2 import PdfFileReader, PdfFileWriter
import os
def split_pdf(filename, filepath, save_dirpath, step):
    """
    拆分PDF為多個(gè)小的PDF文件,
    @param filename:文件名
    @param filepath:文件路徑
    @param save_dirpath:保存小的PDF的文件路徑
    @param step: 每step間隔的頁面生成一個(gè)文件,例如step=5,表示0-4頁、5-9頁...為一個(gè)文件
    @return:
    """
    if not os.path.exists(save_dirpath):
        os.mkdir(save_dirpath)
    pdf_reader = PdfFileReader(filepath)
    # 讀取每一頁的數(shù)據(jù)
    pages = pdf_reader.getNumPages()
    for page in range(0, pages, step):
        pdf_writer = PdfFileWriter()
        # 拆分pdf,每 step 頁的拆分為一個(gè)文件
        for index in range(page, page+step):
            if index < pages:
                pdf_writer.addPage(pdf_reader.getPage(index))
        # 保存拆分后的小文件
        save_path = os.path.join(save_dirpath, filename+str(int(page/step)+1)+'.pdf')
        print(save_path)
        with open(save_path, "wb") as out:
            pdf_writer.write(out)

    print("文件已成功拆分,保存路徑為:"+save_dirpath)
filename = 'Python.pdf'
filepath = "D:\\Python操作PDF\\Python.pdf"
save_dirpath= 'D:\\Python操作PDF\\Python'
step=60
split_pdf(filename, filepath, save_dirpath, step)

結(jié)果:
D:\Python操作PDF\Python\Python.pdf1.pdf
D:\Python操作PDF\Python\Python.pdf2.pdf
D:\Python操作PDF\Python\Python.pdf3.pdf
D:\Python操作PDF\Python\Python.pdf4.pdf
D:\Python操作PDF\Python\Python.pdf5.pdf
D:\Python操作PDF\Python\Python.pdf6.pdf
文件已成功拆分,保存路徑為:D:\Python操作PDF\Python
Process finished with exit code 0


image.png
image.png

批量合并

1)大致思路:
確定要合并的 文件順序
循環(huán)追加到一個(gè)文件塊中
保存成一個(gè)新的文件

def concat_pdf(filename, read_dirpath, save_filepath):
    """
    合并多個(gè)PDF文件
    @param filename:文件名
    @param read_dirpath:要合并的PDF目錄
    @param save_filepath:合并后的PDF文件路徑
    @return:
    """
    pdf_writer = PdfFileWriter()
    # 對文件名進(jìn)行排序
    list_filename = os.listdir(read_dirpath)
    list_filename.sort(key=lambda x: int(x[:-4].replace(filename, "")))
    for filename in list_filename:
        print(filename)
        filepath = os.path.join(read_dirpath, filename)
        # 讀取文件并獲取文件的頁數(shù)
        pdf_reader = PdfFileReader(filepath)
        pages = pdf_reader.getNumPages()
        # 逐頁添加
        for page in range(pages):
            pdf_writer.addPage(pdf_reader.getPage(page))
    # 保存合并后的文件
    with open(save_filepath, "wb") as out:
        pdf_writer.write(out)
    print("文件已成功合并,保存路徑為:"+save_filepath)

提取文字內(nèi)容

1)提取指定頁內(nèi)容
示例代碼:

def extract_text_info(filepath):
    """
    提取PDF中的文字
    @param filepath:文件路徑
    @return:
    """
    with pdfplumber.open(filepath) as pdf:
        # 獲取第2頁數(shù)據(jù)
        page = pdf.pages[1]
        print(page.extract_text())

2)獲取整個(gè)文件

ef extract_text_info(filepath):
    """
    提取PDF中的文字
    @param filepath:文件路徑
    @return:
    """
    with pdfplumber.open(filepath) as pdf:
        # 獲取全部數(shù)據(jù)
        for page in pdf.pages
            print(page.extract_text())

提取表格內(nèi)容

1)提取一個(gè)表格

def extract_table_info(filepath):
    """
    提取PDF中的圖表數(shù)據(jù)
    @param filepath:
    @return:
    """
    with pdfplumber.open(filepath) as pdf:
        # 獲取第18頁數(shù)據(jù)
        page = pdf.pages[17]
        # 如果一頁有一個(gè)表格,設(shè)置表格的第一行為表頭,其余為數(shù)據(jù)
        table_info = page.extract_table()
        df_table = pd.DataFrame(table_info[1:], columns=table_info[0])
        df_table.to_csv('dmeo.csv', index=False, encoding='gbk')

2)提取多個(gè)表格

def extract_table_info(filepath):
    """
    提取PDF中的圖表數(shù)據(jù)
    @param filepath:
    @return:
    """
    # 如果一頁有多個(gè)表格,對應(yīng)的數(shù)據(jù)是一個(gè)三維數(shù)組
    tables_info = page.extract_tables()
    for index in range(len(tables_info)):
        # 設(shè)置表格的第一行為表頭,其余為數(shù)據(jù)
        df_table = pd.DataFrame(tables_info[index][1:], columns=tables_info[index][0])
        print(df_table)
        # df_table.to_csv('dmeo.csv', index=False, encoding='gbk')

提取圖片內(nèi)容

1)安裝 PyMuPDF 模塊

pip install PyMuPDF

大致·思路:打開文檔>遍歷元素>正則匹配>生成圖片>過濾圖片
示例:


"""2. 遍歷PDF中的對象,遇到是圖像才進(jìn)行下一步,不然就continue"""
for index in range(1, xref_len):
    # 1.16.8版本用法 text = doc._getXrefString(index)
    # 最新版本
    text = pdf_info.xref_object(index)

    is_XObject = re.search(check_XObject, text)
    is_Image = re.search(check_Image, text)
    # 如果不是對象也不是圖片,則不操作
    if is_XObject or is_Image:
        img_count += 1
        # 根據(jù)索引生成圖像
        pix = fitz.Pixmap(pdf_info, index)
        pic_filepath = os.path.join(pic_dirpath, 'img_' + str(img_count) + '.png')
        """pix.size 可以反映像素多少,簡單的色素塊該值較低,可以通過設(shè)置一個(gè)閾值過濾。以閾值 10000 為例過濾"""
        # if pix.size < 10000:
        #     continue

        """三、 將圖像存為png格式"""
        if pix.n >= 5:
            # 先轉(zhuǎn)換CMYK
            pix = fitz.Pixmap(fitz.csRGB, pix)
        # 存為PNG
        pix.writePNG(pic_filepath)

轉(zhuǎn)換為圖片

1)安裝 pdf2image模塊
2)安裝組件
windows 用戶需要安裝 poppler for Windows,安裝鏈接是:http://blog.alivate.com.au/poppler-windows/
mac 用戶,需要安裝 poppler for Mac,具體可以參考這個(gè)鏈接:http://macappstore.org/poppler/
示例:

if not os.path.exists(pic_dirpath):
    os.makedirs(pic_dirpath)

images = convert_from_bytes(open(filepath, 'rb').read())
# images = convert_from_path(filepath, dpi=200)
for image in images:
    # 保存圖片
    pic_filepath = os.path.join(pic_dirpath, 'img_'+str(images.index(image))+'.png')
    image.save(pic_filepath, 'PNG')

添加水印

主要代碼:

watermark = PdfFileReader(watermark_filepath)
watermark_page = watermark.getPage(0)

pdf_reader = PdfFileReader(filepath)
pdf_writer = PdfFileWriter()

for page_index in range(pdf_reader.getNumPages()):
    current_page = pdf_reader.getPage(page_index)
    # 封面頁不添加水印
    if page_index == 0:
        new_page = current_page
    else:
        new_page = copy(watermark_page)
        new_page.mergePage(current_page)
    pdf_writer.addPage(new_page)
# 保存水印后的文件
with open(save_filepath, "wb") as out:
    pdf_writer.write(out)

文檔加密與解密

1)加密操作

pdf_reader = PdfFileReader(filepath)
pdf_writer = PdfFileWriter()

for page_index in range(pdf_reader.getNumPages()):
    pdf_writer.addPage(pdf_reader.getPage(page_index))

# 添加密碼
pdf_writer.encrypt(passwd)
with open(save_filepath, "wb") as out:
    pdf_writer.write(out)

2)解密操作

pdf_reader = PdfFileReader(filepath)
# PDF文檔解密
pdf_reader.decrypt('python')

pdf_writer = PdfFileWriter()
for page_index in range(pdf_reader.getNumPages()):
    pdf_writer.addPage(pdf_reader.getPage(page_index))

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

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

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