Reportlab生成PDF文件

用Reportlab生成PDF文件中的图表,碰到以下情况:

直接在图表上标注不可行,此时可以用Legend生成专门的图例:

from reportlab.graphics.charts.piecharts import Pie		# Pie型图表
from reportlab.lib.colors import HexColor, black, red, purple, green, maroon, brown, pink, white, HexColor
from reportlab.graphics.charts.legends import Legend	# 图例
from reportlab.graphics.shapes import Drawing
from myStyle import *		# 在myStyle.py里有自己注册的中文字体

# 指定图例中用到的颜色序列
pdf_chart_colors = [
    HexColor("#8900c9"), HexColor("#60955f"), HexColor("#5757f0"),
	HexColor("#8f8ff5"), HexColor("#c7c7fa"), HexColor("#f5c2c2"),
    HexColor("#eb8585"), HexColor("#e04747"), HexColor("#d60a0a"),
	HexColor("#ce3c7b"), HexColor("#f84031"), ]

# 指定画布的宽高,图表图例都画在画布上
width = 400
height = 200
d = Drawing(width, height)

# 指定图表的宽高
pc = Pie()
pc.width                  = 150
pc.height                 = pc.width
# 图表左下角的坐标
pc.x                      = 20
pc.y                      = (height-pc.height)/2
# 图表表现的数据
pc.data = [11.90,13.30,11.10,9.40,8.50,7.80,7.00,6.20,8.80,4.00]
# 图表的标签
pc.labels = ['翠云山芭蕉洞','平顶山莲花洞','万寿山五庄观','积雷山摩云洞','斜月三星洞','号山火云洞','兜率宫','广寒宫','凌霄殿','披香殿']

# 图表的标签不在图表上显示,而是另行在图例上显示
pc.slices.label_visible   = 0
# 图表上线的颜色和宽度
pc.slices.strokeColor     = white
pc.slices.strokeWidth     = 1

# 指定图表上颜色到颜色列表里取色的循环模式
m = len(pdf_chart_colors)		# 可取的颜色个数
n = len(pc.data)				# 需要的颜色个数
i = m // n						# i是整除后的值,决定取颜色时间隔几个取
for j in range(n):
	setattr(pc.slices[j], 'fillColor', pdf_chart_colors[j * i % m])
	# 填色时不是顺序取色,而是跳着取,跳得幅度跟i有关,隔2个、3个……取

d.add(pc)	# 将图表添加进画布

myLegend = Legend()						# 生成图例对象
# 指定图例锚点的位置
myLegend.x               = 200			# 横坐标
myLegend.y               = height/2		# 纵坐标
myLegend.dx              = 8			# 图例上颜色块的宽度
myLegend.dy              = 8			# 颜色块的高度
myLegend.fontName        = 'apple'
# 指定图例上的字体,apple是自己在myStyle.py里定义的中文字体
myLegend.fontSize        = 7			# 字体大小
myLegend.boxAnchor       = 'w'			# 图例的锚点,w-west
myLegend.columnMaximum   = 15			# 图例最多显示几行
myLegend.strokeWidth     = 1			# 线条宽度
myLegend.strokeColor     = black		# 线条颜色
myLegend.deltay          = 10			# 图例上的行间距
myLegend.yGap            = 0			# 跟前面的参数一起调节行间距
myLegend.dxTextSpace     = 10			# 图示文字和色标的间距
myLegend.alignment       = 'right'		# 图示说明文字在颜色图示的右边
myLegend.dividerLines    = 1|2|4
# 1是行与行之间有线,2是最顶的线,4是最底的线
myLegend.dividerOffsY    = 4.5
# Y轴方向上调整间隔线的位置
myLegend.subCols.rpad    = 30
# 图示文字和数字之间增加了30的间隔

myLegend.colorNamePairs = [(pc.slices[i].fillColor,
	(pc.labels[i], '{:.2f}'.format(pc.data[i]))) for i in range(n)]
# 指定图例上的填色块、图例上的标签和对应的数字,n是图例表达的数据个数

d.add(myLegend)		# 将图例添加进画布

from reportlab.graphics import renderPDF
renderPDF.drawToFile(d, 'pieChartLegend.pdf')	# 写入PDF文件

myStyle.py注册中文字体的相关代码:

......
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
pdfmetrics.registerFont(TTFont('apple', '/Library/Fonts/Chinese/XiaoHuYao-2.ttf'))
......