最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python處理PDF文檔的兩大功能庫(kù)(PyPDF2/pdfplumber)的使用指南

 更新時(shí)間:2026年03月06日 09:17:32   作者:MarkHD  
PyPDF2擅長(zhǎng)PDF文檔操作,而pdfplumber專(zhuān)注于高質(zhì)量文本和表格數(shù)據(jù)提取,本文將對(duì)比Python中兩個(gè)PDF處理庫(kù)PyPDF2和pdfplumber的主要功能與適用場(chǎng)景,希望對(duì)大家有所幫助

一、工欲善其事:PyPDF2 vs pdfplumber,如何選擇?

在處理PDF之前,我們需要理解不同庫(kù)的定位。Python生態(tài)中有多個(gè)PDF處理庫(kù),各有所長(zhǎng)。根據(jù)我們的學(xué)習(xí)目標(biāo),主要聚焦于兩個(gè)庫(kù):

功能/庫(kù)PyPDF2(及其繼任者pypdf)pdfplumber
主要用途PDF操作修改:合并、拆分、旋轉(zhuǎn)、加密、添加水印精確提取結(jié)構(gòu)化數(shù)據(jù),特別是表格和文本
文本提取能力基礎(chǔ)(對(duì)復(fù)雜布局支持有限)高級(jí)(保留布局信息)
表格提取? 不支持? 內(nèi)置強(qiáng)大功能
文本位置/坐標(biāo)? 不支持? 支持
PDF操作? 合并、拆分、加密、水印? 只讀,不支持修改
處理速度一般(基于pdfminer)
典型場(chǎng)景文檔整理、批量處理、添加水印數(shù)據(jù)提取、發(fā)票解析、報(bào)表分析

選擇建議

  • 如果你的任務(wù)是操作PDF本身(合并多個(gè)文件、拆分成單頁(yè)、添加水印、加密解密),PyPDF2是首選。
  • 如果你的任務(wù)是從PDF中提取數(shù)據(jù)(文本內(nèi)容、表格、特定位置的信息),pdfplumber是利器。
  • 在實(shí)際項(xiàng)目中,兩者經(jīng)常配合使用:先用pdfplumber提取數(shù)據(jù)和結(jié)構(gòu),再用PyPDF2進(jìn)行文檔整理和輸出。

開(kāi)始之前,請(qǐng)確保安裝所需庫(kù):

pip install pypdf2 pdfplumber

注意:PyPDF2的后續(xù)版本已更名為pypdf,API有所調(diào)整。本文基于穩(wěn)定版PyPDF2編寫(xiě),代碼同樣適用于pypdf(需注意類(lèi)名變更,如PdfFileReader變?yōu)?code>PdfReader)。

二、PDF文本提取——讓機(jī)器人“讀懂”PDF

2.1 為什么PDF文本提取有難度

PDF本質(zhì)上是描述頁(yè)面外觀的指令集合,而不是像Word或HTML那樣包含結(jié)構(gòu)化文本。這意味著:

  • 文本可能以碎片形式存儲(chǔ)(一個(gè)單詞拆成多個(gè)指令)
  • 缺少段落、標(biāo)題等語(yǔ)義信息
  • 可能存在字體嵌入、編碼轉(zhuǎn)換問(wèn)題

因此,選擇正確的工具至關(guān)重要。

2.2 使用PyPDF2提取基礎(chǔ)文本

PyPDF2提供了基礎(chǔ)的文本提取功能,適合簡(jiǎn)單的、布局規(guī)整的PDF。

import PyPDF2

def extract_text_with_pypdf2(pdf_path):
    """使用PyPDF2提取PDF文本"""
    with open(pdf_path, 'rb') as file:
        # 創(chuàng)建PDF閱讀器對(duì)象
        reader = PyPDF2.PdfReader(file)
        
        # 獲取總頁(yè)數(shù)
        num_pages = len(reader.pages)
        print(f"總頁(yè)數(shù): {num_pages}")
        
        # 提取每一頁(yè)文本
        full_text = ""
        for page_num in range(num_pages):
            page = reader.pages[page_num]
            text = page.extract_text()
            full_text += f"\n--- 第 {page_num + 1} 頁(yè) ---\n{text}"
        
        return full_text

