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

使用Python實現(xiàn)PDF文檔自動化的操作大全(一鍵合并、分割、水印、提取與加密解密)

 更新時間:2025年11月14日 10:09:34   作者:愛分享的飄哥  
在職場中,PDF文件因其格式穩(wěn)定、跨平臺兼容性好而廣泛應用,但你有沒有被PDF的這些痛點折磨過:文件零散、編輯受限、合并/分割麻煩和缺乏保護等,這些重復、低效的PDF文件管理任務,嚴重拖慢了你的辦公自動化進程,所以本文介紹了如何使用Python實現(xiàn)PDF文檔自動化

PDF文件難管理,編輯受限,手動操作低效!

在職場中,PDF文件因其格式穩(wěn)定、跨平臺兼容性好而廣泛應用。但你有沒有被PDF的這些“痛點”折磨過?

文件零散: 多個相關的PDF文件(如項目周報、合同附件),散落在不同地方,難以整合為一個完整文檔。
編輯受限: 想從PDF中提取文字,卻發(fā)現(xiàn)無法復制;想修改某個數(shù)字,卻無從下手。
合并/分割麻煩: 需要把幾份PDF合并成一份,或者把一份長PDF拆分成多個小文件,手動操作效率低下。
缺乏保護: 重要PDF文件直接傳輸,沒有密碼保護,傳輸安全有隱患。

這些重復、低效的PDF文件管理任務,嚴重拖慢了你的辦公自動化進程

今天,我將帶你進入Python處理PDF的奇妙世界!我們將手把手教你如何利用強大的Python庫,輕松

實現(xiàn):

PDF合并與分割: 批量操作,輕松整理文檔。
PDF文本提?。?瞬間獲取PDF中的文字信息。
PDF水印與頁碼: 批量添加,提升文檔專業(yè)度。
PDF加密解密: 為你的重要文檔加上“安全鎖”。

最終,你將擁有一個強大的PDF全能管家。

1.Python PDF處理庫選擇:PyPDF2與PyMuPDF對比

要實現(xiàn)Python處理PDF,有兩個非常流行的庫可供選擇:PyPDF2和PyMuPDF。了解它們的特點,能幫你選擇最適合你需求的Python PDF庫。

1.1 PyPDF2:輕量易用,處理PDF文本和基本操作

PyPDF2: 更輕量級,主要用于PDF的結構化操作(如合并、分割、提取文本/元數(shù)據(jù))。

1.2 PyMuPDF:功能強大,渲染與高級編輯

PyMuPDF (fitz): 功能更強大,除了結構化操作,還具備高性能的PDF渲染(轉(zhuǎn)換為圖片)、高級文本和圖片提取、以及更精細的頁面編輯能力。

pip install PyPDF2
pip install PyMuPDF

1.3 環(huán)境準備與選擇建議

表格:PyPDF2 與 PyMuPDF (fitz) 功能對比]

特性PyPDF2PyMuPDF (fitz)
主要功能合并、分割、旋轉(zhuǎn)、加密、基礎文本/頁面提取渲染、文本/圖片/矢量圖形提取、高級插入、格式轉(zhuǎn)換
合并PDF? 支持? 支持
分割PDF? 支持? 支持
提取文本? 支持(純文本)? 支持(含坐標、格式)
提取圖片? 不支持? 支持
PDF轉(zhuǎn)圖片? 不支持? 支持 (高性能渲染)
添加水印? 支持(簡單文本/圖片)? 支持(高級:文本/圖片,字體、透明度可控)
添加頁碼? 不支持? 支持
加密解密? 支持(簡單密碼)? 支持(多種加密算法)
內(nèi)容替換? 不支持? 支持
復雜編輯? 不支持? 支持
安裝/學習簡單稍復雜/陡峭
適用場景簡單的PDF合并、分割、加密、提取PDF預覽、高級文本/圖片提取、文檔渲染、PDF生成

選擇建議:

如果你只是想簡單合并、分割PDF,提取純文本:PyPDF2已足夠,因為它更簡單,易于快速上手。

如果你需要進行PDF渲染(如將Excel內(nèi)容“畫”到PDF)、高級文本/圖片提取、添加定制水印、或者更
精細的PDF內(nèi)容操作:強烈推薦PyMuPDF。

本文接下來的例子將主要基于PyMuPDF進行演示,因為它功能更全面,能實現(xiàn)更多高級自動化。

2.Python批量合并與分割PDF文件,輕松整理文檔!

PDF文檔的合并與分割,是日常PDF自動化中最高頻的需求。Python能幫你一鍵完成這些操作,讓你的文檔管理自動化效率翻倍!

作用: PyMuPDF將PDF視為一系列頁面,可以方便地添加頁面(合并)或提取頁面(分割)。

2.1 批量合并PDF文件:一鍵拼接,文檔歸一

場景: 你有合同-附件1.pdf、合同-附件2.pdf和合同-正文.pdf,需要將它們按順序合并成一份完整的完整合同.pdf。

