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

Python批量合并PDF文件的方法詳解

 更新時(shí)間:2026年03月24日 08:13:27   作者:站大爺IP  
這篇文章主要為大家詳細(xì)介紹了如何使用Python批量合并PDF文件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下

?周一早上九點(diǎn),你的郵箱里躺著十幾封郵件,每封都帶了一個(gè)PDF附件——上周會(huì)議的簽到表、各小組的報(bào)告、財(cái)務(wù)的報(bào)銷憑證。領(lǐng)導(dǎo)在微信群里發(fā)了一條消息:“把這些文件合并成一個(gè),發(fā)到公司群里。”

你打開第一個(gè)PDF,又打開第二個(gè),鼠標(biāo)拖來(lái)拖去,發(fā)現(xiàn)Adobe Acrobat彈出一個(gè)窗口:“您的試用期已結(jié)束。”同事推薦了在線合并工具,你上傳完所有文件,等待進(jìn)度條走到100%,頁(yè)面彈出五個(gè)字:“請(qǐng)付費(fèi)解鎖。”

這不是你的錯(cuò)。PDF合并這件事看起來(lái)簡(jiǎn)單,真上手才發(fā)現(xiàn)處處是坑。在線工具要么限制頁(yè)數(shù),要么加水印,要么悄悄把你的文件傳到不明服務(wù)器。桌面軟件不是收費(fèi)就是臃腫得像個(gè)航空母艦。

你需要的其實(shí)很簡(jiǎn)單:一個(gè)能批量處理、不用花錢、跑起來(lái)就完事的工具。Python剛好能做到,而且代碼少到你不用是程序員也能看懂。

先把你需要的工具裝好

Python合并PDF這件事,全靠一個(gè)叫PyPDF2的庫(kù)。它專門用來(lái)處理PDF,能讀、能寫、能合并、能拆分。

安裝就一行命令:

pip install PyPDF2

如果你用的是Python 3,可能需要安裝PyPDF2的升級(jí)版PyPDF4,用法幾乎一樣。這里用PyPDF2演示,兼容性最好。

裝完之后,打開你的代碼編輯器,新建一個(gè)Python文件,就叫merge_pdf.py。

最簡(jiǎn)單的合并:把所有PDF放在一起

假設(shè)你的桌面上有一個(gè)文件夾叫“待合并”,里面放了三個(gè)PDF文件:報(bào)告1.pdf、報(bào)告2.pdf、報(bào)告3.pdf。你想把它們按順序拼成一個(gè)總報(bào)告。

代碼長(zhǎng)這樣:

import PyPDF2
import os

# 創(chuàng)建一個(gè)空的PDF寫入器
merger = PyPDF2.PdfMerger()

# 定義文件夾路徑
folder_path = r"C:\Users\你的用戶名\Desktop\待合并"

# 獲取文件夾里所有PDF文件,并按文件名排序
pdf_files = [f for f in os.listdir(folder_path) if f.endswith('.pdf')]
pdf_files.sort()

# 逐個(gè)添加到合并器
for pdf in pdf_files:
    full_path = os.path.join(folder_path, pdf)
    merger.append(full_path)

# 寫出合并后的文件
output_path = os.path.join(folder_path, "合并結(jié)果.pdf")
merger.write(output_path)
merger.close()

print(f"合并完成,文件保存在:{output_path}")

跑完這段代碼,你會(huì)發(fā)現(xiàn)“待合并”文件夾里多了一個(gè)“合并結(jié)果.pdf”,里面按順序包含了所有文件的內(nèi)容。

這段代碼的邏輯很簡(jiǎn)單:PyPDF2.PdfMerger()創(chuàng)建了一個(gè)空容器,相當(dāng)于一張白紙。append()方法把每個(gè)PDF一頁(yè)一頁(yè)地貼上去,就像在打印機(jī)上疊放紙張。最后write()把結(jié)果存下來(lái)。

文件順序亂了怎么辦

上面的代碼用了sort()來(lái)排序,但這只能保證按字母順序排列。如果文件名是“報(bào)告1”、“報(bào)告10”、“報(bào)告2”,sort()會(huì)把“報(bào)告10”排在“報(bào)告2”前面,因?yàn)樽址容^是一個(gè)字符一個(gè)字符來(lái)的。

解決辦法有兩種。

第一種,給文件命名的時(shí)候用數(shù)字編號(hào),比如001_報(bào)告、002_報(bào)告。這樣排序就是按數(shù)字順序,不會(huì)亂。

