本文目录导读:

- 方法一:使用 PyPDF2(最常用)
- 方法二:使用 pdfplumber + PyPDF2(有页面控制)
- 方法三:使用 pdfkit(需要安装wkhtmltopdf)
- 方法四:使用 pypdf(PyPDF2的后继者)
- 方法五:命令行工具(subprocess)
- 完整示例:带界面的PDF合并工具
- 安装依赖
- 使用建议
我来介绍几种在Python中合并PDF文件的方法:
使用 PyPDF2(最常用)
import PyPDF2
def merge_pdfs_pypdf2(pdf_list, output_path):
"""
使用PyPDF2合并PDF文件
:param pdf_list: PDF文件路径列表
:param output_path: 输出文件路径
"""
# 创建PDF合并器
merger = PyPDF2.PdfMerger()
try:
# 逐个添加PDF文件
for pdf_path in pdf_list:
merger.append(pdf_path)
# 写入合并后的文件
with open(output_path, 'wb') as output_file:
merger.write(output_file)
print(f"合并成功!输出文件:{output_path}")
finally:
merger.close()
# 使用示例
pdf_files = ['file1.pdf', 'file2.pdf', 'file3.pdf']
merge_pdfs_pypdf2(pdf_files, 'merged_output.pdf')
使用 pdfplumber + PyPDF2(有页面控制)
import PyPDF2
from pathlib import Path
def merge_pdfs_with_pages(pdf_dict, output_path):
"""
合并PDF并指定页面范围
:param pdf_dict: 字典,格式 {pdf_path: page_ranges}
:param output_path: 输出文件路径
"""
merger = PyPDF2.PdfMerger()
try:
for pdf_path, pages in pdf_dict.items():
if pages is None: # 添加全部页面
merger.append(pdf_path)
else: # 添加指定页面
merger.append(pdf_path, pages=pages)
merger.write(output_path)
print(f"合并成功!输出文件:{output_path}")
finally:
merger.close()
# 使用示例
pdf_files = {
'file1.pdf': None, # 添加全部页面
'file2.pdf': (0, 2), # 添加第0-2页
'file3.pdf': (3, 5) # 添加第3-5页
}
merge_pdfs_with_pages(pdf_files, 'merged_with_pages.pdf')
使用 pdfkit(需要安装wkhtmltopdf)
import pdfkit
def merge_pdfs_pdfkit(pdf_list, output_path):
"""
使用pdfkit合并PDF文件
:param pdf_list: PDF文件路径列表
:param output_path: 输出文件路径
"""
try:
pdfkit.from_file(pdf_list, output_path)
print(f"合并成功!输出文件:{output_path}")
except Exception as e:
print(f"合并失败:{e}")
# 使用示例
pdf_files = ['file1.pdf', 'file2.pdf', 'file3.pdf']
merge_pdfs_pdfkit(pdf_files, 'merged_output.pdf')
使用 pypdf(PyPDF2的后继者)
from pypdf import PdfWriter
def merge_pdfs_pypdf(pdf_list, output_path):
"""
使用pypdf合并PDF文件
:param pdf_list: PDF文件路径列表
:param output_path: 输出文件路径
"""
merger = PdfWriter()
try:
for pdf_path in pdf_list:
merger.append(pdf_path)
merger.write(output_path)
merger.close()
print(f"合并成功!输出文件:{output_path}")
except Exception as e:
print(f"合并失败:{e}")
# 使用示例
pdf_files = ['file1.pdf', 'file2.pdf', 'file3.pdf']
merge_pdfs_pypdf(pdf_files, 'merged_output.pdf')
命令行工具(subprocess)
import subprocess
import os
def merge_pdfs_qpdf(pdf_list, output_path):
"""
使用qpdf命令行工具合并PDF
:param pdf_list: PDF文件路径列表
:param output_path: 输出文件路径
"""
try:
# 构建qpdf命令
cmd = ['qpdf', '--empty', '--pages']
for pdf in pdf_list:
cmd.extend([pdf])
cmd.extend(['--', output_path])
# 执行命令
subprocess.run(cmd, check=True)
print(f"合并成功!输出文件:{output_path}")
except subprocess.CalledProcessError:
print("合并失败,请确保已安装qpdf")
except FileNotFoundError:
print("未找到qpdf,请先安装:sudo apt-get install qpdf")
# 使用示例
pdf_files = ['file1.pdf', 'file2.pdf', 'file3.pdf']
merge_pdfs_qpdf(pdf_files, 'merged_output.pdf')
完整示例:带界面的PDF合并工具
import tkinter as tk
from tkinter import filedialog, messagebox
import PyPDF2
import os
class PDFMergerGUI:
def __init__(self, root):
self.root = root
self.root.title("PDF合并工具")
self.root.geometry("500x400")
self.pdf_files = []
# 创建界面
self.create_widgets()
def create_widgets(self):
# 添加文件按钮
self.btn_add = tk.Button(self.root, text="添加PDF文件",
command=self.add_files, width=15)
self.btn_add.pack(pady=10)
# 文件列表
self.listbox = tk.Listbox(self.root, width=60, height=15)
self.listbox.pack(pady=10)
# 操作按钮
frame = tk.Frame(self.root)
frame.pack(pady=10)
self.btn_up = tk.Button(frame, text="上移", command=self.move_up, width=10)
self.btn_up.pack(side=tk.LEFT, padx=5)
self.btn_down = tk.Button(frame, text="下移", command=self.move_down, width=10)
self.btn_down.pack(side=tk.LEFT, padx=5)
self.btn_remove = tk.Button(frame, text="移除", command=self.remove_file, width=10)
self.btn_remove.pack(side=tk.LEFT, padx=5)
# 合并按钮
self.btn_merge = tk.Button(self.root, text="合并PDF",
command=self.merge_pdfs, width=15,
bg="lightblue")
self.btn_merge.pack(pady=20)
def add_files(self):
files = filedialog.askopenfilenames(
title="选择PDF文件",
filetypes=[("PDF文件", "*.pdf")]
)
for file in files:
if file not in self.pdf_files:
self.pdf_files.append(file)
self.listbox.insert(tk.END, os.path.basename(file))
def move_up(self):
selection = self.listbox.curselection()
if selection:
index = selection[0]
if index > 0:
self.pdf_files[index], self.pdf_files[index-1] = \
self.pdf_files[index-1], self.pdf_files[index]
self.update_listbox()
self.listbox.selection_set(index-1)
def move_down(self):
selection = self.listbox.curselection()
if selection:
index = selection[0]
if index < len(self.pdf_files) - 1:
self.pdf_files[index], self.pdf_files[index+1] = \
self.pdf_files[index+1], self.pdf_files[index]
self.update_listbox()
self.listbox.selection_set(index+1)
def remove_file(self):
selection = self.listbox.curselection()
if selection:
index = selection[0]
del self.pdf_files[index]
self.update_listbox()
def update_listbox(self):
self.listbox.delete(0, tk.END)
for file in self.pdf_files:
self.listbox.insert(tk.END, os.path.basename(file))
def merge_pdfs(self):
if not self.pdf_files:
messagebox.showwarning("警告", "请先添加PDF文件")
return
output_file = filedialog.asksaveasfilename(
defaultextension=".pdf",
filetypes=[("PDF文件", "*.pdf")]
)
if output_file:
try:
merger = PyPDF2.PdfMerger()
for pdf_file in self.pdf_files:
merger.append(pdf_file)
with open(output_file, 'wb') as f:
merger.write(f)
merger.close()
messagebox.showinfo("成功", f"PDF合并完成!\n输出文件:{output_file}")
except Exception as e:
messagebox.showerror("错误", f"合并失败:{str(e)}")
# 运行GUI
if __name__ == "__main__":
root = tk.Tk()
app = PDFMergerGUI(root)
root.mainloop()
安装依赖
# 安装PyPDF2 pip install PyPDF2 # 或安装pypdf pip install pypdf # 安装pdfkit(需要安装wkhtmltopdf) pip install pdfkit # 安装pdfplumber pip install pdfplumber
使用建议
- 选择PyPDF2:最常用,功能完整,适合大多数场景
- 选择pypdf:PyPDF2的现代版本,推荐新项目使用
- 批量处理:使用循环遍历文件夹
- 错误处理:添加异常捕获和处理逻辑
- 内存优化:处理大文件时考虑逐页处理
这些方法都能很好地合并PDF文件,选择哪种取决于你的具体需求和依赖库的可用性。