# 使用示例
text = extract_text_with_pypdf2("report.pdf")
print(text[:500])  # 打印前500個(gè)字符

局限性:PyPDF2的文本提取基于PDF內(nèi)部的文本繪制指令,對(duì)于復(fù)雜排版(如多列、表格、頁(yè)眉頁(yè)腳 交錯(cuò)),提取結(jié)果可能出現(xiàn)亂序或丟失。

2.3 使用pdfplumber高質(zhì)量提取文本

pdfplumber基于pdfminer.six構(gòu)建,但提供了更友好的API和更好的布局分析能力。

import pdfplumber

def extract_text_with_pdfplumber(pdf_path):
    """使用pdfplumber提取PDF文本,保留布局"""
    full_text = ""
    with pdfplumber.open(pdf_path) as pdf:
        print(f"總頁(yè)數(shù): {len(pdf.pages)}")
        
        for i, page in enumerate(pdf.pages):
            # 提取文本(自動(dòng)處理布局)
            text = page.extract_text()
            full_text += f"\n--- 第 {i+1} 頁(yè) ---\n{text}"
            
            # 可選:提取單詞及其位置信息
            words = page.extract_words()
            if words:
                print(f"第{i+1}頁(yè)包含{len(words)}個(gè)單詞")
                # 第一個(gè)單詞的坐標(biāo)信息示例
                first_word = words[0]
                print(f"首個(gè)單詞: '{first_word['text']}' 位置: ({first_word['x0']}, {first_word['top']})")
    
    return full_text

# 使用示例
text = extract_text_with_pdfplumber("復(fù)雜報(bào)表.pdf")

優(yōu)勢(shì):pdfplumber能夠更好地理解頁(yè)面布局,提取的文本順序更符合人類(lèi)閱讀習(xí)慣。

2.4 實(shí)戰(zhàn):提取表格數(shù)據(jù)并結(jié)構(gòu)化

pdfplumber的核心優(yōu)勢(shì)在于表格提取。它能夠自動(dòng)識(shí)別表格的邊界和單元格結(jié)構(gòu)。

import pdfplumber
import pandas as pd

def extract_tables_to_dataframe(pdf_path):
    """提取PDF中的表格并轉(zhuǎn)為DataFrame"""
    all_tables = []
    
    with pdfplumber.open(pdf_path) as pdf:
        for page_num, page in enumerate(pdf.pages):
            # 提取當(dāng)前頁(yè)的所有表格
            tables = page.extract_tables()
            
            for table_num, table in enumerate(tables):
                print(f"第{page_num+1}頁(yè),表格{table_num+1},共{len(table)}行")
                
                # 轉(zhuǎn)為DataFrame(假設(shè)第一行為表頭)
                if len(table) > 0:
                    df = pd.DataFrame(table[1:], columns=table[0])
                    all_tables.append({
                        'page': page_num + 1,
                        'table_num': table_num + 1,
                        'dataframe': df
                    })
    
    return all_tables

# 優(yōu)化表格提取的參數(shù)設(shè)置
def extract_tables_with_settings(pdf_path):
    """使用自定義參數(shù)優(yōu)化表格提取"""
    results = []
    
    with pdfplumber.open(pdf_path) as pdf:
        for page in pdf.pages:
            # 自定義表格檢測(cè)策略
            table_settings = {
                "vertical_strategy": "lines",  # 基于線(xiàn)條檢測(cè)列
                "horizontal_strategy": "lines",  # 基于線(xiàn)條檢測(cè)行
                "snap_tolerance": 5,  # 線(xiàn)條對(duì)齊容差
                "edge_min_length": 3,  # 最小線(xiàn)段長(zhǎng)度
            }
            
            # 或者使用"text"策略(當(dāng)表格沒(méi)有明顯邊框時(shí))
            # table_settings = {
            #     "vertical_strategy": "text",
            #     "horizontal_strategy": "text",
            # }
            
            table = page.extract_table(table_settings)
            if table:
                results.append(table)
    
    return results

