如何用pdfplumber裁剪PDF每页后保存为单个PDF文件?
处理多页PDF裁剪并合并保存的问题
我需要处理一个多页PDF文件,每页顶部都有一个需移除的表格,目标是裁剪表格下方的页面内容,并将所有裁剪后的页面合并保存为单个PDF。
已尝试的方法及问题
初始尝试:用pdfplumber定位并裁剪页面
使用pdfplumber找到每页顶部表格的位置并裁剪,但无法保存合并后的PDF:
import pandas as pd import pdfplumber path = r"file-tests.pdf" with pdfplumber.open(path) as pdf: pages = pdf.pages # 遍历每页 for p in pages: print(p) # 获取表格的bbox(x0,y0,x1,y1)格式 bbox_vals = p.find_tables()[0].bbox # 取表格的y1值作为裁剪起始点,保留表格下方内容 y0_top_table = bbox_vals[3] print(y0_top_table) # 裁剪页面:从左到右,从表格底部到页面底部 p.crop((0, y0_top_table, 590, 840))
输出结果:
<Page:1> 269.64727650000003 <Page:2> 269.64727650000003 ...(省略重复内容) <Page:20> 269.64727650000003
更新1:pdfplumber不支持PDF写入
pdfplumber仅提供PDF读取和解析功能,本身不支持将修改后的页面保存为PDF文件。
更新2:尝试用pdfrw保存失败
尝试使用pdfrw的PdfWriter添加裁剪后的页面,但因类型不兼容报错:
from pdfrw import PdfWriter output_pdf = PdfWriter() with pdfplumber.open(path) as pdf: pages = pdf.pages for p in pages: print(p) bbox_vals = p.find_tables()[0].bbox y0_top_table = bbox_vals[3] print(y0_top_table) cropped_pdf = p.crop((0, y0_top_table, 590, 840)) print(type(cropped_pdf)) output_pdf.addpage(cropped_pdf) output_pdf.write(r"tests_cropped_file.pdf")
报错信息:
<Page:1> 269.64727650000003 <class 'pdfplumber.page.CroppedPage'> --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[219], line 13 11 cropped_pdf = p.crop((0, y0_top_table, 590, 840)) 12 print(type(cropped_pdf)) ---> 13 output_pdf.addpage(cropped_pdf) File c:\Users\vinee\anaconda3\envs\llma_py_3_12\Lib\site-packages\pdfrw\pdfwriter.py:270, in PdfWriter.addpage(self, page) 268 def addpage(self, page): 269 self._trailer = None --> 270 if page.Type != PdfName.Page: 271 raise PdfOutputError('Bad /Type: Expected %s, found %s' 272 % (PdfName.Page, page.Type)) 273 inheritable = page.inheritable # searches for resources AttributeError: 'CroppedPage' object has no attribute 'Type'
更新3:官方无直接解决方案
该裁剪后保存PDF的问题早在2018年就被提出,但pdfplumber官方至今未提供直接的写入支持。
可行解决方案
通过pdfplumber定位裁剪位置 + PyPDF2处理页面裁剪与保存的组合方式实现需求:
步骤1:安装依赖
pip install pdfplumber PyPDF2
步骤2:完整代码
import pdfplumber from PyPDF2 import PdfReader, PdfWriter input_path = "file-tests.pdf" output_path = "tests_cropped_file.pdf" # 第一步:用pdfplumber获取每页的裁剪起始y坐标 crop_ys = [] with pdfplumber.open(input_path) as pdf: for page in pdf.pages: # 获取每页第一个表格的bbox,取y1作为裁剪起始点 table_bbox = page.find_tables()[0].bbox crop_start_y = table_bbox[3] crop_ys.append(crop_start_y) # 第二步:用PyPDF2裁剪页面并合并保存 pdf_reader = PdfReader(input_path) pdf_writer = PdfWriter() for idx, page in enumerate(pdf_reader.pages): # 获取页面原始尺寸 original_mediabox = page.mediabox # 设置裁剪框:保留从裁剪起始y到页面底部的区域 page.cropbox.lower_left = (0, crop_ys[idx]) page.cropbox.upper_right = (original_mediabox.width, original_mediabox.height) # 将裁剪后的页面添加到输出PDF pdf_writer.add_page(page) # 保存最终PDF with open(output_path, "wb") as output_file: pdf_writer.write(output_file)
代码说明
- 先用pdfplumber遍历每页,定位顶部表格的底部位置(
bbox[3]即y1坐标),记录所有页面的裁剪起始点。 - 再用PyPDF2读取原PDF,遍历每页并设置
cropbox参数,实现页面裁剪。 - 最后将所有裁剪后的页面合并,保存为新的PDF文件。
内容的提问来源于stack exchange,提问作者ViSa
相关产品推荐
相关产品推荐

