# 说明

需求:生成 pdf 格式的证书,证书其实是有个模板的(下面测试我随便做了一个),不过内容(主要是证书上的文字)需要自己动态填写
语言:python
引入库: PyPDF2 - 负责读写和合并 pdf;  (PyPDF2 1.26.0)
        reportlab - 负责绘画(创建)生成一个新的 pdf   (reportlab 3.5.67)
        基于 Python 3.6.8
思路:使用 reportlab 的 canvas 根据坐标(以左下角为原点,使得整个 pdf page 在第一象限)绘制新的 pdf 文件放到内存,
      使用 PyPDF2 读取 pdf 模板,合并上面生成的新的 pdf page,然后将合并后的 pdf 写入文件
说明:reportlab 默认不支持中文,直接绘制中文字符会显示小方框乱码,需要先注册字体,字体直接引用系统 ttf 文件即可
      注意 canvas 的坐标系,即第一象限,绘制时可能要多次测试调整 x,y 的值使得内容显示恰当,然后合并后生成你所需要的 pdf
证书模板:我这里是随便找了个证书图片(百度搜一堆,把内容擦掉即可),使用 gimp 工具导出为 pdf(file - export as 修改文件名字为 test.pdf 然后导出)
参考:https://www.reportlab.com/docs/reportlab-userguide.pdf
Demo 证书图片:https://www.google.com/url?sa=i&url=http%3A%2F%2F616pic.com%2Fimage%2Fzhengshu.html&psig=AOvVaw2yhE9FezNqC-6U4kgBWDun&ust=1619226823600000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCMCejI-Yk_ACFQAAAAAdAAAAABAD

# 效果

pdf01

pdf02

# 代码

from PyPDF2 import PdfFileWriter, PdfFileReader
import io
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
pdfmetrics.registerFont(TTFont('SimHei', r'C:\Windows\Fonts\simhei.ttf'))
 
 
if __name__ == '__main__':
    packet = io.BytesIO()
    # create a new PDF with Reportlab
    can = canvas.Canvas(packet, pagesize=letter)
    can.setFillColorRGB(0, 0, 0)  # choose your font colour
    can.setFont("SimHei", 3)  # choose your font type and font size
    can.drawString(18, 50, "小明 同学")  # name
    can.drawString(20, 40, "恭喜小明同学在这次数学竞赛中取得第一名,特此奖励!")
    can.drawString(80, 30, "阳光小学一班")
    can.drawString(80, 20, "二O二一年四月二十三号")
    can.save()
 
    # move to the beginning of the StringIO buffer
    packet.seek(0)
    new_pdf = PdfFileReader(packet)
    # read your existing PDF
    existing_pdf = PdfFileReader(open(r"C:\Users\jalchu\Desktop\test.pdf", "rb"))
    output = PdfFileWriter()
    # add the "watermark" (which is the new pdf) on the existing page
    page = existing_pdf.getPage(0)
    page.mergePage(new_pdf.getPage(0))
    output.addPage(page)
    # finally, write "output" to a real file
    outputStream = open(r"C:\Users\jalchu\Desktop\demo.pdf", "wb")
    output.write(outputStream)
    outputStream.close()
    print('end')
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Jalen Chu 微信支付

微信支付

Jalen Chu 支付宝

支付宝

Jalen Chu 公众号

公众号