# 使用示例
tables = extract_tables_to_dataframe("財(cái)務(wù)報(bào)表.pdf")
for item in tables:
    print(item['dataframe'].head())

參數(shù)調(diào)優(yōu)技巧

  • vertical_strategy:可選"lines"(基于線(xiàn)條)、“text”(基于文本對(duì)齊)、“explicit”(顯式指定)
  • snap_tolerance:當(dāng)線(xiàn)條與文本不完全對(duì)齊時(shí)的容差(像素),默認(rèn)10
  • 對(duì)于無(wú)邊框表格,使用"text"策略可能效果更好

2.5 處理掃描件PDF(OCR集成)

pdfplumber本身不支持OCR,但可以與pytesseract結(jié)合處理掃描件:

import pdfplumber
import pytesseract
from PIL import Image

def ocr_scanned_pdf(pdf_path):
    """對(duì)掃描件PDF進(jìn)行OCR識(shí)別"""
    text_results = []
    
    with pdfplumber.open(pdf_path) as pdf:
        for i, page in enumerate(pdf.pages):
            # 將PDF頁(yè)面轉(zhuǎn)為圖像
            im = page.to_image(resolution=300)
            
            # 使用pytesseract進(jìn)行OCR
            text = pytesseract.image_to_string(im.original, lang='chi_sim+eng')  # 中英文
            text_results.append({
                'page': i + 1,
                'text': text
            })
    
    return text_results

三、合并與拆分PDF——文件管理的自動(dòng)化

3.1 批量合并PDF文件

合并PDF是辦公中最常見(jiàn)的需求之一。比如將多個(gè)部門(mén)的周報(bào)合并為一份總報(bào)告。

import os
from PyPDF2 import PdfMerger

def merge_pdfs(input_folder, output_filename, pattern=None):
    """
    合并指定文件夾中的所有PDF文件
    
    Args:
        input_folder: 包含PDF文件的文件夾路徑
        output_filename: 輸出文件名
        pattern: 文件名過(guò)濾模式,如"report_"開(kāi)頭的文件
    """
    merger = PdfMerger()
    merged_count = 0
    
    # 獲取文件夾下所有PDF文件
    for filename in os.listdir(input_folder):
        if filename.lower().endswith('.pdf'):
            if pattern and pattern not in filename:
                continue
                
        file_path = os.path.join(input_folder, filename)
        print(f"正在添加: {filename}")
        
        try:
            merger.append(file_path)
            merged_count += 1
        except Exception as e:
            print(f"添加文件 {filename} 時(shí)出錯(cuò): {e}")
    
    # 寫(xiě)入合并后的文件
    if merged_count > 0:
        merger.write(output_filename)
        merger.close()
        print(f"合并完成!共合并 {merged_count} 個(gè)文件,保存為: {output_filename}")
    else:
        print("未找到可合并的PDF文件")

# 按指定順序合并(指定文件列表)
def merge_pdfs_by_list(file_list, output_filename):
    """按指定文件列表順序合并PDF"""
    merger = PdfMerger()
    
    for file_path in file_list:
        if os.path.exists(file_path):
            print(f"添加: {os.path.basename(file_path)}")
            merger.append(file_path)
        else:
            print(f"文件不存在: {file_path}")
    
    merger.write(output_filename)
    merger.close()
    print(f"合并完成!保存為: {output_filename}")

# 使用示例
merge_pdfs('./月度報(bào)告', '2025年一季度合并報(bào)告.pdf')
merge_pdfs_by_list(['封面.pdf', '目錄.pdf', '正文.pdf', '附錄.pdf'], '完整報(bào)告.pdf')

3.2 拆分PDF文件

有時(shí)我們需要從大型PDF中提取特定頁(yè)面,比如只保留合同的第一頁(yè)(簽字頁(yè))。

from PyPDF2 import PdfReader, PdfWriter