第二種,自己指定順序:

# 手動(dòng)指定順序
pdf_files = ["簽到表.pdf", "小組報(bào)告.pdf", "財(cái)務(wù)憑證.pdf"]

for pdf in pdf_files:
    full_path = os.path.join(folder_path, pdf)
    if os.path.exists(full_path):
        merger.append(full_path)
    else:
        print(f"警告:找不到文件 {pdf}")

加一個(gè)判斷,文件不存在的時(shí)候跳過(guò)并給出提示,防止程序崩潰。

只合并某些頁(yè)面

有時(shí)候你不需要合并整個(gè)PDF,只需要其中的幾頁(yè)。比如一個(gè)20頁(yè)的報(bào)告,你只要第3到第7頁(yè)。

PyPDF2允許指定頁(yè)碼范圍:

# 只合并第3到第7頁(yè)(頁(yè)碼從0開始)
merger.append("報(bào)告.pdf", pages=(2, 7))

這里的pages參數(shù)接收一個(gè)元組,第一個(gè)數(shù)字是起始頁(yè)(從0開始),第二個(gè)數(shù)字是結(jié)束頁(yè)(不包含這一頁(yè))。所以(2, 7)表示第3頁(yè)到第7頁(yè),一共5頁(yè)。

如果你想單獨(dú)挑幾頁(yè),可以用另一種方式:

# 先讀取文件
reader = PyPDF2.PdfReader("報(bào)告.pdf")
# 只取第1頁(yè)、第3頁(yè)、第5頁(yè)
pages_to_take = [0, 2, 4]
for page_num in pages_to_take:
    merger.append(reader.pages[page_num])

這種方式靈活度更高,你想怎么組合都行。

處理子文件夾里的PDF

真實(shí)的場(chǎng)景往往更復(fù)雜。你的文件可能分散在不同的子文件夾里:財(cái)務(wù)組一個(gè)文件夾、技術(shù)組一個(gè)文件夾、銷售組一個(gè)文件夾。你想把這些文件夾里的所有PDF都合并到一起。

這時(shí)候需要用os.walk來(lái)遍歷文件夾樹:

import PyPDF2
import os

merger = PyPDF2.PdfMerger()
root_folder = r"C:\Users\你的用戶名\Desktop\各部門報(bào)告"

# 遍歷所有子文件夾
for folder_path, subfolders, files in os.walk(root_folder):
    for file in files:
        if file.endswith('.pdf'):
            full_path = os.path.join(folder_path, file)
            merger.append(full_path)
            print(f"已添加:{full_path}")

merger.write(os.path.join(root_folder, "全部合并.pdf"))
merger.close()

這段代碼會(huì)從根文件夾開始,一層一層往下找,把所有子文件夾里的PDF都翻出來(lái)合并。注意一個(gè)問題:這樣合并的順序是按os.walk的遍歷順序來(lái)的,不是按文件夾名字排序。如果你需要控制順序,可以在添加之前先收集所有文件路徑,排序之后再添加。

加上書簽和目錄

合并后的PDF如果頁(yè)數(shù)太多,翻起來(lái)很痛苦。加上書簽會(huì)友好很多。

你可以把每個(gè)文件的文件名作為書簽插入:

merger = PyPDF2.PdfMerger()

for pdf in pdf_files:
    # 記錄當(dāng)前總頁(yè)數(shù),作為書簽的起始位置
    merger.append(pdf)
    # 獲取文件名(不含擴(kuò)展名)作為書簽名稱
    bookmark_name = os.path.splitext(pdf)[0]
    # 在最后添加的書簽位置插入書簽
    # 這里需要先獲取當(dāng)前總頁(yè)數(shù),PyPDF2的add_bookmark方法需要知道頁(yè)碼

PyPDF2添加書簽的API稍微有點(diǎn)繞。更簡(jiǎn)單的方式是換一個(gè)庫(kù)——pypdf(PyPDF2的現(xiàn)代替代品),它的書簽功能更直觀。

安裝pypdf:

pip install pypdf

然后用pypdf合并并添加書簽:

from pypdf import PdfWriter, PdfReader

writer = PdfWriter()

for pdf in pdf_files:
    reader = PdfReader(pdf)
    # 記錄添加之前的頁(yè)數(shù)
    start_page = len(writer.pages)
    # 添加所有頁(yè)面
    for page in reader.pages:
        writer.add_page(page)
    # 添加書簽,指向這個(gè)文件的第一頁(yè)
    bookmark_name = os.path.splitext(pdf)[0]
    writer.add_outline_item(bookmark_name, start_page)