方案: 編寫一個Python腳本,指定多個源PDF文件,PyMuPDF將它們快速拼接成一個大的PDF文檔,實現(xiàn)PDF合并的自動化。

代碼:

import fitz # PyMuPDF庫
import os

def merge_pdfs(pdf_list, output_pdf_path):
    """
    批量合并多個PDF文件為一個PDF文件。
    這是Python處理PDF和PDF合并分割的核心功能。
    :param pdf_list: 要合并的PDF文件路徑列表
    :param output_pdf_path: 合并后PDF文件的輸出路徑
    """
    if not pdf_list:
        print("? 沒有指定任何PDF文件進行合并。")
        return False
    
    os.makedirs(os.path.dirname(output_pdf_path), exist_ok=True)

    print(f"?? 正在合并 {len(pdf_list)} 個PDF文件到 '{os.path.basename(output_pdf_path)}'...")
    
    # 創(chuàng)建一個新的PDF文檔
    new_pdf = fitz.open() 
    
    try:
        for pdf_path in pdf_list:
            if not os.path.exists(pdf_path):
                print(f"?? 文件不存在,跳過:{os.path.basename(pdf_path)}")
                continue
            
            # 打開每個PDF文件,并將其所有頁面插入到新PDF中
            with fitz.open(pdf_path) as doc:
                new_pdf.insert_pdf(doc) # 插入PDF的所有頁面
                print(f"   ? 已合并:{os.path.basename(pdf_path)}")
        
        new_pdf.save(output_pdf_path) # 保存合并后的PDF
        print(f"? PDF合并成功!結果保存到:'{output_pdf_path}'")
        return True
    except Exception as e:
        print(f"? PDF合并失?。簕e}")
        return False
    finally:
        new_pdf.close() # 確保關閉PDF對象

if __name__ == "__main__":
    # 準備測試PDF文件
    pdf1_path = os.path.expanduser("~/Desktop/report_part1.pdf")
    pdf2_path = os.path.expanduser("~/Desktop/report_part2.pdf")
    output_merged_pdf = os.path.expanduser("~/Desktop/merged_annual_report.pdf")

    # 簡單創(chuàng)建模擬PDF文件 (實際請用你的真實PDF)
    if not os.path.exists(pdf1_path):
        doc1 = fitz.open(); doc1.new_page().insert_text(fitz.Point(50,50), "這是第一部分"); doc1.save(pdf1_path); doc1.close()
    if not os.path.exists(pdf2_path):
        doc2 = fitz.open(); doc2.new_page().insert_text(fitz.Point(50,50), "這是第二部分"); doc2.save(pdf2_path); doc2.close()
    
    pdfs_to_merge = [pdf1_path, pdf2_path]
    merge_pdfs(pdfs_to_merge, output_merged_pdf)

步驟:

安裝PyMuPDF: pip install PyMuPDF。

準備PDF文件: 在桌面創(chuàng)建report_part1.pdf和report_part2.pdf等測試PDF文件。

修改代碼路徑: 修改 pdfs_to_merge 列表中的路徑和 output_merged_pdf。

運行: 運行 python merge_pdfs.py。

效果展示:

2.2 單個PDF文件按頁分割:長篇文檔秒變小冊子!

場景: 你收到一份50頁的PDF報告,但你只需要其中的第5頁到第10頁,或者想把每一頁都拆分成單獨的PDF文件。手動操作耗時且容易出錯。

方案: PyMuPDF能讓你精確地將一個多頁PDF文件按頁碼范圍分割成多個獨立的PDF文件,或者將每一頁都拆分成單獨的文件。

代碼:

import fitz # PyMuPDF
import os

def split_pdf_by_pages(input_pdf_path, output_folder, page_ranges=None):
    """
    將單個PDF文件按頁碼范圍分割為多個PDF文件。
    這是Python處理PDF和PDF合并分割的高級功能。
    :param input_pdf_path: 源PDF文件路徑
    :param output_folder: 分割后PDF文件的輸出文件夾
    :param page_ranges: 要分割的頁碼范圍列表,例如 [[0, 2], [5, 5]] 表示分割第1-3頁和第6頁
                        頁碼從0開始計數(shù)。如果為None,則每頁生成一個PDF。
    """
    if not os.path.exists(input_pdf_path):
        print(f"? PDF文件不存在:{input_pdf_path}")
        return False
    
    os.makedirs(output_folder, exist_ok=True)

    print(f"?? 正在分割PDF文件 '{os.path.basename(input_pdf_path)}'...")
    
    try:
        with fitz.open(input_pdf_path) as doc:
            if page_ranges is None: # 如果沒有指定范圍,則每頁分割一個PDF
                page_ranges = [[i, i] for i in range(doc.page_count)]

            for i, (start_page, end_page) in enumerate(page_ranges):
                if start_page < 0 or end_page >= doc.page_count or start_page > end_page:
                    print(f"?? 頁碼范圍無效,跳過:[{start_page}, {end_page}]")
                    continue
                
                # 創(chuàng)建新PDF來存儲分割的頁面
                new_pdf = fitz.open()
                new_pdf.insert_pdf(doc, from_page=start_page, to_page=end_page)
                
                output_filename = f"{os.path.splitext(os.path.basename(input_pdf_path))[0]}_part_{i+1}_pages_{start_page+1}-{end_page+1}.pdf"
                output_full_path = os.path.join(output_folder, output_filename)
                
                new_pdf.save(output_full_path)
                new_pdf.close()
                print(f"   ? 已分割:'{output_filename}' (頁碼: {start_page+1}-{end_page+1})")
        
        print(f"? PDF分割完成!結果保存到:'{output_folder}'")
        return True
    except Exception as e:
        print(f"? PDF分割失?。簕e}")
        return False