def split_pdf_by_pages(input_pdf, output_pattern, pages_to_extract):
    """
    提取指定頁(yè)面并保存為新文件
    
    Args:
        input_pdf: 輸入PDF路徑
        output_pattern: 輸出文件名模式,如"提取_第{page}頁(yè).pdf"
        pages_to_extract: 要提取的頁(yè)碼列表(從1開(kāi)始)
    """
    reader = PdfReader(input_pdf)
    total_pages = len(reader.pages)
    
    for page_num in pages_to_extract:
        if page_num < 1 or page_num > total_pages:
            print(f"頁(yè)碼 {page_num} 超出范圍(1-{total_pages})")
            continue
        
        writer = PdfWriter()
        # 注意:頁(yè)碼從0開(kāi)始索引
        writer.add_page(reader.pages[page_num - 1])
        
        output_file = output_pattern.format(page=page_num)
        with open(output_file, 'wb') as output_pdf:
            writer.write(output_pdf)
        
        print(f"已提取第 {page_num} 頁(yè),保存為: {output_file}")

def split_pdf_every_n_pages(input_pdf, n):
    """每n頁(yè)拆分成一個(gè)文件(如每10頁(yè)一個(gè)文件)"""
    reader = PdfReader(input_pdf)
    total_pages = len(reader.pages)
    
    for start in range(0, total_pages, n):
        end = min(start + n, total_pages)
        writer = PdfWriter()
        
        for page_num in range(start, end):
            writer.add_page(reader.pages[page_num])
        
        output_file = f"拆分_{start+1}-{end}.pdf"
        with open(output_file, 'wb') as output_pdf:
            writer.write(output_pdf)
        
        print(f"已生成: {output_file} (第{start+1}-{end}頁(yè))")

# 使用示例
split_pdf_by_pages('年度報(bào)告.pdf', '第{page}頁(yè)_摘要.pdf', [1, 5, 10])
split_pdf_every_n_pages('超大文檔.pdf', 20)

3.3 實(shí)戰(zhàn):智能拆分工具

結(jié)合pdfplumber的文本查找功能,我們可以實(shí)現(xiàn)更智能的拆分——根據(jù)內(nèi)容自動(dòng)切分。

import pdfplumber
from PyPDF2 import PdfReader, PdfWriter

def split_pdf_by_keyword(input_pdf, keyword, output_prefix):
    """
    根據(jù)關(guān)鍵字出現(xiàn)的頁(yè)碼拆分PDF
    找到關(guān)鍵字出現(xiàn)的所有頁(yè)碼,每個(gè)關(guān)鍵頁(yè)及其后續(xù)頁(yè)直到下一個(gè)關(guān)鍵頁(yè)之前,作為一個(gè)獨(dú)立文件
    """
    # 第一步:找出所有包含關(guān)鍵字的頁(yè)碼
    keyword_pages = []
    
    with pdfplumber.open(input_pdf) as pdf:
        for i, page in enumerate(pdf.pages):
            text = page.extract_text()
            if keyword in text:
                keyword_pages.append(i)  # 保存0-based索引
                print(f"第{i+1}頁(yè)包含關(guān)鍵字: {keyword}")
    
    if not keyword_pages:
        print(f"未找到包含關(guān)鍵字'{keyword}'的頁(yè)面")
        return
    
    # 第二步:根據(jù)關(guān)鍵頁(yè)拆分
    reader = PdfReader(input_pdf)
    total_pages = len(reader.pages)
    
    for idx, start_page in enumerate(keyword_pages):
        writer = PdfWriter()
        
        # 確定結(jié)束頁(yè):下一個(gè)關(guān)鍵頁(yè)的前一頁(yè),或最后一頁(yè)
        end_page = keyword_pages[idx + 1] - 1 if idx + 1 < len(keyword_pages) else total_pages - 1
        
        # 添加從start_page到end_page的所有頁(yè)
        for page_num in range(start_page, end_page + 1):
            writer.add_page(reader.pages[page_num])
        
        # 保存文件
        output_file = f"{output_prefix}_第{idx+1}段_頁(yè){start_page+1}-{end_page+1}.pdf"
        with open(output_file, 'wb') as output_pdf:
            writer.write(output_pdf)
        
        print(f"已生成: {output_file}")

