我的知识记录

Python reportlab生成简单PDF:三行代码出一份合同

用Python的reportlab库从零生成一份带标题、正文和中文字体的PDF文件,覆盖画页、写文字、设置字号颜色、保存输出,适合做合同、报告、收据模板。

场景痛点

工作中经常需要把一段固定格式的合同、报价单、对账单做成PDF,手动用Word排版另存,每次改公司名、金额都要重新打开软件,批量出几十份更是繁琐。reportlab是Python里最老牌的PDF生成库,直接用代码画页面、写文字、放表格,一次写好模板,传参就能批量出PDF。

用到的库

pip install reportlab

完整代码

# -*- coding: utf-8 -*-
"""
用 reportlab 生成一份简单的 PDF 文档,含标题、正文、中文字体。
"""
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.units import cm


def register_chinese_font():
"""注册一个支持中文的 TrueType 字体,否则中文会变方块。
这里用系统常见的文泉驿微米黑;Windows 下可换成 simsun.ttc / msyh.ttc。
"""
font_path = "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc"
try:
pdfmetrics.registerFont(TTFont("CNFont", font_path))
except Exception:
# 兜底:退到 Helvetica,中文可能显示不全,但脚本能跑通
return "Helvetica"
return "CNFont"


def create_simple_pdf(output_path: str, title: str, body_lines: list):
# A4 页面大小,单位是磅(point),1cm ≈ 28.35 磅
c = canvas.Canvas(output_path, pagesize=A4)
width, height = A4
font_name = register_chinese_font()

# 1) 画标题:居中、加粗、字号 18
c.setFont(font_name, 18)
c.drawCentredString(width / 2, height - 3 * cm, title)

# 2) 画一条分隔线
c.setLineWidth(1)
c.line(2 * cm, height - 3.5 * cm, width - 2 * cm, height - 3.5 * cm)

# 3) 写正文,从顶部往下排,每行行距 0.8cm
c.setFont(font_name, 11)
y = height - 5 * cm
for line in body_lines:
c.drawString(2 * cm, y, line)
y -= 0.8 * cm

# 4) 页脚:日期 + 页码
c.setFont(font_name, 9)
c.drawRightString(width - 2 * cm, 1.5 * cm, "第 1 页 / 共 1 页")

c.save()
print(f"PDF 已生成:{output_path}")


if __name__ == "__main__":
create_simple_pdf(
output_path="simple_report.pdf",
title="合作协议(模板)",
body_lines=[
"甲方:宝鸡市金台区卓亚技术服务部",
"乙方:稳驰供应链管理有限公司",
"合作内容:乙方为甲方提供全国干线物流运输服务。",
"结算方式:月结30天,凭对账单及发票付款。",
"本协议自双方签字盖章之日起生效。",
],
)

代码讲解

  • canvas.Canvas(路径, pagesize=A4) 就是一个新的空白PDF画布,所有绘制都基于它。
  • pdfmetrics.registerFont(TTFont(...)) 注册中文字体;reportlab默认字体不含中文,不注册直接写中文会变成方块或问号。Linux常用/usr/share/fonts/...,Windows直接用C:/Windows/Fonts/msyh.ttc
  • drawString(x, y, text) 在指定坐标写字,原点在左下角,y越大越靠上,这是PDF坐标系统跟网页不一样的地方。
  • drawCentredString 居中写、drawRightString 右对齐写,适合做标题和页脚。
  • c.save() 才真正把文件落盘,之前都只是内存操作。

运行结果

脚本跑完会在当前目录生成 simple_report.pdf,打开能看到居中标题"合作协议(模板)"、一条横线、五行正文和右下角页脚。可以用Acrobat或浏览器直接打开验证。

注意事项

  • 中文字体是最大的坑:找不到字体文件时脚本会兜底用Helvetica,中文会显示成空心方块,务必把字体路径改成你机器上真实存在的ttf/ttc。
  • 坐标原点在左下角,写多段文字要自己维护y值递减;长文排版建议换用reportlab.platypus的Paragraph/Table,自动换行分页。
  • reportlab不依赖Word/Acrobat,纯Python跨平台,适合服务器批量出单。
  • 复杂表格、图片、页眉页脚可以配合platypus.SimpleDocTemplate,比裸canvas省事。

Python reportlab生成简单PDF:三行代码出一份合同

标签:

更新时间:2026-09-14 21:34:04

上一篇:Python PDF旋转页面方向 批量转正教程

下一篇:Python读取PDF文本内容 pdfplumber 实战教程