在实际工作中,PDF 的页面尺寸往往决定了它能否顺利打印、归档或嵌入到其他系统里。比如,一份为 A3 设计的报表需要缩成 A4 分发,或者扫描件需要统一到某个自定义尺寸。手动逐页调整既耗时又容易出错,用 Python 脚本批量处理会是更稳妥的选择。
Free Spire.PDF for Python 是这个场景下轻量且够用的工具之一。它体积小,API 设计也比较直接,适合做页面级别的重构。下面从原理到代码,完整梳理一遍用它修改 PDF 页面尺寸的几种常见做法。
准备工作
只需要通过 pip 安装即可:
bash
pip install spire.pdf.free
免费版本对文档页数有一定限制(通常为 10 页以内),适合小规模处理或验证方案。
核心思路:为什么不能"直接改尺寸"?
PDF 的页面尺寸(MediaBox)虽然在规范层面是一个可修改的属性,但直接改动它会导致原本按旧尺寸排布的文字、图片发生错位甚至被裁剪。更可靠的做法是"另起炉灶":
- 加载原文档 ,逐页创建页面模板(Template),把该页的全部内容"快照"下来。
- 新建一个文档 ,按照目标尺寸创建空白页面。
- 把模板绘制到新页面上 ,通过控制绘制坐标和缩放布局,实现内容的适配。
- 保存新文档 ,释放资源。
Free Spire.PDF 的 PdfPageBase.CreateTemplate() 和 PdfTemplate.Draw() 正是为这个流程设计的。无论目标尺寸是变大、变小还是改变宽高比,都可以用同一套逻辑完成。
场景一:更改为标准纸张尺寸(A3、B4、Letter 等)
Free Spire.PDF 内置了常见的标准纸张枚举,如 PdfPageSize.A3()、PdfPageSize.B4()、PdfPageSize.Letter() 等。下面的代码把一份 PDF 的每一页都转换为 B4:
python
from spire.pdf.common import *
from spire.pdf import *
input_file = "source.pdf"
output_file = "resized_b4.pdf"
original_pdf = PdfDocument()
original_pdf.LoadFromFile(input_file)
new_pdf = PdfDocument()
for i in range(original_pdf.Pages.Count):
page = original_pdf.Pages.get_Item(i)
# 创建 B4 尺寸的新页面,边距设为 0,避免额外留白
new_page = new_pdf.Pages.Add(PdfPageSize.B4(), PdfMargins(0.0))
# 关键:将文本布局设为 OnePage,让原内容整体缩放到新页面内
layout = PdfTextLayout()
layout.Layout = PdfLayoutType.OnePage
template = page.CreateTemplate()
template.Draw(new_page, PointF.Empty(), layout)
`new_pdf.SaveToFile(output_file)`
`
new_pdf.Close()`
`
original_pdf.Close()`
`
`
这里的关键是 PdfLayoutType.OnePage。如果不设置这个布局,内容会按原始比例绘制,超出新页面尺寸的部分会被直接裁掉,而不是自动缩放。设置之后,模板会根据新页面的可用区域整体缩放,保证内容完整可见。
场景二:自定义尺寸(毫米、英寸等任意单位)
实际需求中,目标尺寸很少恰好是标准纸张。比如印刷品可能要求 200mm × 280mm,或者某个系统规定页面必须是 6 × 9 英寸。Free Spire.PDF 的度量单位是点(point) ,1 点 = 1/72 英寸。用 PdfUnitConvertor 可以先把物理单位转成点,再创建 SizeF:
python
from spire.pdf.common import *
from spire.pdf import *
input_file = "source.pdf"
output_file = "custom_size.pdf"
# 目标尺寸:200mm × 280mm
converter = PdfUnitConvertor()
width_pt = converter.ConvertUnits(200, PdfGraphicsUnit.Millimeter, PdfGraphicsUnit.Point)
height_pt = converter.ConvertUnits(280, PdfGraphicsUnit.Millimeter, PdfGraphicsUnit.Point)
original_pdf = PdfDocument()
original_pdf.LoadFromFile(input_file)
new_pdf = PdfDocument()
for i in range(original_pdf.Pages.Count):
page = original_pdf.Pages.get_Item(i)
new_page = new_pdf.Pages.Add(SizeF(width_pt, height_pt), PdfMargins(0.0))
layout = PdfTextLayout()
layout.Layout = PdfLayoutType.OnePage
template = page.CreateTemplate()
template.Draw(new_page, PointF.Empty(), layout)
`new_pdf.SaveToFile(output_file)`
`
new_pdf.Close()`
`
original_pdf.Close()`
`
`
ConvertUnits 的第一个参数是数值,第二个是源单位,第三个是目标单位。支持的单位包括 Millimeter、Inch、Pixel、Point 等。如果不确定原始页面的尺寸,可以先读取出来作为参考:
python
page = original_pdf.Pages[0]
print(f"原页面尺寸: {page.Size.Width} × {page.Size.Height} points")
场景三:按比例缩放(放大或缩小)
有时目标不是某个固定的物理尺寸,而是"整体放大 1.2 倍"或"缩到 80%"。这只需要在原尺寸基础上乘以系数,逻辑比前两种场景更简单:
python
from spire.pdf.common import *
from spire.pdf import *
input_file = "source.pdf"
output_file = "scaled_120.pdf"
scale = 1.2
original_pdf = PdfDocument()
original_pdf.LoadFromFile(input_file)
new_pdf = PdfDocument()
for i in range(original_pdf.Pages.Count):
page = original_pdf.Pages.get_Item(i)
new_width = float(page.Size.Width * scale)
new_height = float(page.Size.Height * scale)
new_page = new_pdf.Pages.Add(SizeF(new_width, new_height), PdfMargins(0.0))
layout = PdfTextLayout()
layout.Layout = PdfLayoutType.OnePage
template = page.CreateTemplate()
template.Draw(new_page, PointF.Empty(), layout)
`new_pdf.SaveToFile(output_file)`
`
new_pdf.Close()`
`
original_pdf.Close()`
`
`
按比例缩放时,所有页面的宽高比保持不变,内容不会因为拉伸而变形。PdfLayoutType.OnePage 在这里主要起保险作用:即使某页的原始尺寸与其他页略有差异,也能保证内容完整落入新页面。
小结
通过页面模板重绘的方式调整 PDF 页面尺寸,是比较稳定可靠的方案,适合自动化批量规整文档页面。核心流程可以概括为四步:读原页 → 建模板 → 开新页 → 画上去 。实际操作中你可以根据业务需求调整缩放逻辑、边距、对齐方式。