如何使用PyPDF2按页拆分PDF并让拆分后单页文件体积更小?
核心原因
拆分后单页体积接近原文件,本质是PyPDF2默认会将原PDF的全量共享资源(嵌入字体、公共图片、元数据、表单资源等)全部复制到每个输出文件,哪怕当前页面完全没用到这些资源。remove_links()仅能删除链接注解,完全不涉及占体积90%以上的共享资源,因此没有缩减效果。
可行方案
方案1:PyPDF2原生优化(无需额外依赖,效果一般)
PyPDF2 2.0+版本提供了冗余对象清理和内容流压缩接口,可在原有代码基础上修改,能清理大部分无用资源:
from PyPDF2 import PdfReader, PdfWriter def save_pdf_page(file_name, page_index): reader = PdfReader(file_name) writer = PdfWriter() writer.add_page(reader.pages[page_index]) # 压缩页面内容流 writer.compress_content_streams() # 最高等级清理无引用的冗余资源 writer.remove_unreferenced_objects() with open(f"output_page{page_index}.pdf", "wb") as fh: writer.write(fh)
该方案对嵌套引用的资源识别准确率有限,最终体积通常比理论值大20%~50%,适合不想额外安装第三方库的场景。
方案2:PyMuPDF拆分(体积控制最优,推荐)
PyMuPDF(导入名为fitz)拆分PDF时默认仅复制当前页实际依赖的资源,配合内置的最高等级压缩参数,输出文件基本无冗余,体积接近理论最小值。
首先安装依赖:pip install pymupdf
实现代码:
import fitz def save_pdf_page(file_name, page_index): source_doc = fitz.open(file_name) target_doc = fitz.open() # 仅插入指定页,自动关联必要资源 target_doc.insert_pdf(source_doc, from_page=page_index, to_page=page_index) # 最高等级冗余清理+全量压缩 target_doc.save( f"output_page{page_index}.pdf", garbage=4, deflate=True, deflate_images=True, deflate_fonts=True ) target_doc.close() source_doc.close()
常规场景下该方案输出的单页体积约为原文件的1/N(N为原PDF总页数),比优化后的PyPDF2输出体积小30%~70%,且不会出现文件损坏、内容丢失的问题。
注意事项
- 若个别单页拆分后体积仍偏大,优先检查该页是否本身嵌入了高分辨率图片、完整字体集,属于正常情况
- 不建议通过修改PyPDF2私有方法的方式裁剪资源,版本迭代后极易失效,还可能导致输出PDF无法打开
- 压缩时不要盲目调低图片质量,避免出现文字模糊、打印失真问题
内容的提问来源于stack exchange,提问作者Yaron Gertel
相关产品推荐
相关产品推荐