# 使用示例:按"第一章"、"第二章"拆分書(shū)籍
split_pdf_by_keyword('Python教程.pdf', '第', '章節(jié)')

四、添加水印與高級(jí)操作——讓PDF更專(zhuān)業(yè)

4.1 添加文字水?。ㄊ褂胷eportlab+PyPDF2)

PyPDF2本身不支持創(chuàng)建新內(nèi)容,因此添加水印的通用方法是:先用reportlab創(chuàng)建水印PDF,再與原文件合并。

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from PyPDF2 import PdfReader, PdfWriter

def create_watermark_pdf(watermark_text, output_path, page_size=letter):
    """
    創(chuàng)建水印PDF文件
    """
    c = canvas.Canvas(output_path, pagesize=page_size)
    width, height = page_size
    
    # 設(shè)置透明度和旋轉(zhuǎn)
    c.setFillAlpha(0.3)  # 透明度30%
    c.setFont("Helvetica", 60)
    c.setFillColorRGB(0.5, 0.5, 0.5)  # 灰色
    
    # 旋轉(zhuǎn)45度,居中顯示
    c.saveState()
    c.translate(width/2, height/2)
    c.rotate(45)
    c.drawCentredString(0, 0, watermark_text)
    c.restore()
    
    c.save()
    print(f"水印文件已創(chuàng)建: {output_path}")

def add_watermark_to_pdf(input_pdf, watermark_pdf, output_pdf):
    """
    為PDF文件添加水印
    """
    # 讀取水印PDF
    watermark_reader = PdfReader(watermark_pdf)
    watermark_page = watermark_reader.pages[0]
    
    # 讀取原PDF
    reader = PdfReader(input_pdf)
    writer = PdfWriter()
    
    # 為每一頁(yè)添加水印
    for page_num in range(len(reader.pages)):
        page = reader.pages[page_num]
        page.merge_page(watermark_page)  # 合并水印
        writer.add_page(page)
    
    # 保存結(jié)果
    with open(output_pdf, 'wb') as output_file:
        writer.write(output_file)
    
    print(f"水印添加完成!保存為: {output_pdf}")

# 支持中文的水印
def create_chinese_watermark(watermark_text, output_path, font_path='simsun.ttc'):
    """
    創(chuàng)建支持中文的水印PDF
    """
    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    
    # 注冊(cè)中文字體
    pdfmetrics.registerFont(TTFont('SimSun', font_path))
    
    c = canvas.Canvas(output_path, pagesize=letter)
    width, height = letter
    
    c.setFillAlpha(0.2)
    c.setFont('SimSun', 50)
    c.setFillColorRGB(0.7, 0.7, 0.7)
    
    # 居中旋轉(zhuǎn)
    c.saveState()
    c.translate(width/2, height/2)
    c.rotate(45)
    c.drawCentredString(0, 0, watermark_text)
    c.restore()
    
    c.save()

# 使用示例
create_watermark_pdf("CONFIDENTIAL", "watermark.pdf")
add_watermark_to_pdf("report.pdf", "watermark.pdf", "report_confidential.pdf")

create_chinese_watermark("絕密", "chinese_watermark.pdf")
add_watermark_to_pdf("合同.pdf", "chinese_watermark.pdf", "合同_帶水印.pdf")

4.2 旋轉(zhuǎn)頁(yè)面

from PyPDF2 import PdfReader, PdfWriter

def rotate_pdf_pages(input_pdf, output_pdf, rotation_degree=90, pages=None):
    """
    旋轉(zhuǎn)PDF頁(yè)面
    pages: 要旋轉(zhuǎn)的頁(yè)碼列表,None表示所有頁(yè)
    """
    reader = PdfReader(input_pdf)
    writer = PdfWriter()
    
    for page_num in range(len(reader.pages)):
        page = reader.pages[page_num]
        
        if pages is None or (page_num + 1) in pages:
            page.rotate(rotation_degree)
        
        writer.add_page(page)
    
    with open(output_pdf, 'wb') as output_file:
        writer.write(output_file)
    
    print(f"旋轉(zhuǎn)完成!保存為: {output_pdf}")