if __name__ == "__main__":
    # 準備測試PDF文件 (多頁)
    long_report_path = os.path.expanduser("~/Desktop/long_report.pdf")
    # 簡單創(chuàng)建模擬PDF文件 (例如創(chuàng)建5頁的PDF)
    if not os.path.exists(long_report_path):
        doc = fitz.open()
        for i in range(5):
            page = doc.new_page(width=595, height=842) # A4
            page.insert_text(fitz.Point(50,50), f"這是第 {i+1} 頁")
        doc.save(long_report_path); doc.close()
    
    output_split_folder = os.path.expanduser("~/Desktop/分割后PDF")
    
    # 示例1:將每一頁分割為單獨的文件
    print("\n--- 示例1:按頁分割所有PDF ---")
    split_pdf_by_pages(long_report_path, os.path.join(output_split_folder, "ByPage"))

    # 示例2:按指定范圍分割 (例如,只取第2頁到第4頁,對應索引1到3)
    print("\n--- 示例2:按頁碼范圍分割PDF (取第2到4頁) ---")
    split_pdf_by_pages(long_report_path, os.path.join(output_split_folder, "Range"), page_ranges=[[1, 3]]) # 頁碼索引是0-based,范圍是[start, end)

操作步驟:

安裝PyMuPDF: pip install PyMuPDF。

準備PDF文件: 在桌面創(chuàng)建long_report.pdf(包含多頁內(nèi)容,如5頁)。

修改代碼路徑和頁碼范圍: 修改 long_report_path 和 output_split_folder。

運行: 運行 python split_pdfs.py。

效果展示:

3. Python為PDF添加水印、頁碼與實現(xiàn)加密解密!

PDF的保護和專業(yè)化是文檔管理的重要環(huán)節(jié)。

PyMuPDF能讓你為PDF添加水印、自動生成頁碼,甚至進行PDF加密與解密,全方位提升你的PDF自動化能力!

3.1 PDF水?。禾砑游淖帧D片Logo,保護文檔版權!

場景: 你需要為一份重要報告或內(nèi)部資料添加“絕密”、“版權所有”等文字水印,或在每頁添加你的公司名稱。
方案: PyMuPDF可以精確地在PDF的每一頁上添加文字水印或圖片水印,并控制其位置、透明度等。

代碼:

import fitz # PyMuPDF
from PIL import Image, ImageDraw, ImageFont # 用于文字渲染到圖片 (如果需要),或處理Logo圖片
import os
import io # 用于內(nèi)存中的文件操作

# 定義一個中文字體路徑,確保你的系統(tǒng)中有,否則中文可能顯示為方塊
CHINESE_FONT_PATH = "C:/Windows/Fonts/simhei.ttf" # Windows黑體示例

