一. 安装模块
pip install reportlab
二. reportlab相关介绍
from reportlab.lib.pagesizes import letter
print(letter)
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('song', 'simsun.ttc'))
from reportlab.lib import colors
from reportlab.pdfgen import canvas
canvas.Canvas('新PDF文件名称.pdf', pagesize=letter)
c = canvas.Canvas(filename, pagesize=letter)
c.setFont('song', 12)
tab_style = TableStyle([
('FONTNAME', (0, 0), (-1, 0), 'song-Bold', 12),
('TOPPADDING', (0, 1), (-1, -1), 1),
('BOTTOMPADDING', (0, 0), (-1, 0), 1),
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
("FONT", (0, 0), (-1, -1), 'song', 8),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('BOX', (0, 0), (-1, -1), 0.5, colors.black),
('INNERGRID', (0, 0), (-1, -1), 0.5, colors.black),
])
table_data= [
('姓名', '性别', '年龄', '民族'),
('张三', '男', 20, '汉'),
('李四', '男', 21, '汉'),
('王小小', '女', 18, '汉'),
]
colWidths = [20, 15, 13, 15]
rowHeights = [29]*len(table_data)
x = 30
y = 600
table1 = Table(table_data, style=table_style, colWidths=colWidths, rowHeights=rowHeights)
table1.wrapOn(self, letter[0], letter[1])
table1.drawOn(self, x, y)
filepath = 'd:\images\tttt.png'
image = ImageReader(filepath)
c.drawImage(image, x, y, width=120, height=60)
c.drawString(x, y, text)
def translate(func):
def wrapper(*args, **kwargs):
ox = letter[0] / 2
oy = letter[1] / 2
args[0].saveState()
args[0].translate(ox, oy)
args[0].rotate(90)
func(args[0], *args[1:], **kwargs)
args[0].restoreState()
return wrapper
三. 扩展canvas类
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
from reportlab.lib.utils import ImageReader
class PDFCanvas(canvas.Canvas):
FONTS_DIR = r"D:\fonts"
font_path = os.path.join(FONTS_DIR, 'simsun.ttc')
pdfmetrics.registerFont(TTFont('song', font_path))
def __init__(self, filename, **kwargs):
super().__init__(filename, **kwargs)
def draw_image(self, filename, **kwargs):
IMAGES_DIR = r'C:\下载图片'
filepath = os.path.join(IMAGES_DIR, filename)
x = kwargs.get('x', 20)
y = kwargs.get('y', 756)
width = kwargs.get('width', 48)
height = kwargs.get('height', 18)
image = ImageReader(filepath)
self.drawImage(image, x, y, width=width, height=height)
def draw_text(self, text, **kwargs):
x = kwargs.get('x', None)
y = kwargs.get('y', None)
font = kwargs.get('font', 'song')
font_size = kwargs.get('font_size', 12)
self.setFont(font, font_size)
text_width = self.stringWidth(text, font, font_size)
x = x if x else (letter[0] - text_width) / 2
self.drawString(x, y, text)
def draw_table(self, table_data, **kwargs):
title = kwargs.get('title', '')
if title:
table_data = [(title,), *table_data]
x = kwargs.get('x', 30)
y = kwargs.get('y', 650)
colWidths = kwargs.get('colWidths', 120)
table_style = kwargs.get('table_style', tab_style)
table_h = Table(table_data, style=table_style, colWidths=colWidths, rowHeights=[29]*len(table_data))
table_h.wrapOn(self, letter[0], letter[1])
table_h.drawOn(self, x, y)
def translate(func):
def wrapper(*args, **kwargs):
ox = letter[0] / 2
oy = letter[1] / 2
args[0].saveState()
args[0].translate(ox, oy)
args[0].rotate(90)
func(args[0], *args[1:], **kwargs)
args[0].restoreState()
return wrapper
class PDFCanvas(canvas.Canvas):
font_path = os.path.join(FONTS_DIR, 'simsun.ttc')
pdfmetrics.registerFont(TTFont('song', font_path))
def __init__(self, filename, **kwargs):
super().__init__(filename, **kwargs)
@translate
def draw_image(self, filename, **kwargs):
IMAGES_DIR = r'C:\下载图片'
filepath = os.path.join(IMAGES_DIR, filename)
x = kwargs.get('x', 20)
y = kwargs.get('y', 756)
width = kwargs.get('width', 48)
height = kwargs.get('height', 18)
x1 = -(letter[1] / 2 - y)
y = letter[0] / 2 - x
image = ImageReader(filepath)
self.drawImage(image, x1, y, width=width, height=height)
@translate
def draw_text(self, text, **kwargs):
x = kwargs.get('x', 20)
y = kwargs.get('y', None)
font = kwargs.get('font', 'song')
font_size = kwargs.get('font_size', 12)
self.setFont(font, font_size)
text_width = self.stringWidth(text, font, font_size)
x1 = -(letter[1] / 2 - y) if y else -int(text_width / 2)
y = letter[0] / 2 - x
self.drawString(x1, y, text)
@translate
def draw_table(self, table_data, **kwargs):
title = kwargs.get('title', '')
if title:
table_data = [(title,), *table_data]
x = kwargs.get('x', 30)
y = kwargs.get('y', 650)
colWidths = kwargs.get('colWidths', 120)
table_style = kwargs.get('table_style', tab_style)
x1 = -(letter[1] / 2 - y)
y = letter[0] / 2 - x
table1 = Table(table_data, style=table_style, colWidths=colWidths, rowHeights=[29]*len(table_data))
table1.wrapOn(self, letter[0], letter[1])
table1.drawOn(self, x1, y)
四. 水平写入完整代码
import os
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
from reportlab.lib.utils import ImageReader
tab_style = TableStyle([
('FONTNAME', (0, 0), (-1, 0), 'song-Bold', 12),
('TOPPADDING', (0, 1), (-1, -1), 1),
('BOTTOMPADDING', (0, 0), (-1, 0), 1),
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
("FONT", (0, 0), (-1, -1), 'song', 8),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('BOX', (0, 0), (-1, -1), 0.5, colors.black),
('INNERGRID', (0, 0), (-1, -1), 0.5, colors.black),
])
class PDFCanvas(canvas.Canvas):
FONTS_DIR = r"D:\fonts"
font_path = os.path.join(FONTS_DIR, 'simsun.ttc')
pdfmetrics.registerFont(TTFont('song', font_path))
def __init__(self, filename, **kwargs):
super().__init__(filename, **kwargs)
def draw_image(self, filename, **kwargs):
IMAGES_DIR = r'C:\下载图片'
filepath = os.path.join(IMAGES_DIR, filename)
x = kwargs.get('x', 20)
y = kwargs.get('y', 756)
width = kwargs.get('width', 48)
height = kwargs.get('height', 18)
image = ImageReader(filepath)
self.drawImage(image, x, y, width=width, height=height)
def draw_text(self, text, **kwargs):
x = kwargs.get('x', None)
y = kwargs.get('y', None)
font = kwargs.get('font', 'song')
font_size = kwargs.get('font_size', 12)
self.setFont(font, font_size)
text_width = self.stringWidth(text, font, font_size)
x = x if x else (letter[0] - text_width) / 2
self.drawString(x, y, text)
def draw_table(self, table_data, **kwargs):
title = kwargs.get('title', '')
if title:
table_data = [(title,), *table_data]
x = kwargs.get('x', 30)
y = kwargs.get('y', 650)
colWidths = kwargs.get('colWidths', 120)
table_style = kwargs.get('table_style', tab_style)
table_h = Table(table_data, style=table_style, colWidths=colWidths, rowHeights=[29]*len(table_data))
table_h.wrapOn(self, letter[0], letter[1])
table_h.drawOn(self, x, y)
if __name__ == '__main__':
c = PDFCanvas('水平写入.pdf', pagesize=letter)
image_name = '123.png'
c.draw_image(image_name, x=70, y=400, width=320, height=240)
text1 = '我现在需要回答用户关于“reportlab letter”的问题'
c.draw_text(text1, y=700, font_size=16)
table1 = [
('姓名', '性别', '年龄', '民族'),
('张三', '男', 20, '汉'),
('李四', '男', 21, '汉'),
('王小小', '女', 18, '汉'),
]
c.draw_table(table1, x=100, y=200, colWidths=[80, 80, 80, 80])
c.save()