# 使用示例:將第2頁(yè)旋轉(zhuǎn)90度
rotate_pdf_pages("掃描件.pdf", "掃描件_校正.pdf", rotation_degree=90, pages=[2])

4.3 加密與解密PDF

from PyPDF2 import PdfReader, PdfWriter

def encrypt_pdf(input_pdf, output_pdf, user_password, owner_password=None):
    """添加密碼保護(hù)"""
    reader = PdfReader(input_pdf)
    writer = PdfWriter()
    
    # 復(fù)制所有頁(yè)面
    for page in reader.pages:
        writer.add_page(page)
    
    # 加密
    writer.encrypt(user_password, owner_password)
    
    with open(output_pdf, 'wb') as output_file:
        writer.write(output_file)
    
    print(f"加密完成!保存為: {output_pdf}")

def decrypt_pdf(input_pdf, output_pdf, password):
    """解密PDF(需要知道密碼)"""
    reader = PdfReader(input_pdf)
    
    if reader.is_encrypted:
        reader.decrypt(password)
    
    writer = PdfWriter()
    for page in reader.pages:
        writer.add_page(page)
    
    with open(output_pdf, 'wb') as output_file:
        writer.write(output_file)
    
    print(f"解密完成!保存為: {output_pdf}")

# 使用示例
encrypt_pdf("財(cái)務(wù)報(bào)告.pdf", "財(cái)務(wù)報(bào)告_加密.pdf", "123456")
decrypt_pdf("財(cái)務(wù)報(bào)告_加密.pdf", "財(cái)務(wù)報(bào)告_解密.pdf", "123456")

五、實(shí)戰(zhàn)案例:構(gòu)建自動(dòng)化PDF處理流水線(xiàn)

讓我們綜合三天所學(xué),構(gòu)建一個(gè)完整的PDF處理流程:從多個(gè)PDF中提取表格數(shù)據(jù),合并分析結(jié)果,并添加水印和密碼保護(hù)。

import os
import pandas as pd
import pdfplumber
from PyPDF2 import PdfMerger, PdfReader, PdfWriter
from reportlab.pdfgen import canvas

class PDFAutomationPipeline:
    """PDF自動(dòng)化處理流水線(xiàn)"""
    
    def __init__(self, input_folder, output_folder):
        self.input_folder = input_folder
        self.output_folder = output_folder
        os.makedirs(output_folder, exist_ok=True)
    
    def extract_all_tables(self):
        """從所有PDF中提取表格"""
        all_data = []
        
        for filename in os.listdir(self.input_folder):
            if filename.endswith('.pdf'):
                file_path = os.path.join(self.input_folder, filename)
                print(f"處理文件: {filename}")
                
                with pdfplumber.open(file_path) as pdf:
                    for page_num, page in enumerate(pdf.pages):
                        tables = page.extract_tables()
                        for table_num, table in enumerate(tables):
                            # 假設(shè)第一行是表頭
                            if len(table) > 0:
                                df = pd.DataFrame(table[1:], columns=table[0])
                                all_data.append({
                                    'source': filename,
                                    'page': page_num + 1,
                                    'table': table_num + 1,
                                    'data': df
                                })
        
        return all_data
    
    def create_summary_pdf(self, all_tables, summary_pdf):
        """創(chuàng)建匯總PDF(使用reportlab繪制簡(jiǎn)單匯總)"""
        from reportlab.lib.pagesizes import A4
        from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table as RLTable
        from reportlab.lib.styles import getSampleStyleSheet
        
        doc = SimpleDocTemplate(summary_pdf, pagesize=A4)
        styles = getSampleStyleSheet()
        story = []
        
        # 添加標(biāo)題
        story.append(Paragraph("數(shù)據(jù)匯總報(bào)告", styles['Title']))
        story.append(Spacer(1, 12))
        
        # 匯總每個(gè)表格的基本信息
        for idx, item in enumerate(all_tables[:5]):  # 只顯示前5個(gè)表格
            story.append(Paragraph(f"表格 {idx+1}: 來(lái)源 {item['source']} 第{item['page']}頁(yè)", styles['Heading2']))
            
            # 將DataFrame轉(zhuǎn)為列表
            data = item['data'].values.tolist()
            if data:
                # 添加表頭
                table_data = [item['data'].columns.tolist()] + data[:5]  # 只顯示前5行
                t = RLTable(table_data)
                story.append(t)
                story.append(Spacer(1, 12))
        
        doc.build(story)
        print(f"匯總PDF已創(chuàng)建: {summary_pdf}")
    
    def run_pipeline(self):
        """執(zhí)行完整流程"""
        print("=== 步驟1: 提取所有表格 ===")
        tables = self.extract_all_tables()
        print(f"共提取 {len(tables)} 個(gè)表格")
        
        print("\n=== 步驟2: 生成匯總PDF ===")
        summary_path = os.path.join(self.output_folder, "匯總報(bào)告.pdf")
        self.create_summary_pdf(tables, summary_path)
        
        print("\n=== 步驟3: 添加水印 ===")
        # 創(chuàng)建水印
        watermark_path = os.path.join(self.output_folder, "watermark.pdf")
        create_watermark_pdf("內(nèi)部資料", watermark_path)
        
        # 添加水印
        watermarked_path = os.path.join(self.output_folder, "匯總報(bào)告_帶水印.pdf")
        add_watermark_to_pdf(summary_path, watermark_path, watermarked_path)
        
        print("\n=== 步驟4: 加密保護(hù) ===")
        final_path = os.path.join(self.output_folder, "最終報(bào)告_加密.pdf")
        encrypt_pdf(watermarked_path, final_path, "secure123")
        
        print(f"\n? 所有處理完成!最終文件: {final_path}")