with open("帶書簽的合并文件.pdf", "wb") as f:
    writer.write(f)

這樣生成的PDF,左側(cè)書簽欄里會(huì)列出每個(gè)原文件的文件名,點(diǎn)擊就能跳轉(zhuǎn)到對(duì)應(yīng)位置。

處理加密的PDF

有些PDF設(shè)置了打開密碼,直接合并會(huì)報(bào)錯(cuò)。如果你知道密碼,可以在讀取時(shí)解密:

reader = PyPDF2.PdfReader("加密文件.pdf")
if reader.is_encrypted:
    reader.decrypt("你的密碼")

然后把reader的頁(yè)面添加到merger里。

如果密碼不知道,那基本無(wú)解。PDF的加密算法是工業(yè)級(jí)的,直接破解不現(xiàn)實(shí)。你需要先找文件提供方要密碼,或者用專門工具移除密碼——但移除密碼也需要先輸入密碼。

大文件合并時(shí)的內(nèi)存問題

合并幾十個(gè)PDF、幾百頁(yè)文件,PyPDF2跑起來(lái)很快。但如果合并上千頁(yè)的大文件,或者一次合并上百個(gè)PDF,可能會(huì)遇到內(nèi)存不足。

PyPDF2是把所有內(nèi)容加載到內(nèi)存里再寫入的。解決方案是用pypdf的增量寫入模式,或者換用PDFtk這個(gè)命令行工具——它在底層是用C++實(shí)現(xiàn)的,處理大文件比Python高效得多。

如果你堅(jiān)持用Python,可以這樣優(yōu)化:分批次合并,先合并成幾個(gè)中間文件,再把中間文件合并成最終結(jié)果。

# 先每10個(gè)文件合并成一個(gè)臨時(shí)文件
batch_size = 10
temp_files = []

for i in range(0, len(pdf_files), batch_size):
    batch = pdf_files[i:i+batch_size]
    temp_writer = PyPDF2.PdfMerger()
    for pdf in batch:
        temp_writer.append(os.path.join(folder_path, pdf))
    temp_name = f"temp_{i}.pdf"
    temp_writer.write(temp_name)
    temp_writer.close()
    temp_files.append(temp_name)

# 再合并所有臨時(shí)文件
final_merger = PyPDF2.PdfMerger()
for temp in temp_files:
    final_merger.append(temp)
final_merger.write("最終合并.pdf")
final_merger.close()

# 清理臨時(shí)文件
import os
for temp in temp_files:
    os.remove(temp)

這種分段合并的方式,內(nèi)存占用會(huì)小很多。

給代碼加一個(gè)圖形界面

代碼寫好了,但每次運(yùn)行都要改文件夾路徑,同事想用又不會(huì)Python。這時(shí)候可以加一個(gè)簡(jiǎn)單的圖形界面,用tkinter(Python自帶的GUI庫(kù))實(shí)現(xiàn)。

import tkinter as tk
from tkinter import filedialog, messagebox
import PyPDF2
import os

def merge_pdfs():
    # 讓用戶選擇文件夾
    folder = filedialog.askdirectory()
    if not folder:
        return
    
    # 獲取所有PDF文件
    pdf_files = [f for f in os.listdir(folder) if f.lower().endswith('.pdf')]
    if not pdf_files:
        messagebox.showwarning("提示", "該文件夾中沒有PDF文件")
        return
    
    pdf_files.sort()
    
    # 合并
    merger = PyPDF2.PdfMerger()
    for pdf in pdf_files:
        full_path = os.path.join(folder, pdf)
        merger.append(full_path)
    
    output_path = os.path.join(folder, "合并結(jié)果.pdf")
    merger.write(output_path)
    merger.close()
    
    messagebox.showinfo("完成", f"合并完成!\n文件保存在:{output_path}")

# 創(chuàng)建窗口
root = tk.Tk()
root.title("PDF合并工具")
root.geometry("300x150")

btn = tk.Button(root, text="選擇文件夾并合并PDF", command=merge_pdfs, height=3, width=25)
btn.pack(expand=True)

root.mainloop()

保存為pdf_merger_gui.py,雙擊運(yùn)行,會(huì)彈出一個(gè)窗口,點(diǎn)按鈕選擇文件夾,剩下的交給程序。你的同事雙擊就能用,不需要安裝Python環(huán)境嗎?還是需要的——不過(guò)你可以用pyinstaller打包成一個(gè)exe文件,發(fā)給誰(shuí)都能用。