五. 垂直写入完整代码
import os
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors
from reportlab.lib.utils import ImageReader
def translate(func):
def wrapper(*args, **kwargs):
ox = letter[0] / 2
oy = letter[1] / 2
args[0].saveState()
args[0].translate(ox, oy)
args[0].rotate(90)
func(args[0], *args[1:], **kwargs)
args[0].restoreState()
return wrapper
tab_style = TableStyle([
('FONTNAME', (0, 0), (-1, 0), 'song-Bold', 12),
('TOPPADDING', (0, 1), (-1, -1), 1),
('BOTTOMPADDING', (0, 0), (-1, 0), 1),
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
("FONT", (0, 0), (-1, -1), 'song', 8),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('BOX', (0, 0), (-1, -1), 0.5, colors.black),
('INNERGRID', (0, 0), (-1, -1), 0.5, colors.black),
])
class PDFCanvas(canvas.Canvas):
FONTS_DIR = r"D:\fonts"
font_path = os.path.join(FONTS_DIR, 'simsun.ttc')
pdfmetrics.registerFont(TTFont('song', font_path))
def __init__(self, filename, **kwargs):
super().__init__(filename, **kwargs)
@translate
def draw_image(self, filename, **kwargs):
IMAGES_DIR = r'C:\下载图片'
filepath = os.path.join(IMAGES_DIR, filename)
x = kwargs.get('x', 20)
y = kwargs.get('y', 756)
width = kwargs.get('width', 48)
height = kwargs.get('height', 18)
x1 = -(letter[1] / 2 - y)
y = letter[0] / 2 - x
image = ImageReader(filepath)
self.drawImage(image, x1, y, width=width, height=height)
@translate
def draw_text(self, text, **kwargs):
x = kwargs.get('x', 20)
y = kwargs.get('y', None)
font = kwargs.get('font', 'song')
font_size = kwargs.get('font_size', 12)
self.setFont(font, font_size)
text_width = self.stringWidth(text, font, font_size)
x1 = -(letter[1] / 2 - y) if y else -int(text_width / 2)
y = letter[0] / 2 - x
self.drawString(x1, y, text)
@translate
def draw_table(self, table_data, **kwargs):
title = kwargs.get('title', '')
if title:
table_data = [(title,), *table_data]
x = kwargs.get('x', 30)
y = kwargs.get('y', 650)
colWidths = kwargs.get('colWidths', 120)
table_style = kwargs.get('table_style', tab_style)
x1 = -(letter[1] / 2 - y)
y = letter[0] / 2 - x
table1 = Table(table_data, style=table_style, colWidths=colWidths, rowHeights=[29]*len(table_data))
table1.wrapOn(self, letter[0], letter[1])
table1.drawOn(self, x1, y)
if __name__ == '__main__':
c = PDFCanvas('垂直写入.pdf', pagesize=letter)
image_name = '123.png'
c.draw_image(image_name, x=280, y=100, width=320, height=200)
text1 = '我现在需要回答用户关于“reportlab letter”的问题'
c.draw_text(text1, x=50, font_size=16)
table1 = [
('姓名', '性别', '年龄', '民族'),
('张三', '男', 20, '汉'),
('李四', '男', 21, '汉'),
('王小小', '女', 18, '汉'),
]
c.draw_table(table1, x=400, y=100, colWidths=[80, 80, 80, 80])
c.save()