# 使用流水線(xiàn)
pipeline = PDFAutomationPipeline("./輸入文件夾", "./輸出文件夾")
pipeline.run_pipeline()

六、性能對(duì)比與最佳實(shí)踐

6.1 性能對(duì)比

根據(jù)官方性能測(cè)試,不同庫(kù)在處理大文件時(shí)差異顯著:

  • PyMuPDF:處理7031頁(yè)P(yáng)DF僅需3.05秒(合并/復(fù)制操作)
  • PyPDF2:處理同樣任務(wù)需要494秒,是PyMuPDF的160倍以上
  • 文本提取:PyMuPDF比PyPDF2快約12倍

因此,如果追求極致性能,尤其是處理大文件,可以考慮PyMuPDF。但本文聚焦的PyPDF2和pdfplumber在API友好度和特定功能(如表格提取)上仍有不可替代的優(yōu)勢(shì)。

6.2 避坑指南

版本兼容性:PyPDF2 3.x版本已棄用PdfFileReader等舊類(lèi)名,改用PdfReader/PdfWriter。本文代碼兼容新舊版本。

內(nèi)存管理:處理大文件時(shí),及時(shí)釋放對(duì)象:

reader = PdfReader(open('large.pdf', 'rb'))
# 處理完成后
del reader

異常處理:PDF文件可能損壞或加密,添加異常捕獲:

try:
    reader = PdfReader(file)
except PyPDF2.errors.PdfReadError as e:
    print(f"PDF讀取錯(cuò)誤: {e}")

中文支持

  • 提取中文:確保pdfplumber能正確編碼
  • 生成中文水?。盒枳?cè)中文字體文件(.ttc/.ttf)

表格提取調(diào)優(yōu):如果默認(rèn)參數(shù)提取效果不佳,嘗試調(diào)整snap_tolerance和策略。