處理掃描件和圖片型PDF

有一種PDF比較特殊:里面不是文字,而是掃描的圖片。這類PDF合并的時(shí)候,上面所有方法都適用,因?yàn)镻yPDF2處理的是頁(yè)面對(duì)象,不管里面是文字還是圖片。

但合并之后可能會(huì)遇到一個(gè)問題——文件特別大。圖片型PDF本來(lái)就大,合并之后更大。如果需要壓縮,可以用另外的庫(kù),比如pypdf的壓縮功能,或者用img2pdf重新生成。

簡(jiǎn)單壓縮的方法:

from pypdf import PdfWriter, PdfReader

reader = PdfReader("大文件.pdf")
writer = PdfWriter()

for page in reader.pages:
    # 壓縮頁(yè)面內(nèi)容
    page.compress_content_streams()
    writer.add_page(page)

with open("壓縮后.pdf", "wb") as f:
    writer.write(f)

這個(gè)壓縮力度有限,但聊勝于無(wú)。真正想大幅壓縮圖片型PDF,需要用OCR或?qū)iT的PDF壓縮工具。

遇到報(bào)錯(cuò)怎么辦

合并過(guò)程中最常見的報(bào)錯(cuò)是“PdfReadError: EOF marker not found”。意思是PDF文件可能損壞或不完整。解決辦法是在append之前先驗(yàn)證文件是否能正常讀?。?/p>

def is_valid_pdf(filepath):
    try:
        with open(filepath, 'rb') as f:
            reader = PyPDF2.PdfReader(f)
            # 嘗試獲取頁(yè)數(shù),如果出錯(cuò)說(shuō)明文件有問題
            _ = len(reader.pages)
        return True
    except:
        return False

# 只添加有效的PDF
for pdf in pdf_files:
    full_path = os.path.join(folder_path, pdf)
    if is_valid_pdf(full_path):
        merger.append(full_path)
    else:
        print(f"跳過(guò)無(wú)效文件:{pdf}")

另一個(gè)常見報(bào)錯(cuò)是“Permission denied”,表示文件被其他程序打開(比如你在Adobe Acrobat里正看著這個(gè)文件)。關(guān)掉文件再運(yùn)行一次就行。

把合并過(guò)程寫成日志

如果你要合并的文件很多,想記錄哪些成功了、哪些失敗了,可以加一個(gè)日志功能:

import logging

logging.basicConfig(filename='merge_log.txt', level=logging.INFO, 
                    format='%(asctime)s - %(message)s')

for pdf in pdf_files:
    try:
        full_path = os.path.join(folder_path, pdf)
        merger.append(full_path)
        logging.info(f"成功添加:{pdf}")
    except Exception as e:
        logging.error(f"添加失敗:{pdf},錯(cuò)誤信息:{str(e)}")

跑完之后打開merge_log.txt,一目了然。

回到那個(gè)周一的早晨

現(xiàn)在你手頭有了一段能用的Python代碼。你雙擊運(yùn)行,三秒鐘之后,“合并結(jié)果.pdf”出現(xiàn)在文件夾里。你把它發(fā)到群里,領(lǐng)導(dǎo)回了一個(gè)大拇指。

更重要的是,下次再有同事遇到同樣的問題,你不用再解釋“你試試那個(gè)在線工具、注意不要點(diǎn)廣告、合并完記得檢查順序”——直接把代碼扔過(guò)去,或者打包成exe發(fā)給他。

PDF合并這件事,Python幫你做了一次性投入、無(wú)限次復(fù)用的自動(dòng)化。那些浪費(fèi)在下載軟件、比較付費(fèi)方案、擔(dān)心文件泄露上的時(shí)間,都可以省下來(lái)了。

到此這篇關(guān)于Python批量合并PDF文件的方法詳解的文章就介紹到這了,更多相關(guān)Python合并PDF內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

邹城市| 汶上县| 个旧市| 定远县| 永定县| 遵义市| 弥渡县| 会东县| 赣州市| 克山县| 芦山县| 定远县| 太康县| 象山县| 闻喜县| 金乡县| 东阳市| 巴青县| 淮南市| 麻栗坡县| 福清市| 治多县| 海南省| 丰顺县| 于田县| 阿图什市| 玛曲县| 湘潭县| 孝昌县| 招远市| 册亨县| 金塔县| 灵璧县| 商丘市| 平罗县| 桐庐县| 邹平县| 涡阳县| 呼伦贝尔市| 兴城市| 子长县|