def add_pdf_watermark(pdf_path, output_path, watermark_type="text",
                      text_content="", font_size=30, text_color=(0.5, 0.5, 0.5), # RGB (0.0-1.0)
                      image_watermark_path=None, image_opacity=0.3, image_size_ratio=0.1,
                      position="bottom_right", rotate_degree=0): # 新增旋轉(zhuǎn)參數(shù)
    """
    為PDF文件添加文字水印或圖片水印。
    這是PDF自動化和PDF加水印的核心功能。
    :param pdf_path: 源PDF文件路徑
    :param output_path: 輸出PDF文件路徑
    :param watermark_type: "text" (文字水印) 或 "image" (圖片水印)
    :param text_content: 文字水印內(nèi)容
    :param font_size: 文字水印字體大小
    :param text_color: 文字水印顏色 (RGB元組,范圍0.0-1.0)
    :param image_watermark_path: 圖片水印文件路徑
    :param image_opacity: 圖片水印透明度 (0.0-1.0)
    :param image_size_ratio: 圖片水印相對于頁面寬度的比例
    :param position: 水印位置 ("top_left", "top_right", "bottom_left", "bottom_right", "center")
    :param rotate_degree: 文字水印旋轉(zhuǎn)角度 (度)
    """
    if not os.path.exists(pdf_path): return print(f"? PDF文件不存在:{pdf_path}")
    os.makedirs(os.path.dirname(output_path), exist_ok=True)

    doc = fitz.open(pdf_path) # 打開PDF文檔
    print(f"?? 正在為 '{os.path.basename(pdf_path)}' 添加水印...")

    # 嘗試加載中文字體
    font_name_in_pdf = "helv" # 默認內(nèi)置字體
    if pdf_font_path and os.path.exists(CHINESE_FONT_PATH):
        try:
            # register_font 返回字體對象的xref,可以直接用于insert_text
            font_xref = doc.register_font(fontfile=CHINESE_FONT_PATH, fontname="MyCustomFont")
            font_name_in_pdf = "MyCustomFont"
            print(f"   ?? 已注冊自定義字體 '{font_name_in_pdf}'。")
        except Exception as e:
            print(f"?? 注冊中文字體失?。簕e}。中文水印可能無法正確顯示。")
    
    # 加載圖片水?。ㄡ槍D片水?。?
    watermark_img_obj = None
    if watermark_type == "image":
        if not os.path.exists(image_watermark_path):
            print(f"? 水印圖片文件不存在:{image_watermark_path}")
            return False
        try:
            watermark_img_obj = Image.open(image_watermark_path).convert("RGBA")
            print(f"   ?? 已加載水印圖片:{os.path.basename(image_watermark_path)}")
        except Exception as e:
            print(f"? 無法加載水印圖片:{e}")
            return False

    for page_num in range(doc.page_count):
        page = doc.load_page(page_num)
        rect = page.rect # 獲取頁面矩形
        
        if watermark_type == "text":
            # 插入文字水印
            # 注意:fitz.insert_text直接處理透明度和顏色 (R,G,B浮點數(shù)0.0-1.0)
            # 計算文字尺寸和位置 (需要實際渲染才能準確獲取,這里估算)
            # fitz.Font().text_bbox() 更精確,但需先實例化Font
            text_len_estimate = fitz.Font(fontname=font_name_in_pdf).text_bbox(text_content, fontsize=font_size)[2]
            text_height_estimate = font_size * 1.2 # 粗略估算高度

            x, y = 0, 0
            if position == "top_left": x, y = rect.x0 + 20, rect.y0 + 20
            elif position == "top_right": x, y = rect.x1 - text_len_estimate - 20, rect.y0 + 20
            elif position == "bottom_left": x, y = rect.x0 + 20, rect.y1 - text_height_estimate - 20
            elif position == "bottom_right": x, y = rect.x1 - text_len_estimate - 20, rect.y1 - text_height_estimate - 20
            elif position == "center": x, y = (rect.width - text_len_estimate) / 2, (rect.height - text_height_estimate) / 2
            
            # 使用 insert_text
            page.insert_text(
                (x, y),
                text_content,
                fontname=font_name_in_pdf,
                fontsize=font_size,
                color=text_color, # 顏色為RGB浮點元組 (0.0, 0.0, 0.0) 到 (1.0, 1.0, 1.0)
                # rotate=rotate_degree, # 旋轉(zhuǎn)在insert_text中不直接支持,需要transform矩陣
                overlay=True, # 確保水印在內(nèi)容之上
            )
            # 對于旋轉(zhuǎn),需要更復雜的PyMuPDF變換矩陣,這里為簡潔不展開

        elif watermark_type == "image" and watermark_img_obj:
            # 插入圖片水印
            page_width, page_height = rect.width, rect.height

            # 調(diào)整水印圖片大小 (相對于頁面寬度比例)
            wm_width = int(page_width * image_size_ratio)
            wm_height = int(wm_width * watermark_img_obj.height / watermark_img_obj.width) # 保持比例
            
            # 確保水印不超出頁面且有最小尺寸
            if wm_width == 0 or wm_height == 0:
                print(f"?? 水印尺寸計算為零,跳過頁面 {page_num+1}。")
                continue
            
            resized_watermark_pil = watermark_img_obj.resize((wm_width, wm_height), Image.LANCZOS)
            
            # 調(diào)整水印圖片透明度
            alpha = resized_watermark_pil.split()[-1]
            alpha = Image.eval(alpha, lambda x: x * image_opacity)
            resized_watermark_pil.putalpha(alpha)
            
            # 將處理后的水印圖片轉(zhuǎn)為BytesIO,以便PyMuPDF插入
            img_byte_arr = io.BytesIO()
            resized_watermark_pil.save(img_byte_arr, format='PNG')
            img_byte_arr_value = img_byte_arr.getvalue()

            # 計算粘貼坐標
            insert_x, insert_y = 0, 0
            if position == "top_left": insert_x, insert_y = 10, 10
            elif position == "top_right": insert_x, insert_y = page_width - wm_width - 10, 10
            elif position == "bottom_left": insert_x, insert_y = 10, page_height - wm_height - 10
            elif position == "bottom_right": insert_x, insert_y = page_width - wm_width - 10, page_height - wm_height - 10
            elif position == "center": insert_x, insert_y = (page_width - wm_width) // 2, (page_height - wm_height) // 2
            
            insert_rect = fitz.Rect(insert_x, insert_y, insert_x + wm_width, insert_y + wm_height)
            
            page.insert_image(insert_rect, stream=img_byte_arr_value, overlay=True)

        print(f"   - 頁面 {page_num+1} 已添加水印。")
    
    doc.save(output_path)
    print(f"? PDF水印添加完成!文件已保存到:'{output_path}'")
    return True
    finally:
        if 'doc' in locals(): doc.close()
        if 'watermark_img_obj' in locals(): watermark_img_obj.close() # 關閉水印圖片

