如何用Python将PDF多页合并为单张纵向拼接页面?
解决pdfrw/pypdf合并PDF页面堆叠而非纵向拼接的问题
问题原因
使用PageMerge.add()时,默认会将所有页面放置在坐标(0, 0)位置,导致页面相互重叠堆叠,而非纵向排列。
pdfrw 解决方案
需要手动计算每个页面的纵向偏移量,将后续页面依次放置在前一页的下方。核心是获取页面高度,累加计算每个页面的起始Y坐标:
from pdfrw import PdfReader, PdfWriter, PageMerge def merge_pdf_pages(input_file='input.pdf'): reader = PdfReader(input_file) writer = PdfWriter() pages = PageMerge() current_y = 0 # 初始Y坐标,从顶部开始(PDF坐标原点在左下角) for page in reader.pages: # 获取当前页面的实际高度 page_height = float(page.MediaBox[3]) - float(page.MediaBox[1]) # 将页面放置在指定Y坐标(current_y为页面底部的位置) pages.add(page, y=current_y) # 更新Y坐标,让下一页底部对齐当前页的顶部 current_y += page_height # 渲染合并页面,并设置总高度为所有页面高度之和 merged_page = pages.render() merged_page.MediaBox[3] = current_y writer.addpage(merged_page) with open("output.pdf",'wb') as file: writer.write(file) # 调用示例 merge_pdf_pages('input.pdf')
关键说明
- PDF坐标系统原点在左下角,所以通过累加页面高度,能让页面从上到下依次衔接。
- 渲染后必须手动设置合并页面的
MediaBox高度,否则输出PDF可能无法完整显示所有内容。
pypdf 类似实现思路
pypdf的merge_page()默认也是重叠逻辑,要实现纵向拼接需用相同的坐标计算思路:
- 创建一个高度等于所有页面总高度的空白容器页面。
- 依次将每个页面叠加到容器的对应Y坐标位置。
示例代码:
from pypdf import PdfReader, PdfWriter, PageObject def merge_pdf_pages_pypdf(input_file='input.pdf'): reader = PdfReader(input_file) writer = PdfWriter() # 计算所有页面的总高度 total_height = sum(float(page.mediabox.height) for page in reader.pages) # 创建空白容器,宽度取第一页的宽度,高度为总高度 container = PageObject.create_blank_page( width=float(reader.pages[0].mediabox.width), height=total_height ) current_y = total_height # 容器顶部的Y坐标 for page in reader.pages: page_height = float(page.mediabox.height) current_y -= page_height # 计算当前页面顶部的Y坐标 # 将页面合并到容器的指定位置 container.merge_translated_page(page, 0, current_y) writer.add_page(container) with open("output_pypdf.pdf", 'wb') as f: writer.write(f)
内容的提问来源于stack exchange,提问作者V Falcon
相关产品推荐
相关产品推荐

