PyPDF2裁剪生成新PDF后调用lpr打印仍输出原内容如何解决
问题成因
- 核心原因是PDF规范中定义了多组页面边界属性:
mediabox是页面的物理全尺寸边界,是所有渲染引擎识别页面范围的基础属性;cropbox仅为PDF阅读器预览时默认使用的裁剪边界,绝大多数打印渲染栈(包括lpr调用的CUPS、Ghostscript/Poppler后端)打印时会直接读取mediabox渲染全页内容,忽略cropbox设置。你仅修改了cropbox,所以打开PDF预览能看到裁剪效果,打印时仍输出原始全页内容。 - 其次是PyPDF2版本兼容问题:部分旧版本PyPDF2中
page.rotate()方法不会原地修改页面旋转属性,直接修改从PdfReader取出的原始页对象属性时,也可能因为对象引用机制导致部分属性未被正确写入新生成的PDF。 - 额外隐患:你调用lpr的命令中没有给文件路径加引号,如果路径或文件名包含空格,会导致lpr读取目标文件失败,存在打印错文件的风险。
修复方案
- 裁剪页面时同步修改
mediabox、cropbox、trimbox等所有页面边界属性,从根源上让所有渲染/打印引擎识别到正确的裁剪后页面范围 - 直接通过
page.rotation属性设置旋转角度,避免rotate()方法的版本兼容问题 - lpr命令中给文件路径加引号,兼容带空格的路径场景
修复后的完整代码如下:
import os from PyPDF2 import PdfReader, PdfWriter order_number = entry1.get() final = order_number.upper() edit = PdfReader(f"{pathfile}{order_number} - Shipping Label.pdf") output = PdfWriter() # 处理第一页 page = edit.pages[0] # 定义裁剪坐标 x0, y0 = 63.389830508474574, 643.7972508591065 x1, y1 = 561.8644067796611, 483.2096219931271 # 同步更新所有页面边界,兼容所有渲染引擎 for box in [page.mediabox, page.cropbox, page.trimbox, page.artbox, page.bleedbox]: box.upper_left = (x0, y0) box.lower_right = (x1, y1) page.rotation = 90 output.add_page(page) # 处理第二页 page = edit.pages[1] x0, y0 = 32.45454545454545, 545.4601542416452 x1, y1 = 556.7757575757576, 238.09768637532136 for box in [page.mediabox, page.cropbox, page.trimbox, page.artbox, page.bleedbox]: box.upper_left = (x0, y0) box.lower_right = (x1, y1) page.rotation = 90 output.add_page(page) output_path = f"{pathfile}{final}.pdf" with open(output_path, "wb") as fp: output.write(fp) # 路径加引号,兼容空格场景 os.system(f'lpr -P Munbyn_Printer_1 "{output_path}"')
修复后可以先查看生成PDF的页面属性,确认页面尺寸为裁剪后的尺寸,此时打印就会输出裁剪后的内容。
内容的提问来源于stack exchange,提问作者Ruibin Wu
相关产品推荐
相关产品推荐

