Python使用PyPDF2和ReportLab操作PDF文件的详细指南

 更新时间:2025年01月03日 10:05:38   作者:萧鼎  
在日常工作和项目中,PDF 文件处理是个常见需求,不论是合并报告、加密文档、填充表单,还是生成发票,Python 中有许多用于操作 PDF 文件的库,其中 PyPDF2 和 ReportLab 是两个广泛使用的工具,本文给大家介绍了Python使用PyPDF2和ReportLab操作PDF文件的详细指南

Python中的PDF处理工具:PyPDF2和ReportLab使用指南

在日常工作和项目中,PDF 文件处理是个常见需求,不论是合并报告、加密文档、填充表单,还是生成发票。Python 中有许多用于操作 PDF 文件的库,其中 PyPDF2 和 ReportLab 是两个广泛使用的工具:前者用于 PDF 文档的读取和修改,后者用于从头生成 PDF 文件。在这篇博客中,我们将介绍如何使用 PyPDF2 和 ReportLab 完成一些常见的 PDF 处理任务。

一、安装 PyPDF2 和 ReportLab

要开始使用 PyPDF2 和 ReportLab,首先需要安装它们。可以在终端或命令提示符中执行以下命令:

pip install PyPDF2 reportlab

安装完成后,即可使用它们进行 PDF 的读写和生成操作。

二、使用 PyPDF2 操作 PDF 文件

PyPDF2 是一个强大的 PDF 处理库,它提供了多种功能,可以让我们读取、合并、拆分、加密和解密 PDF 文件。以下是 PyPDF2 的一些常见操作。

1. 读取 PDF 文件

首先,让我们看看如何用 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 中读取纯文本内容,比如报告和文档。

2. 合并 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

3. 拆分 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

4. 加密和解密 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 文件

ReportLab 是另一个强大的 PDF 库,适合从头生成 PDF 文件,并支持复杂的布局和样式。ReportLab 使用 画布(Canvas)进行 PDF 内容的绘制,可以生成包含文本、图形和表格的 PDF 文件。

1. 创建 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!”。

2. 添加图片和图形

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 格式。

3. 添加表格

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 文件的两大主要工具,各有其强项:

  • PyPDF2:适用于读取、合并、拆分和加密 PDF 文件,主要用于处理现有的 PDF 文件。
  • ReportLab:用于从头生成 PDF 文件,可以精确控制布局,适合创建发票、报表和其他定制文档。

这两个库的结合可以帮助我们实现全面的 PDF 处理需求,从简单的文件合并到复杂的图表和表格创建,Python 都能轻松完成。希望这篇指南能帮您更好地掌握这两个库的使用方法,实现 PDF 的自动化处理。

五、综合应用:生成发票 PDF 示例

在这里,我们将 PyPDF2 和 ReportLab 结合使用,生成一个包含公司信息、客户信息和项目列表的发票 PDF。这种场景在实际应用中非常常见。

1. 创建发票模板

首先,我们使用 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: contact@xyz.com")

    # 客户信息部分
    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()

在这个代码中,我们设置了发票的基本结构,包括公司和客户信息的显示位置,以及一张带有标题的表格,用于填写产品或服务明细。

2. 使用 PyPDF2 填写客户信息和项目详情

接下来,我们用 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 文件处理的效率。

以上就是Python使用PyPDF2和ReportLab操作PDF文件的详细指南的详细内容,更多关于Python PyPDF2和ReportLab使用的资料请关注脚本之家其它相关文章!

相关文章

  • numba CUDA报错的问题解决

    numba CUDA报错的问题解决

    本文主要介绍了numba CUDA报错的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Python 实现定积分与二重定积分的操作

    Python 实现定积分与二重定积分的操作

    这篇文章主要介绍了Python 实现定积分与二重定积分的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05
  • 利用Python制作动态排名图的实现代码

    利用Python制作动态排名图的实现代码

    这篇文章主要介绍了利用Python制作动态排名图的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 基于Python爬取京东双十一商品价格曲线

    基于Python爬取京东双十一商品价格曲线

    这篇文章主要介绍了基于Python爬取双十一商品价格曲线,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • python实现从本地摄像头和网络摄像头截取图片功能

    python实现从本地摄像头和网络摄像头截取图片功能

    这篇文章主要介绍了python实现从本地摄像头和网络摄像头截取图片功能 ,文中给大家提到了python , opencv 打开网络摄像头读取图像的实现代码,需要的朋友可以参考下
    2019-07-07
  • Python 文件处理之open()函数

    Python 文件处理之open()函数

    这篇文章主要介绍了Python 文件处理之open()函数,在 Python 中使用文件的关键函数是 open() 函数,关于其打开文件的不同方式需要的小伙伴可以参考下面详细介绍
    2022-03-03
  • python连接数据库后通过占位符添加数据

    python连接数据库后通过占位符添加数据

    在pymysql中支持对占位符的处理,开发者需要在SQL中使用“%”定义占位符,在使用excute()方法执行时对占位符的数据进行填充即可,本文给大家介绍python连接数据库后通过占位符添加数据的方法,需要的朋友参考下吧
    2021-12-12
  • python pandas利用fillna方法实现部分自动填充功能

    python pandas利用fillna方法实现部分自动填充功能

    这篇文章主要介绍了python pandas通过fillna方法实现部分自动填充功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 使用Python中的Argparse实现将列表作为命令行参数传递

    使用Python中的Argparse实现将列表作为命令行参数传递

    Argparse 是一个 Python 库,用于以用户友好的方式解析命令行参数,本文我们将讨论如何使用 Python 中的 Argparse 库将列表作为命令行参数传递,感兴趣的可以了解下
    2023-08-08
  • Python中的字典遍历备忘

    Python中的字典遍历备忘

    这篇文章主要介绍了Python中的字典遍历备忘,本文列举了多种字典遍历方法,适合初学者查看,并简单讲解了interitems和iterms区别,需要的朋友可以参考下
    2015-01-01

最新评论