以上就是Python處理PDF文檔的兩大功能庫(kù)(PyPDF2/pdfplumber)的使用指南的詳細(xì)內(nèi)容,更多關(guān)于Python處理PDF的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Mac中Python 3環(huán)境下安裝scrapy的方法教程

    Mac中Python 3環(huán)境下安裝scrapy的方法教程

    作為一名python爬蟲(chóng)愛(ài)好者,怎能不折騰下Scrapy?折騰了許久之后終于安裝到了mac中,所以下面這篇文章主要給大家介紹了關(guān)于Mac系統(tǒng)中Python 3環(huán)境下安裝scrapy的相關(guān)資料,文中將實(shí)現(xiàn)的步驟一步步介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-10-10
  • Python集合set的交集和并集操作方法

    Python集合set的交集和并集操作方法

    這篇文章主要介紹了Python集合set的交集和并集操作方法小,python的set,是一個(gè)無(wú)序不重復(fù)元素集,?基本功能包括關(guān)系測(cè)試和消除重復(fù)元素本文講述了python中set集合的比較方法包括交集,并集,差集,下文更多詳細(xì)資料,需要的小伙伴可以參考一下
    2022-03-03
  • 3個(gè)適合新手練習(xí)的python小游戲

    3個(gè)適合新手練習(xí)的python小游戲

    這篇文章主要分析的是3個(gè)適合新手練習(xí)的python小游戲,初學(xué)者嘛就應(yīng)該多練手,下文分享的python小游戲歡迎大家來(lái)玩,需要的小伙伴也可以參考一下
    2022-01-01
  • Python進(jìn)階之協(xié)程詳解

    Python進(jìn)階之協(xié)程詳解

    這篇文章主要為大家介紹了Python進(jìn)階之協(xié)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • keras自定義損失函數(shù)并且模型加載的寫(xiě)法介紹

    keras自定義損失函數(shù)并且模型加載的寫(xiě)法介紹

    這篇文章主要介紹了keras自定義損失函數(shù)并且模型加載的寫(xiě)法介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • 國(guó)產(chǎn)麒麟系統(tǒng)kylin部署python項(xiàng)目詳細(xì)步驟

    國(guó)產(chǎn)麒麟系統(tǒng)kylin部署python項(xiàng)目詳細(xì)步驟

    這篇文章主要給大家介紹了關(guān)于國(guó)產(chǎn)麒麟系統(tǒng)kylin部署python項(xiàng)目的相關(guān)資料,文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 一文教你Python如何快速精準(zhǔn)抓取網(wǎng)頁(yè)數(shù)據(jù)

    一文教你Python如何快速精準(zhǔn)抓取網(wǎng)頁(yè)數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)快速精準(zhǔn)抓取網(wǎng)頁(yè)數(shù)據(jù),文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下
    2025-04-04
  • Python使用scipy保存圖片的一些注意點(diǎn)

    Python使用scipy保存圖片的一些注意點(diǎn)

    這篇文章主要介紹了Python使用scipy保存圖片的一些注意點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 實(shí)例詳解Python裝飾器與閉包

    實(shí)例詳解Python裝飾器與閉包

    閉包是Python裝飾器的基礎(chǔ)。要理解閉包,先要了解Python中的變量作用域規(guī)則。本文主要給大家介紹Python裝飾器與閉包的相關(guān)知識(shí),需要的朋友可以參考下
    2019-07-07
  • JWT?登錄鑒權(quán)全流程完整步驟

    JWT?登錄鑒權(quán)全流程完整步驟

    JWT是一種用于在各方之間安全傳輸信息的開(kāi)放標(biāo)準(zhǔn),JWT的優(yōu)勢(shì)在于無(wú)狀態(tài)、分布式支持和簡(jiǎn)單性,本文給大家介紹JWT登錄鑒權(quán)全流程,感興趣的朋友跟隨小編一起看看吧
    2026-01-01

最新評(píng)論

平湖市| 会东县| 色达县| 米易县| 罗定市| 定州市| 海口市| 长春市| 普定县| 临漳县| 双牌县| 静宁县| 蒙阴县| 金堂县| 泽库县| 兴安盟| 金华市| 德州市| 蒙阴县| 花垣县| 万盛区| 葫芦岛市| 邵东县| 三穗县| 新密市| 云南省| 元谋县| 陆川县| 丰宁| 黄骅市| 桐乡市| 尚志市| 财经| 延寿县| 垣曲县| 搜索| 锡林浩特市| 昆明市| 宜城市| 柳林县| 陇西县|