您的位置:

Python PDF 全方位解析

一、PDF 文件的常见操作

现在,PDF 文件已经成为了文档交换和共享的主要文档格式,它一般用来保存排版比较复杂的文档,比如报告、期刊、合同等。在 Python 中,我们可以使用 PyPDF2 来操作 PDF 文件,比如读取、写入、拆分、合并、加密、解密等。下面,我们将对这些常见的操作进行介绍。

1、读取 PDF 文件

import PyPDF2

pdfFileObj = open('example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
print("总页数:", pdfReader.numPages)

for page in range(pdfReader.numPages):
    pageObj = pdfReader.getPage(page)
    print(pageObj.extractText())
pdfFileObj.close()

使用 PyPDF2 打开文件、读取页数、逐页读取并打印,这是读取 PDF 文件最基本的操作。

2、写入 PDF 文件

import PyPDF2

pdfFileObj = open('example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

pdfWriter = PyPDF2.PdfFileWriter()
for page in range(pdfReader.numPages):
    pdfWriter.addPage(pdfReader.getPage(page))

pdfOutFile = open('output.pdf', 'wb')
pdfWriter.write(pdfOutFile)

pdfFileObj.close()
pdfOutFile.close()

使用 PyPDF2 在 Python 中生成 PDF 文件,这个过程非常简单。首先,我们打开原有的 PDF 文件,并以只读模式读取其中的内容。然后,我们创建一个新的 PDF 文件,并以写入模式写入读取的内容,最后关闭两个文件即可得到一个新的 PDF 文件。

3、拆分 PDF 文件

import PyPDF2

pdfFileObj = open('example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

pdfWriter = PyPDF2.PdfFileWriter()
for page in range(pdfReader.numPages):
    pdfWriter.addPage(pdfReader.getPage(page))
    if page % 5 == 0:
        filename = 'split_%s.pdf' % (page // 5)
        pdfOutFile = open(filename, 'wb')
        pdfWriter.write(pdfOutFile)
        pdfWriter = PyPDF2.PdfFileWriter()
        pdfOutFile.close()

if pdfWriter.getNumPages() > 0:
    filename = 'split_%s.pdf' % ((page // 5) + 1)
    pdfOutFile = open(filename, 'wb')
    pdfWriter.write(pdfOutFile)
    pdfOutFile.close()

pdfFileObj.close()

使用 PyPDF2 对 PDF 文件进行拆分,这个过程比较繁琐。我们可以遍历读取的 PDF 文件,每 5 页拆分为一个新的 PDF 文件。在拆分时,我们需要注意最后一页不足 5 页不需要拆分,而拆分后的文件名需要按照序列递增命名。

4、合并 PDF 文件

import PyPDF2

pdfOutFile = open('merged.pdf', 'wb')
pdfWriter = PyPDF2.PdfFileWriter()

for filename in ['example1.pdf', 'example2.pdf', 'example3.pdf']:
    pdfFileObj = open(filename, 'rb')
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
    for page in range(pdfReader.numPages):
        pdfWriter.addPage(pdfReader.getPage(page))
    pdfFileObj.close()

pdfWriter.write(pdfOutFile)
pdfOutFile.close()

使用 PyPDF2 合并多个 PDF 文件,这个过程比较简单。我们只需要遍历需要合并的 PDF 文件,将其每一页逐个加入到新的 PDF 文件中即可。需要注意的是,生成的新文件必须以写入模式打开。

5、加密 PDF 文件

import PyPDF2
pdfWriter = PyPDF2.PdfFileWriter()
pdfWriter.encrypt("password")
pdfFileObj = open('example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
for page in range(pdfReader.numPages):
    pdfWriter.addPage(pdfReader.getPage(page))
pdfOutFile = open('encrypted.pdf', 'wb')
pdfWriter.write(pdfOutFile)
pdfFileObj.close()
pdfOutFile.close()

使用 PyPDF2 对 PDF 文件进行加密,这个过程非常简单。我们只需要在创建 PDFWriter 对象时,调用 encrypt 方法并传入密码即可。需要注意的是,加密后的文件只能在输入正确的密码后才能打开。

二、PDF 文件的高级操作

1、PDF 文件的裁剪、旋转和缩放

import PyPDF2

pdfFileObj = open('example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)

pdfWriter = PyPDF2.PdfFileWriter()
for page in range(pdfReader.numPages):
    pageObj = pdfReader.getPage(page)
    pageObj.mediaBox.lowerLeft = (pageObj.mediaBox.getLowerLeft_x() + 200, pageObj.mediaBox.getLowerLeft_y() + 200)
    pageObj.mediaBox.upperRight = (pageObj.mediaBox.getUpperRight_x() - 200, pageObj.mediaBox.getUpperRight_y() - 200)
    pageObj.rotateClockwise(90)
    pageObj.scale(0.8, 0.8)
    pdfWriter.addPage(pageObj)

pdfOutFile = open('output.pdf', 'wb')
pdfWriter.write(pdfOutFile)

pdfFileObj.close()
pdfOutFile.close()

使用 PyPDF2 对 PDF 文件进行裁剪、旋转和缩放,这些高级操作需要对 PDF 文件的页面对象进行比较深入的处理。比如,我们可以通过获取页面的 mediaBox 属性来对其进行裁剪,并通过 rotateClockwise 和 scale 方法对其进行旋转和缩放。

2、PDF 文件的文本处理和样式设置

import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from PyPDF2 import PdfFileReader, PdfFileWriter
from reportlab.lib import colors
from reportlab.lib.units import inch

buffer = io.BytesIO()
pdf = canvas.Canvas(buffer, pagesize=letter)

pdf.setFont('Helvetica-Bold', 14)
pdf.setFillColor(colors.red)
pdf.drawString(1 * inch, 10.5 * inch, "Hello World")
pdf.showPage()
pdf.save()

buffer.seek(0)
new_pdf = PdfFileReader(buffer)
existing_pdf = PdfFileReader(open("example.pdf", "rb"))
output = PdfFileWriter()

for page in range(existing_pdf.getNumPages()):
    input_page = existing_pdf.getPage(page)
    watermark = new_pdf.getPage(0)
    input_page.mergePage(watermark)
    output.addPage(input_page)

outputStream = open("output.pdf", "wb")
output.write(outputStream)
outputStream.close()
buffer.close()

使用 ReportLab 先生成一个 PDF,并将其作为水印加入到原有 PDF 中,这个过程比较繁琐。我们可以先使用 ReportLab 生成指定文本、字体、颜色和位置的 PDF(这部分比较难控制)。然后,使用 PyPDF2 进行 PDF 文件的合并,将新生成的 PDF 文件作为水印加入到原有 PDF 文件中。

3、PDF 文件的表单操作

import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from PyPDF2 import PdfFileReader, PdfFileWriter
from reportlab.lib import colors
from reportlab.lib.units import inch

buffer = io.BytesIO()
pdf = canvas.Canvas(buffer, pagesize=letter)

pdf.setFont('Helvetica', 10)
pdf.drawCentredString(300, 77, "姓名:")
pdf.drawCentredString(450, 77, "李四")
pdf.line(80, 65, 500, 65)

pdf.showPage()
pdf.save()

buffer.seek(0)
new_pdf = PdfFileReader(buffer)
existing_pdf = PdfFileReader(open("example.pdf", "rb"))
output = PdfFileWriter()

for page in range(existing_pdf.getNumPages()):
    input_page = existing_pdf.getPage(page)
    input_page.mergePage(new_pdf.getPage(0))
    output.addPage(input_page)

outputStream = open("output.pdf", "wb")
output.write(outputStream)
outputStream.close()
buffer.close()

使用 ReportLab 生成表单,这个过程比较繁琐。我们可以先计算好表单中各个字段的位置,然后使用 drawCentredString、line 等方法将这些字段画出来,并设置好属性(字体、颜色、位置等)。最后,使用 PyPDF2 进行 PDF 文件的合并,将新生成的 PDF 文件作为表单加入到原有 PDF 文件中。