if __name__ == "__main__":
    # 準備測試PDF文件 (多頁)
    source_pdf_path = os.path.expanduser("~/Desktop/sample_report.pdf")
    # 簡單創(chuàng)建模擬PDF文件
    if not os.path.exists(source_pdf_path):
        doc = fitz.open(); doc.new_page().insert_text(fitz.Point(50,50), "這是測試報告第一頁\n請勿復制"); doc.new_page().insert_text(fitz.Point(50,50), "這是第二頁"); doc.save(source_pdf_path); doc.close()
    
    # 準備Logo圖片 (如果測試圖片水印)
    logo_path = os.path.expanduser("~/Desktop/company_logo.png")
    if not os.path.exists(logo_path):
        Image.new('RGBA', (100, 50), color = (255, 0, 0, 128)).save(logo_path) # 模擬透明紅色Logo
        print(f"臨時Logo文件 '{os.path.basename(logo_path)}' 已創(chuàng)建。")

    output_text_wm_pdf = os.path.expanduser("~/Desktop/report_with_text_wm.pdf")
    output_image_wm_pdf = os.path.expanduser("~/Desktop/report_with_logo_wm.pdf")

    # 示例1:批量添加文字水印
    print("\n--- 示例1:添加文字水印 ---")
    add_pdf_watermark(
        source_pdf_path, 
        output_text_wm_pdf, 
        watermark_type="text", 
        text_content="【機密文件 嚴禁外傳】", 
        font_size=20, # 調(diào)整字體大小
        text_color=(1, 0, 0), # 紅色 (0.0-1.0)
        position="center" # 居中
    )

    # 示例2:批量添加圖片水印 (Logo)
    print("\n--- 示例2:添加圖片Logo水印 ---")
    add_pdf_watermark(
        source_pdf_path, 
        output_image_wm_pdf, 
        watermark_type="image", 
        image_watermark_path=logo_path, 
        image_opacity=0.3, # 更透明
        image_size_ratio=0.2 # 尺寸更大
    )

操作:

安裝庫: pip install PyMuPDF Pillow。

準備PDF和Logo: 在桌面創(chuàng)建sample_report.pdf(多頁),以及company_logo.png(一個Logo圖)。

修改代碼路徑和水印參數(shù): 修改 source_pdf_path、logo_path 等路徑和水印參數(shù)。

運行: 運行 python add_pdf_watermark.py。

注意中文: 如果使用中文水印,需要確保 CHINESE_FONT_PATH 指向一個存在的中文字體文件,否則可能顯示方塊。

展示:

3.2 批量添加頁碼:讓你的報告規(guī)范專業(yè)

場景: 制作長篇報告、書籍時,需要為每一頁自動添加統(tǒng)一的頁眉、頁腳和頁碼,如“第X頁 / 共Y頁”。手動在PDF編輯器中添加,效率極低且容易出錯。

方案: PyMuPDF能夠讓你自動化地為PDF文檔添加頁碼,讓你的文檔瞬間變得專業(yè)和規(guī)范。

代碼:

mport fitz # PyMuPDF
import os

# 確保中文字體路徑正確,用于PDF中文頁碼渲染
CHINESE_FONT_PATH = "C:/Windows/Fonts/simhei.ttf" # Windows黑體示例

