如何用pypdf或纯Python包将多PDF页面按指定网格合并为单页?
纯Python实现多PDF页面单页网格排列方案
完全可以用纯Python包实现这个需求,pypdf负责读取各个PDF的页面内容,搭配ReportLab来完成网格布局的绘制和最终单页PDF的生成,这两个都是纯Python工具,不需要依赖外部软件。
核心实现思路
- 先读取所有目标PDF的页面,统一获取源页面的尺寸(因为所有页面尺寸一致,取第一个页面的尺寸即可)。
- 确定网格规则:固定10列,行数等于你的PDF文件数量n,以此计算出最终单页PDF的总宽度和总高度。
- 创建一个空白的大尺寸画布,按行遍历每个PDF,每行放置该PDF的10页,逐个计算每个页面在画布上的坐标并绘制上去。
- 最后保存成
summary.pdf。
可运行示例代码
from pypdf import PdfReader from reportlab.pdfgen import canvas from reportlab.pdfbase import pdfutils def generate_summary_pdf(pdf_file_list, output_name="summary.pdf"): # 获取源页面的尺寸(以第一个PDF的第一页为准) first_pdf_reader = PdfReader(pdf_file_list[0]) sample_page = first_pdf_reader.pages[0] page_width = float(sample_page.mediabox.width) page_height = float(sample_page.mediabox.height) # 网格配置:10列,行数等于PDF文件数量 cols = 10 rows = len(pdf_file_list) # 计算最终单页的尺寸 total_width = page_width * cols total_height = page_height * rows # 创建画布 summary_canvas = canvas.Canvas(output_name, pagesize=(total_width, total_height)) # 遍历每个PDF,按行绘制页面 for row_num, pdf_path in enumerate(pdf_file_list): pdf_reader = PdfReader(pdf_path) # 校验页面数量,确保每个PDF都是10页 if len(pdf_reader.pages) != 10: raise ValueError(f"{pdf_path} 的页面数量不是10页,请检查文件") for col_num in range(cols): current_page = pdf_reader.pages[col_num] # 将PDF页面转为可绘制的图像对象 page_image = pdfutils.PDFImage(current_page) # 计算绘制坐标:ReportLab原点在画布左下角,所以需要从下往上算行的位置 draw_x = col_num * page_width draw_y = total_height - (row_num + 1) * page_height # 绘制页面到对应位置 page_image.drawOn(summary_canvas, draw_x, draw_y, width=page_width, height=page_height) # 保存最终PDF summary_canvas.save() # 使用示例:替换成你的PDF文件列表 if __name__ == "__main__": my_pdfs = [f"{i}.pdf" for i in range(1, 5)] # 示例包含1-4.pdf generate_summary_pdf(my_pdfs)
注意事项
- 确保所有源PDF的页面尺寸完全一致,不然会出现布局错位的问题。
- 先安装依赖包:执行
pip install pypdf reportlab即可。 - 如果源页面是横向排版,只需确认
page_width和page_height的对应关系即可,代码逻辑不需要大改。
内容的提问来源于stack exchange,提问作者Tom M. Ragonneau
相关产品推荐
相关产品推荐

