在日常工作和项目中,PDF 文件处理是个常见需求,不论是合并报告、加密文档、填充表单,还是生成发票。Python 中有许多用于操作 PDF 文件的库,其中 PyPDF2 和 ReportLab 是两个广泛使用的工具:前者用于 PDF 文档的读取和修改,后者用于从头生成 PDF 文件。在这篇博客中,我们将介绍如何使用 PyPDF2 和 ReportLab 完成一些常见的 PDF 处理任务。
要开始使用 PyPDF2 和 ReportLab,首先需要安装它们。可以在终端或命令提示符中执行以下命令:
pip install PyPDF2 reportlab
安装完成后,即可使用它们进行 PDF 的读写和生成操作。
PyPDF2 是一个强大的 PDF 处理库,它提供了多种功能,可以让我们读取、合并、拆分、加密和解密 PDF 文件。以下是 PyPDF2 的一些常见操作。
首先,让我们看看如何用 PyPDF2 打开并读取 PDF 文件的内容。
from PyPDF2 import PdfReader
# 打开 PDF 文件
reader = PdfReader("example.pdf")
# 获取页面数
num_pages = len(reader.pages)
print(f"Total pages: {num_pages}")
# 读取每一页的内容
for page_num in range(num_pages):
page = reader.pages[page_num]
text = page.extract_text()
print(f"Page {page_num + 1}:\n{text}")
在这个例子中,我们使用 PdfReader
类打开 PDF 文件,并通过 extract_text()
方法提取每一页的文本内容。这种方式适合从 PDF 中读取纯文本内容,比如报告和文档。
合并多个 PDF 文件是 PyPDF2 的强项之一。以下是将两个 PDF 文件合并成一个 PDF 文件的示例:
from PyPDF2 import PdfWriter, PdfReader
# 创建 PDF 写入器
writer = PdfWriter()
# 读取两个 PDF 文件并将它们的页面添加到写入器中
pdf_files = ["file1.pdf", "file2.pdf"]
for pdf_file in pdf_files:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
# 保存合并后的 PDF 文件
with open("merged_output.pdf", "wb") as output_pdf:
writer.write(output_pdf)
在这个示例中,我们创建了一个 PdfWriter
实例,依次读取每个 PDF 文件,并将其页面添加到写入器中。最终,合并后的 PDF 文件会保存为 merged_output.pdf
。
如果需要将 PDF 文件中的某些页面提取出来,也可以通过 PyPDF2 实现。例如,提取 PDF 文件中的第 1 页到第 3 页:
from PyPDF2 import PdfWriter, PdfReader
reader = PdfReader("example.pdf")
writer = PdfWriter()
# 提取特定页
for i in range(3): # 这里表示提取第1页到第3页
writer.add_page(reader.pages[i])
# 保存拆分后的文件
with open("split_output.pdf", "wb") as output_pdf:
writer.write(output_pdf)
此代码将 example.pdf
的前 3 页提取并保存为 split_output.pdf
。
对于机密文件,PyPDF2 提供了加密和解密功能。我们可以使用 encrypt
方法设置密码保护 PDF 文件:
writer = PdfWriter()
reader = PdfReader("example.pdf")
# 添加所有页面
for page in reader.pages:
writer.add_page(page)
# 加密并设置密码
writer.encrypt("password123")
# 保存加密的文件
with open("encrypted_output.pdf", "wb") as output_pdf:
writer.write(output_pdf)
在这个例子中,encrypted_output.pdf
文件只能通过密码“password123”打开,确保了文件的安全性。
ReportLab 是另一个强大的 PDF 库,适合从头生成 PDF 文件,并支持复杂的布局和样式。ReportLab 使用 画布(Canvas)进行 PDF 内容的绘制,可以生成包含文本、图形和表格的 PDF 文件。
首先,让我们看如何使用 ReportLab 创建一个简单的 PDF 文件并添加文本:
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
# 创建 PDF 文件
pdf_path = "generated_example.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)
# 添加文本
pdf_canvas.drawString(100, 750, "Hello, ReportLab!")
pdf_canvas.drawString(100, 730, "This is a simple PDF file created using Python.")
# 保存并关闭 PDF
pdf_canvas.save()
print(f"PDF saved as {pdf_path}")
在此代码中,drawString
方法可以指定文本位置,单位为点(pt),A4 页面的尺寸是 595x842 pt。在 100, 750
位置写入文本 “Hello, ReportLab!”。
ReportLab 允许将图片插入到 PDF 中,并能绘制各种形状,这对于生成图表或带有图像的报告非常有用。
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
# 创建 PDF 文件
pdf_path = "pdf_with_image.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)
# 添加图片
pdf_canvas.drawImage("example_image.jpg", 100, 500, width=200, height=150)
# 绘制矩形
pdf_canvas.setStrokeColorRGB(0, 0, 1) # 蓝色边框
pdf_canvas.setFillColorRGB(0.8, 0.8, 1) # 浅蓝填充
pdf_canvas.rect(100, 450, 200, 100, fill=True)
# 保存 PDF
pdf_canvas.save()
print(f"PDF with image and shapes saved as {pdf_path}")
在这里,我们插入了一张图片,并绘制了一个蓝色矩形,位置在 (100, 450)
,尺寸为 200x100
。drawImage
方法可以用来插入图像文件,支持 JPG 和 PNG 格式。
ReportLab 的 Table
类可以方便地创建和格式化表格。以下示例展示了如何在 PDF 中插入一个包含数据的表格:
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
# 创建 PDF 文件
pdf_path = "pdf_with_table.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)
# 表格数据
data = [
["Product", "Price", "Quantity"],
["Widget", "$25.00", "10"],
["Gadget", "$15.00", "30"],
["Doohickey", "$5.00", "50"]
]
# 创建表格
table = Table(data)
table.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
("ALIGN", (0, 0), (-1, -1), "CENTER"),
("GRID", (0, 0), (-1, -1), 0.5, colors.black),
("BACKGROUND", (0, 1), (-1, -1), colors.beige),
]))
# 将表格添加到 PDF
table.wrapOn(pdf_canvas, 400, 300)
table.drawOn(pdf_canvas, 100, 600)
# 保存 PDF
pdf_canvas.save()
print(f"PDF with table saved as {pdf_path}")
在此代码中,我们创建了一个包含产品、价格和数量信息的表格,并设置了样式,包括背景颜色、对齐方式和边框线。
PyPDF2 和 ReportLab 是处理 PDF 文件的两大主要工具,各有其强项:
这两个库的结合可以帮助我们实现全面的 PDF 处理需求,从简单的文件合并到复杂的图表和表格创建,Python 都能轻松完成。希望这篇指南能帮您更好地掌握这两个库的使用方法,实现 PDF 的自动化处理。
在这里,我们将 PyPDF2 和 ReportLab 结合使用,生成一个包含公司信息、客户信息和项目列表的发票 PDF。这种场景在实际应用中非常常见。
首先,我们使用 ReportLab 创建一个发票模板文件 invoice_template.pdf
,包括公司标志、发票标题和必要的表格格式:
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
def create_invoice_template():
pdf_path = "invoice_template.pdf"
pdf_canvas = canvas.Canvas(pdf_path, pagesize=A4)
# 设置页面标题
pdf_canvas.setFont("Helvetica-Bold", 16)
pdf_canvas.drawString(220, 800, "Invoice")
# 公司信息
pdf_canvas.setFont("Helvetica", 12)
pdf_canvas.drawString(50, 780, "Company Name: XYZ Ltd.")
pdf_canvas.drawString(50, 765, "Address: 123 Example St., City")
pdf_canvas.drawString(50, 750, "Phone: (123) 456-7890")
pdf_canvas.drawString(50, 735, "Email: [email protected]")
# 客户信息部分
pdf_canvas.drawString(50, 700, "Bill To:")
pdf_canvas.drawString(50, 685, "Customer Name:")
pdf_canvas.drawString(50, 670, "Customer Address:")
# 添加表格表头
data = [["Item", "Description", "Quantity", "Unit Price", "Total"]]
table = Table(data)
table.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, 0), colors.grey),
("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke),
("ALIGN", (0, 0), (-1, -1), "CENTER"),
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
("FONTSIZE", (0, 0), (-1, 0), 12),
("BOTTOMPADDING", (0, 0), (-1, 0), 12),
("GRID", (0, 0), (-1, -1), 0.5, colors.black),
]))
table.wrapOn(pdf_canvas, 450, 400)
table.drawOn(pdf_canvas, 50, 600)
# 保存模板
pdf_canvas.save()
print(f"Invoice template saved as {pdf_path}")
# 生成模板
create_invoice_template()
在这个代码中,我们设置了发票的基本结构,包括公司和客户信息的显示位置,以及一张带有标题的表格,用于填写产品或服务明细。
接下来,我们用 PyPDF2 在生成的模板上填写客户信息和项目详情。我们将客户信息和项目列表写入 invoice_filled.pdf
文件。
from PyPDF2 import PdfReader, PdfWriter
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from io import BytesIO
def fill_invoice(customer_name, customer_address, items):
# 打开模板
reader = PdfReader("invoice_template.pdf")
writer = PdfWriter()
# 创建一个内存缓冲区来绘制覆盖内容
packet = BytesIO()
pdf_canvas = canvas.Canvas(packet, pagesize=A4)
# 填写客户信息
pdf_canvas.setFont("Helvetica", 12)
pdf_canvas.drawString(150, 685, customer_name)
pdf_canvas.drawString(150, 670, customer_address)
# 填写项目明细
y = 580
for item in items:
pdf_canvas.drawString(50, y, item["item"])
pdf_canvas.drawString(150, y, item["description"])
pdf_canvas.drawString(250, y, str(item["quantity"]))
pdf_canvas.drawString(350, y, f"${item['unit_price']:.2f}")
pdf_canvas.drawString(450, y, f"${item['quantity'] * item['unit_price']:.2f}")
y -= 20 # 调整 y 坐标,确保每一项在新行
# 保存绘制的内容
pdf_canvas.save()
# 将覆盖内容作为新页面内容合并
packet.seek(0)
overlay = PdfReader(packet)
for page in reader.pages:
page.merge_page(overlay.pages[0])
writer.add_page(page)
# 保存带内容的发票
with open("invoice_filled.pdf", "wb") as output_pdf:
writer.write(output_pdf)
print("Invoice filled and saved as invoice_filled.pdf")
# 示例数据
customer_name = "John Doe"
customer_address = "456 Example Ave., City"
items = [
{"item": "Widget", "description": "High-quality widget", "quantity": 5, "unit_price": 20.00},
{"item": "Gadget", "description": "Advanced gadget", "quantity": 3, "unit_price": 35.00},
{"item": "Doohickey", "description": "Multi-purpose tool", "quantity": 2, "unit_price": 15.50},
]
# 生成发票
fill_invoice(customer_name, customer_address, items)
在这个代码中,我们使用 fill_invoice
函数将客户信息和项目明细填充到 invoice_template.pdf
的模板中,并将其保存为 invoice_filled.pdf
。每个项目明细按行填写,包括产品名称、描述、数量、单价和总价。
在本教程中,我们学习了如何使用 PyPDF2 和 ReportLab 来处理 PDF 文件,从读取和合并现有文件,到从头生成和填充内容的自定义发票。这些技术为日常工作中的 PDF 操作带来了高效的解决方案,使自动化 PDF 处理成为可能。
借助 PyPDF2 和 ReportLab,您可以轻松创建自动化脚本生成 PDF 报告,处理包含敏感数据的加密文件,或构建批量文件处理系统。希望通过这篇博客,您能够灵活运用这两个库,提高 PDF 文件处理的效率。