def add_page_numbers_to_pdf(input_pdf_path, output_pdf_path, position="bottom_center", font_size=9, color=(0,0,0)):
    """
    為PDF文件的每一頁批量添加頁碼。
    這是Python處理PDF和PDF頁碼自動化的核心功能。
    :param input_pdf_path: 源PDF文件路徑
    :param output_pdf_path: 添加頁碼后PDF文件的輸出路徑
    :param position: 頁碼位置 ("top_left", "top_right", "bottom_left", "bottom_right", "center", "bottom_center", "top_center")
    :param font_size: 字體大小
    :param color: 顏色 (R, G, B),范圍0.0-1.0
    """
    if not os.path.exists(input_pdf_path): return print(f"? PDF文件不存在:{input_pdf_path}")
    os.makedirs(os.path.dirname(output_pdf_path), exist_ok=True)

    print(f"?? 正在為 '{os.path.basename(input_pdf_path)}' 批量添加頁碼...")
    try:
        doc = fitz.open(input_pdf_path)
        
        # 嘗試加載中文字體 (用于中文頁碼,如“第X頁”)
        font_name_in_pdf = "helv" # 默認內(nèi)置字體 (英文數(shù)字)
        if CHINESE_FONT_PATH and os.path.exists(CHINESE_FONT_PATH):
            try:
                doc.register_font(fontfile=CHINESE_FONT_PATH, fontname="MyCustomFont")
                font_name_in_pdf = "MyCustomFont"
                print(f"   ?? 已注冊自定義字體 '{font_name_in_pdf}'。")
            except Exception as e:
                print(f"?? 注冊中文字體失?。簕e}。中文頁碼可能無法正確顯示。")
        
        total_pages = doc.page_count
        for page_num in range(total_pages):
            page = doc.load_page(page_num)
            
            # 頁碼文本:例如 "Page 1 / 10" 或 "第1頁 / 共10頁" (根據(jù)是否成功加載中文顯示)
            page_text = f"Page {page_num + 1} / {total_pages}" 
            if font_name_in_pdf == "MyCustomFont": # 如果成功加載了中文字體
                 page_text = f"第 {page_num + 1} 頁 / 共 {total_pages} 頁"

            # 計算頁碼位置
            rect = page.rect # 頁面矩形
            # fitz.Font().text_bbox() 更精確計算文本寬度,這里使用估算
            # text_len_estimate = fitz.Font(fontname=font_name_in_pdf).text_bbox(page_text, fontsize=font_size)[2]
            text_len_estimate = font_size * len(page_text) * 0.6 # 粗略估算寬度
            text_height_estimate = font_size * 1.2 # 粗略估算高度

            x, y = 0, 0
            if position == "top_left": x, y = rect.x0 + 20, rect.y0 + 20
            elif position == "top_right": x, y = rect.x1 - text_len_estimate - 20, rect.y0 + 20
            elif position == "bottom_left": x, y = rect.x0 + 20, rect.y1 - text_height_estimate - 20
            elif position == "bottom_right": x, y = rect.x1 - text_len_estimate - 20, rect.y1 - text_height_estimate - 20
            elif position == "center": x, y = (rect.width - text_len_estimate) / 2, (rect.height - text_height_estimate) / 2
            elif position == "bottom_center": x, y = (rect.width - text_len_estimate) / 2, rect.y1 - text_height_estimate - 20
            elif position == "top_center": x, y = (rect.width - text_len_estimate) / 2, rect.y0 + 20
            
            page.insert_text(
                (x, y),
                page_text,
                fontname=font_name_in_pdf, # 使用注冊的字體名或內(nèi)置字體
                fontsize=font_size,
                color=color, # 顏色 (R, G, B) 范圍0.0-1.0
                overlay=True # 確保頁碼在內(nèi)容之上
            )
            print(f"   - 頁面 {page_num+1} 已添加頁碼。")
    
    doc.save(output_path)
    print(f"? PDF頁碼添加完成!文件已保存到:'{output_path}'")
    return True
    finally:
        if 'doc' in locals(): doc.close()

if __name__ == "__main__":
    input_pdf = os.path.expanduser("~/Desktop/long_report_no_pages.pdf")
    output_pdf = os.path.expanduser("~/Desktop/report_with_page_numbers.pdf")

    # 簡單創(chuàng)建模擬PDF文件 (多頁)
    if not os.path.exists(input_pdf):
        doc = fitz.open()
        for i in range(5):
            page = doc.new_page()
            page.insert_text(fitz.Point(50,50), f"這是第 {i+1} 頁的內(nèi)容。")
        doc.save(input_pdf); doc.close()

    # 示例1:添加右下角居中頁碼
    print("\n--- 示例1:添加居中底部頁碼 ---")
    add_page_numbers_to_pdf(
        input_pdf, 
        output_pdf, 
        position="bottom_center", 
        font_size=10, 
        color=(0, 0, 0) # 黑色
    )

操作步驟:

安裝PyMuPDF: pip install PyMuPDF。

準備PDF文件: 在桌面準備一個包含多頁的PDF文件(如long_report_no_pages.pdf)。

修改代碼路徑和頁碼參數(shù): 修改 input_pdf 和 output_pdf。

運行: 運行 python add_pdf_page_numbers.py。

效果展示:

3.3 PDF密碼加密與解密:為你的重要文檔上鎖

場景: 你的PDF報告或合同包含敏感信息,需要進行PDF加密保護,只有擁有密碼的人才能打開。手動設置密碼繁瑣且不安全。

方案: PyPDF2能夠?qū)崿F(xiàn)PDF文件的密碼加密和解密,為你的敏感文檔加上一把“安全鎖”,確保PDF加密和PDF解密的便捷。
代碼:

from PyPDF2 import PdfReader, PdfWriter
import os
import shutil # 用于復制文件,如果未加密則直接復制

def encrypt_pdf_with_password(pdf_path, output_path, password):
    """
    使用密碼加密PDF文件。
    這是PDF自動化和PDF加密的核心功能。
    :param pdf_path: 源PDF文件路徑
    :param output_path: 加密后PDF文件的輸出路徑
    :param password: 加密密碼 (字符串)
    """
    if not os.path.exists(pdf_path): return print(f"? PDF文件不存在:{pdf_path}")
    os.makedirs(os.path.dirname(output_path), exist_ok=True)

    reader = PdfReader(pdf_path)
    writer = PdfWriter()

    print(f"?? 正在加密PDF文件 '{os.path.basename(pdf_path)}'...")

    for page in reader.pages:
        writer.add_page(page) # 將所有頁面添加到writer

    try:
        writer.encrypt(password) # 設置加密密碼
        with open(output_path, "wb") as output_pdf_file:
            writer.write(output_pdf_file)
        print(f"? PDF文件加密成功!保存到:'{output_path}'")
        return True
    except Exception as e:
        print(f"? PDF加密失敗:{e}")
        return False

def decrypt_pdf_with_password(encrypted_pdf_path, output_path, password):
    """
    使用密碼解密PDF文件。
    這是PDF自動化和PDF解密的核心功能。
    :param encrypted_pdf_path: 加密PDF文件路徑
    :param output_path: 解密后PDF文件的輸出路徑
    :param password: 解密密碼 (字符串)
    """
    if not os.path.exists(encrypted_pdf_path): return print(f"? 加密PDF文件不存在:{encrypted_pdf_path}")
    os.makedirs(os.path.dirname(output_path), exist_ok=True)

    reader = PdfReader(encrypted_pdf_path)
    
    if reader.is_encrypted:
        if not reader.decrypt(password): # 嘗試解密
            print(f"? 解密失敗:'{os.path.basename(encrypted_pdf_path)}' 密碼不正確或文件已損壞。")
            return False
    else:
        print(f"?? 文件 '{os.path.basename(encrypted_pdf_path)}' 未加密,直接復制到輸出路徑。")
        shutil.copyfile(encrypted_pdf_path, output_path) # 未加密則直接復制
        print(f"文件已直接復制到:'{output_path}'")
        return True
     
    writer = PdfWriter()
    for page in reader.pages:
        writer.add_page(page)

    try:
        with open(output_path, "wb") as output_pdf_file:
            writer.write(output_pdf_file)
        print(f"? PDF文件解密成功!保存到:'{output_path}'")
        return True
    except Exception as e:
        print(f"? PDF解密失敗:{e}")
        return False

if __name__ == "__main__":
    # 準備測試PDF文件
    source_pdf = os.path.expanduser("~/Desktop/secret_document.pdf")
    if not os.path.exists(source_pdf):
        doc = fitz.open(); doc.new_page().insert_text(fitz.Point(50,50), "這是機密文檔"); doc.save(source_pdf); doc.close()
    
    encrypted_pdf = os.path.expanduser("~/Desktop/secret_document_encrypted.pdf")
    decrypted_pdf = os.path.expanduser("~/Desktop/secret_document_decrypted.pdf")
    
    password = "MySecurePassword123"

    # 示例1:加密PDF
    print("\n--- 示例1:加密PDF文件 ---")
    encrypt_pdf_with_password(source_pdf, encrypted_pdf, password)

    # 示例2:解密PDF
    print("\n--- 示例2:解密PDF文件 ---")
    decrypt_pdf_with_password(encrypted_pdf, decrypted_pdf, password)
    
    # 示例3:嘗試用錯誤密碼解密
    print("\n--- 示例3:嘗試用錯誤密碼解密 ---")
    decrypt_pdf_with_password(encrypted_pdf, os.path.expanduser("~/Desktop/failed_decryption.pdf"), "WrongPassword")

步驟:

安裝庫: pip install PyPDF2 PyMuPDF (PyMuPDF用于創(chuàng)建測試PDF)。
準備PDF: 在桌面創(chuàng)建secret_document.pdf。

修改代碼路徑和密碼: 修改 source_pdf 等路徑和 password。
運行: 運行 python pdf_encrypt_decrypt.py。

效果展示:

4. 階段性總結pdf 全能管家

通過本篇文章,你已經(jīng)掌握了PDF文檔自動化的各項核心魔法,親手打造了一個能夠一鍵合并、分割、水印、提取與加密解密的 PDF全能管家!

我們深入學習了PyPDF2和PyMuPDF等庫,它們堪稱Python PDF庫中的“瑞士軍刀”,實現(xiàn)了:

PDF合并分割: 輕松將多份PDF批量合并,或?qū)㈤L篇PDF按頁分割,高效整理文檔。

PDF水印: 自動化添加文字/圖片Logo水印,保護文檔版權,提升專業(yè)度。

PDF頁碼自動化: 告別手動排版,為報告批量加頁碼,瞬間規(guī)范。

PDF加密解密: 為你的敏感PDF文件加把“安全鎖”,確保文檔管理中的數(shù)據(jù)安全。

現(xiàn)在,你不再需要為PDF文件難管理、編輯受限、手動操作低效而煩惱。

5.尾聲:PDF自動化,解鎖文檔管理新高度!

通過本篇文章,你已經(jīng)掌握了PDF文檔自動化的強大能力,為你的辦公自動化之旅又增添了一個重量級技能!你學會了如何利用Python的PDF處理庫,高效地進行PDF文檔的合并、分割、水印、頁碼和加密解密。

除了今天學到的PDF自動化功能,你還希望Python能幫你實現(xiàn)哪些更復雜的PDF處理需求?比如:自動填寫PDF表單?將PDF內(nèi)容智能轉(zhuǎn)換為Excel或Word?

以上就是使用Python實現(xiàn)PDF文檔自動化的操作大全(一鍵合并、分割、水印、提取與加密解密)的詳細內(nèi)容,更多關于Python PDF文檔自動化的資料請關注腳本之家其它相關文章!

相關文章

  • python基于三階貝塞爾曲線的數(shù)據(jù)平滑算法

    python基于三階貝塞爾曲線的數(shù)據(jù)平滑算法

    這篇文章主要介紹了python基于三階貝塞爾曲線的數(shù)據(jù)平滑算法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • Python編程中使用Pillow來處理圖像的基礎教程

    Python編程中使用Pillow來處理圖像的基礎教程

    這篇文章主要介紹了Python編程中使用Pillow來處理圖像的基礎教程,Pillow和PIL都是Python下十分強大的圖片處理利器,朋友可以參考下
    2015-11-11
  • Python 利用argparse模塊實現(xiàn)腳本命令行參數(shù)解析

    Python 利用argparse模塊實現(xiàn)腳本命令行參數(shù)解析

    這篇文章主要介紹了Python 利用argparse模塊實現(xiàn)腳本命令行參數(shù)解析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Python語言在AI中的常用工具和應用場景

    Python語言在AI中的常用工具和應用場景

    文章探討了TensorFlow、PyTorch和Keras等流行的深度學習框架,以及Scikit-learn等用于機器學習的庫,文章還舉例說明了AI在自然語言處理、圖像識別、語音識別和推薦系統(tǒng)等領域的實際應用場景,并介紹了如何使用Python調(diào)用AI大模型的接口
    2025-02-02
  • Python函數(shù)參數(shù)基礎介紹及示例

    Python函數(shù)參數(shù)基礎介紹及示例

    在聲明函數(shù)的時候,一般會根據(jù)函數(shù)所要實現(xiàn)的功能來決定函數(shù)是否需要參數(shù)。在多數(shù)情況下,我們聲明的函數(shù)都會使用到參數(shù),這篇文章主要介紹了Python函數(shù)參數(shù)
    2022-08-08
  • Python之Matplotlib文字與注釋的使用方法

    Python之Matplotlib文字與注釋的使用方法

    這篇文章主要介紹了Python之Matplotlib文字與注釋的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Python安全傳參給C函數(shù)的4種類型轉(zhuǎn)換方法詳解

    Python安全傳參給C函數(shù)的4種類型轉(zhuǎn)換方法詳解

    這篇文章主要來帶大家掌握Python調(diào)用C函數(shù)的安全傳參技巧,被將詳解C語言Python類型轉(zhuǎn)換的4種核心方法,涵蓋字符串、數(shù)值與指針轉(zhuǎn)換場景,確保數(shù)據(jù)安全高效交互,感興趣的小伙伴可以了解下
    2026-01-01
  • Python unittest框架操作實例解析

    Python unittest框架操作實例解析

    這篇文章主要介紹了Python unittest框架操作實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • python3操作微信itchat實現(xiàn)發(fā)送圖片

    python3操作微信itchat實現(xiàn)發(fā)送圖片

    這篇文章主要為大家詳細介紹了python3操作微信itchat實現(xiàn)發(fā)送圖片,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Python中用于返回絕對值的abs()方法

    Python中用于返回絕對值的abs()方法

    這篇文章主要介紹了Python中用于返回絕對值的abs()方法,是Python入門中的基礎知識,需要的朋友可以參考下
    2015-05-05

最新評論

文成县| 仙桃市| 栖霞市| 上虞市| 永安市| 江北区| 定西市| 陆良县| 甘德县| 社旗县| 黎平县| 东方市| 乌兰察布市| 崇信县| 肇源县| 安福县| 嘉善县| 湾仔区| 丽水市| 德安县| 乌恰县| 鄂温| 炉霍县| 华宁县| 耒阳市| 项城市| 福海县| 留坝县| 济南市| 六枝特区| 桃园县| 汾西县| 张家川| 浠水县| 班玛县| 吴桥县| 儋州市| 桓台县| 正定县| 拉孜县| 蒙城县|