ReportLab 导出 PDF(图文表格)

ReportLab 导出 PDF(文档创建)
ReportLab 导出 PDF(页面布局)
ReportLab 导出 PDF(图文表格)

文章目录

  • [1. Paragraph(段落)](#1. Paragraph(段落))
  • [2. Table(表格)](#2. Table(表格))
  • [3. VerticalBarChart(柱形图表)](#3. VerticalBarChart(柱形图表))
    • [3.1. 多组多条数据](#3.1. 多组多条数据)
    • [3.2. 多组单条数据](#3.2. 多组单条数据)
    • [3.3. 柱状图累加](#3.3. 柱状图累加)
  • [4. 饼状图](#4. 饼状图)
  • [5. Image(图像)](#5. Image(图像))
  • [6. 常用颜色](#6. 常用颜色)
  • [7. 字体与编码](#7. 字体与编码)

1. Paragraph(段落)

官网:

https://docs.reportlab.com/reportlab/userguide/ch6_paragraphs/

https://blog.csdn.net/weixin_49278803/article/details/132907427

python 复制代码
canvas.drawString(80, 700, 'Standard String')				# 标准绘制函数
canvas.drawRightString(80, 680, 'Right String')				# x轴右对齐绘制函数
canvas.drawAlignedString(60, y, str(number))				# 轴对称绘制函数
canvas.drawCentredString(width/2, 550, 'Centered String')	# 中心对称绘制函数

https://blog.csdn.net/icloudend/article/details/98902717

2. Table(表格)

https://www.cnblogs.com/jilingxf/p/15857940.html

python 复制代码
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

from reportlab.graphics.charts.barcharts import VerticalBarChart    # 图表类
from reportlab.graphics.charts.legends import Legend                # 图例类
from reportlab.graphics.shapes import Drawing                       # 绘图工具
from reportlab.platypus import Table, Paragraph, TableStyle
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet

def draw_table1(datas: list):
    col_widths, row_heights = [80, 100, 100, 100, 100], [60, 50, 50, 50, 50, 50]
    # 表格行列的表达形式为(x, y):左上方第一个单元格为(0, 0), 右下角单元格为(-1, -1)
    table_style = TableStyle([
        ("FONT", (0, 0), (0, -1), "simsun", 15),                # 第一列:配置字体
        ("FONT", (0, 0), (-1, 0), "simsun", 15),                # 第一行:
        ("FONT", (1, 1), (-1, -1), "simsun", 12),
        ("ALIGN", (0, 0), (-1, -1), "CENTER"),                  # 水平居中
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),                 # 垂直居中
        ("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black),    # 单元格分割线
        ("BOX", (0, 0), (-1, -1), 0.25, colors.black),          # 边框
        ("BACKGROUND", (0, 0), (-1, -1), colors.lightgrey),     # 背景色(默认为白色)
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.red),             # 第一行: 区域字体颜色
        ("LINEBELOW", (0,-1), (-1,-1), 0, colors.white),        # 移除最后一行的下框线,延申LINEABOVE(上框线)、LINEBEFORE(左框线)、LINEAFTER(右框线)
        # ("GRID", (0, 0), (-1, -1), 0.5, colors.black),        # 表格框线为灰色,线宽为0.5
        # ("SPAN", (0, 3), (-1, 3)),                              # 合并单元格
    ])

    return Table(datas, colWidths=col_widths, rowHeights=row_heights, style=table_style)

def draw_table2(datas: list):
    col_widths, row_heights = [80, 100, 100, 100, 100], [30, 25, 25, 25, 25, 25]
    # 表格行列的表达形式为(x, y):左上方第一个单元格为(0, 0), 右下角单元格为(-1, -1)
    table_style = TableStyle([
        ("FONT", (0, 0), (0, -1), "simsun", 20),                # 第一列:配置字体
        ("FONT", (0, 0), (-1, 0), "simsun", 15),                # 第一行:
        ("FONT", (1, 1), (-1, -1), "simsun", 15),
        ("ALIGN", (0, 0), (-1, -1), "CENTER"),                  # 水平居中
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),                 # 垂直居中
        ("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black),    # 单元格分割线
        ("BOX", (0, 0), (-1, -1), 0.25, colors.black),          # 边框
        # ("BACKGROUND", (0, 0), (-1, -1), colors.lightgrey),     # 背景色(默认为白色)
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.red),             # 第一行: 区域字体颜色
        # ("LINEBELOW", (0,-1), (-1,-1), 0, colors.white),        # 移除最后一行的下框线,延申LINEABOVE(上框线)、LINEBEFORE(左框线)、LINEAFTER(右框线)
        # ("GRID", (0, 0), (-1, -1), 0.5, colors.black),        # 表格框线为灰色,线宽为0.5
        ("SPAN", (0, 3), (-1, 3)),                              # 合并单元格
    ])

    return Table(datas, colWidths=col_widths, rowHeights=row_heights, style=table_style)

def main(filename):
    # pdfmetrics.registerFont(TTFont('微软雅黑', 'msyh.ttf'))
    pdfmetrics.registerFont(TTFont('simsun', "simsun.ttc"))

    doc = SimpleDocTemplate(filename, pagesize=A4)
    Story = []
    datas = [
        ["姓名", "语文", "数学", "英语", "体育"],
        ["张三", 91, 97, 79, "良好"],
        ["李四", 99, 87, 73, "优秀"],
        ["王五", 86, 89, 83, "良好"],
        ["赵六", 95, 88, 86, "良好"],
        # 当需要将数据在一个单元格分两列的话,可以用下面的语法
        ["孙七", 79, 95, 98, "良"+"\n"+"好"],
    ]

    # 编辑表格标题及样式
    tabletitle = """<para alignment=center fontName="simsun" fontSize=20 spaceAfter=30>表1: 学生成绩表</para>"""
    # 可以配置上下左右页边距,topMargin=1*cm,bottomMargin=1*cm,leftMargin=1*cm,rightMargin=1*cm
    Story.append(Paragraph(tabletitle, getSampleStyleSheet()["Normal"]))
    Story.append(draw_table1(datas))

    tabletitle = """<para alignment=center fontName="simsun" fontSize=20 spaceBefore=30 spaceAfter=30>表1: 学生成绩表</para>"""
    Story.append(Paragraph(tabletitle))
    Story.append(draw_table2(datas))
    doc.build(Story)

if __name__ == '__main__': 
    main(filename='example.pdf')

3. VerticalBarChart(柱形图表)

参考:

https://blog.csdn.net/weixin_49278803/article/details/132907427

https://www.cnblogs.com/hujq1029/p/7767980.html

https://zhuanlan.zhihu.com/p/528669672

3.1. 多组多条数据

python 复制代码
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

from reportlab.graphics.charts.barcharts import VerticalBarChart    # 图表类
from reportlab.graphics.charts.legends import Legend                # 图例类
from reportlab.graphics.shapes import Drawing                       # 绘图工具

# 多组多列
def draw_group_bars1(datas: list, categorys: list, legends: list):
    drawing = Drawing(500, 250)
    bc = VerticalBarChart()
    bc.x                            = 45            # 整个图表的x坐标
    bc.y                            = 45            # 整个图表的y坐标
    bc.height                       = 200           # 图表的高度
    bc.width                        = 350           # 图表的宽度
    bc.data                         = datas
    bc.strokeColor                  = colors.black  # 顶部和右边轴线的颜色
    bc.valueAxis.valueMin           = 5000          # 设置y坐标的最小值
    bc.valueAxis.valueMax           = 26000         # 设置y坐标的最大值
    bc.valueAxis.valueStep          = 2000          # 设置y坐标的步长
    bc.groupSpacing                 = 10            # 每组柱状图之间的间隔
    # bc.barSpacing                   = 1           # 每个柱状图之间的间隔
    bc.categoryAxis.labels.dx       = 2             # x和y是x轴下方的标签距离x轴远近的坐标
    bc.categoryAxis.labels.dy       = -8
    # bc.categoryAxis.labels.angle    = 20            # x轴上描述文字的倾斜角度
    bc.categoryAxis.categoryNames   = categorys

    bc.bars[0].fillColor = colors.red
    bc.bars[1].fillColor = colors.orange
    bc.bars[2].fillColor = colors.yellow
    bc.bars[3].fillColor = colors.green

    # 图示
    leg = Legend()
    leg.fontName        = 'simsun'
    leg.alignment       = 'right'                   # 文字在色块的左或者右
    leg.boxAnchor       = 'ne'
    leg.x               = 475                       # 图例的x坐标
    leg.y               = 240
    leg.dxTextSpace     = 10                        # 色块与文字之间的间距
    leg.columnMaximum   = len(legends)
    leg.colorNamePairs  = legends
    drawing.add(leg)
    drawing.add(bc)
    return drawing

# 多组多列
def draw_group_bars2(datas: list, categorys: list, legends: list):
    drawing = Drawing(500, 250)
    bc = VerticalBarChart()
    bc.x                            = 45            # 整个图表的x坐标
    bc.y                            = 45            # 整个图表的y坐标
    bc.height                       = 200           # 图表的高度
    bc.width                        = 350           # 图表的宽度
    bc.data                         = datas
    bc.strokeColor                  = colors.black  # 顶部和右边轴线的颜色
    bc.valueAxis.valueMin           = 5000          # 设置y坐标的最小值
    bc.valueAxis.valueMax           = 26000         # 设置y坐标的最大值
    bc.valueAxis.valueStep          = 2000          # 设置y坐标的步长
    bc.groupSpacing                 = 10            # 每组柱状图之间的间隔
    # bc.barSpacing                   = 1           # 每个柱状图之间的间隔
    bc.categoryAxis.labels.dx       = 2             # x和y是x轴下方的标签距离x轴远近的坐标
    bc.categoryAxis.labels.dy       = -8
    bc.categoryAxis.labels.angle    = 20            # x轴上描述文字的倾斜角度
    bc.categoryAxis.categoryNames   = categorys

    bc.bars[0].fillColor = colors.red
    bc.bars[1].fillColor = colors.orange
    bc.bars[2].fillColor = colors.yellow
    bc.bars[3].fillColor = colors.green

    # 图示
    leg = Legend()
    leg.fontName        = 'simsun'
    leg.alignment       = 'left'                    # 文字在色块的左或者右
    leg.boxAnchor       = 'ne'
    leg.x               = 475                       # 图例的x坐标
    leg.y               = 240
    leg.dxTextSpace     = 20                        # 色块与文字之间的间距
    leg.columnMaximum   = len(legends)
    leg.colorNamePairs  = legends
    drawing.add(leg)
    drawing.add(bc)
    return drawing

def main(filename):
    # pdfmetrics.registerFont(TTFont('微软雅黑', 'msyh.ttf'))
    pdfmetrics.registerFont(TTFont('simsun', "simsun.ttc"))

    doc = SimpleDocTemplate(filename, pagesize=A4)
    Story = []
    datas = [(25400, 12900, 20100, 20300, 20300, 17400), 
              (15800, 9700, 12982, 20100, 13900, 7623),
              (20100, 13900, 9700, 12982, 7623, 15800),
              (12900, 13900, 20300, 9283, 25400, 9700)]
    categorys = ['BeiJing', 'ChengDu', 'ShenZhen', 'ShangHai', 'HangZhou', 'NanJing']
    legends = [(colors.red, '标准1'), (colors.orange, '标准2'), (colors.yellow, '标准3'), (colors.green, '标准4')]
    Story.append(draw_group_bars1(datas, categorys, legends))
    Story.append(draw_group_bars2(datas, categorys, legends))

    doc.build(Story)

if __name__ == '__main__': 
    main(filename='example.pdf')

3.2. 多组单条数据

参考:https://dev59.com/uF7Va4cB1Zd3GeqPKod0

python 复制代码
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

from reportlab.graphics.charts.barcharts import VerticalBarChart    # 图表类
from reportlab.graphics.charts.legends import Legend                # 图例类
from reportlab.graphics.shapes import Drawing                       # 绘图工具
from reportlab.graphics.shapes import String
from reportlab.graphics.charts.textlabels import Label

# 多组单条
def draw_group_bar1(datas: list, categorys: list, legends: list):
    drawing = Drawing(500, 280)
    # drawing.add(String(45, 260, "多组单条柱状图", fontSize=14, fontName='simsun', fillColor=colors.black))
    # 配置图表标题
    title = Label()
    title.setText("多组单条柱状图")
    # title.fontSize, title.fontName, title.dx, title.dy = 14, "simsun", 45, 260
    title.fontSize, title.fontName, title.x, title.y = 14, "simsun", 45, 260
    drawing.add(title)

    bc = VerticalBarChart()
    bc.x                            = 45            # 整个图表的x坐标
    bc.y                            = 45            # 整个图表的y坐标
    bc.height                       = 200           # 图表的高度
    bc.width                        = 350           # 图表的宽度
    bc.data                         = datas
    bc.strokeColor                  = colors.black  # 顶部和右边轴线的颜色
    bc.valueAxis.valueMin           = 5000          # 设置y坐标的最小值
    bc.valueAxis.valueMax           = 26000         # 设置y坐标的最大值
    bc.valueAxis.valueStep          = 2000          # 设置y坐标的步长
    bc.groupSpacing                 = 10            # 每组柱状图之间的间隔
    # bc.barSpacing                   = 1           # 每个柱状图之间的间隔
    bc.categoryAxis.labels.dx       = 2
    bc.categoryAxis.labels.dy       = -8
    # bc.categoryAxis.labels.angle    = 20
    bc.categoryAxis.categoryNames   = categorys

    # 图形柱上标注文字
    # bc.barLabels.nudge              = -10           # 文字在图形柱的上下位置
    bc.barLabels.nudge              = 10            # 文字在图形柱的上下位置
    # bc.barLabelArray                = labels        # 要添加的文字
    # bc.barLabelFormat               = 'values'      # 以字符串类型,还有函数类型,不会用
    # bc.barLabelFormat               = "%0.0f"
    bc.barLabelFormat               = "%d"

    bc.bars[0].fillColor = colors.red
    bc.bars[1].fillColor = colors.orange
    bc.bars[2].fillColor = colors.yellow
    bc.bars[3].fillColor = colors.green

    # 图示
    leg = Legend()
    leg.fontName        = 'simsun'
    leg.alignment       = 'right'                   # 文字在色块的左或者右
    leg.boxAnchor       = 'ne'
    leg.x               = 475                       # 图例的x坐标
    leg.y               = 240
    leg.dxTextSpace     = 10                        # 色块与文字之间的间距
    leg.columnMaximum   = len(legends)
    leg.colorNamePairs  = legends
    drawing.add(leg)
    drawing.add(bc)
    return drawing

def draw_group_bar2(datas: list, labels: list, categorys: list, legends: list):
    drawing = Drawing(500, 280)
    drawing.add(String(45, 260, "多组单条柱状图", fontSize=14, fontName='simsun', fillColor=colors.black))

    bc = VerticalBarChart()
    bc.x                            = 45            # 整个图表的x坐标
    bc.y                            = 45            # 整个图表的y坐标
    bc.height                       = 200           # 图表的高度
    bc.width                        = 350           # 图表的宽度
    bc.data                         = datas
    bc.strokeColor                  = colors.black  # 顶部和右边轴线的颜色
    bc.valueAxis.valueMin           = 5000          # 设置y坐标的最小值
    bc.valueAxis.valueMax           = 26000         # 设置y坐标的最大值
    bc.valueAxis.valueStep          = 2000          # 设置y坐标的步长
    bc.groupSpacing                 = 10            # 每组柱状图之间的间隔
    # bc.barSpacing                   = 1           # 每个柱状图之间的间隔
    bc.categoryAxis.labels.dx       = 2
    bc.categoryAxis.labels.dy       = -8
    bc.categoryAxis.labels.angle    = 20
    bc.categoryAxis.categoryNames   = categorys

    # 图形柱上标注文字
    # bc.barLabels.nudge              = -10           # 文字在图形柱的上下位置
    bc.barLabels.nudge              = 10            # 文字在图形柱的上下位置
    bc.barLabelArray                = labels        # 要添加的文字
    bc.barLabelFormat               = 'values'      # 以字符串类型,还有函数类型,不会用
    # bc.barLabelFormat               = "%0.0f"

    # 每组0-3条的颜色
    bc.bars[0].fillColor = colors.red
    bc.bars[1].fillColor = colors.orange
    bc.bars[2].fillColor = colors.yellow
    bc.bars[3].fillColor = colors.green

    # 每组第0条 也就是数组中 第一个元组的颜色
    bc.bars[(0,0)].fillColor = colors.yellowgreen
    bc.bars[(0,1)].fillColor = colors.blue
    bc.bars[(0,2)].fillColor = colors.purple
    bc.bars[(0,3)].fillColor = colors.peru
    bc.bars[(0,4)].fillColor = colors.pink
    bc.bars[(0,5)].fillColor = colors.coral

    # 第1组(也就是第二组) 第1条(第二条)
    bc.bars[(1,1)].fillColor = colors.gray

    # 图示
    leg = Legend()
    leg.fontName        = 'simsun'
    leg.alignment       = 'left'                    # 文字在色块的左或者右
    leg.boxAnchor       = 'ne'
    leg.x               = 475                       # 图例的x坐标
    leg.y               = 240
    leg.dxTextSpace     = 10                        # 色块与文字之间的间距
    leg.columnMaximum   = len(legends)
    leg.colorNamePairs  = legends
    # drawing.add(leg)
    drawing.add(bc)
    return drawing

def main(filename):
    # pdfmetrics.registerFont(TTFont('微软雅黑', 'msyh.ttf'))
    pdfmetrics.registerFont(TTFont('simsun', "simsun.ttc"))

    doc = SimpleDocTemplate(filename, pagesize=A4)
    Story = []
    datas = [(25400, 12900, 20100, 20300, 20300, 17400)]
    categorys = ['BeiJing', 'ChengDu', 'ShenZhen', 'ShangHai', 'HangZhou', 'NanJing']
    legends = [(colors.red, '标准1'), (colors.orange, '标准2'), (colors.yellow, '标准3'), (colors.green, '标准4')]
    Story.append(draw_group_bar1(datas, categorys, legends))

    datas = [(25400, 12900, 20100, 20300, 20300, 17400),
              (15800, 9700, 12982, 20100, 13900, 7623),]
    labels = [("25400", "12900", "20100", "20300", "20300", "17400"),
              ("15800", "9700", "12982", "20100", "13900", "7623"),]
    categorys = ['BeiJing', 'ChengDu', 'ShenZhen', 'ShangHai', 'HangZhou', 'NanJing']
    legends = [(colors.red, '标准1'), (colors.orange, '标准2'), (colors.yellow, '标准3'), (colors.green, '标准4')]
    Story.append(draw_group_bar2(datas, labels, categorys, legends))

    doc.build(Story)

if __name__ == '__main__': 
    main(filename='example.pdf')

3.3. 柱状图累加

python 复制代码
from reportlab.platypus import SimpleDocTemplate
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

from reportlab.graphics.charts.barcharts import VerticalBarChart    # 图表类
from reportlab.graphics.charts.legends import Legend                # 图例类
from reportlab.graphics.shapes import Drawing                       # 绘图工具
from reportlab.graphics.shapes import String
from reportlab.graphics.charts.textlabels import Label

def func(datas: list):
    minv, maxv, tmpv = 0, 0, 0
    # print(len(datas), datas)
    for idxj,val in enumerate(datas[0]):
        tmpv = 0
        for idxi in range(len(datas)):
            tmpv += datas[idxi][idxj]
        # print("#########333", tmpv)
        if tmpv < minv:
            minv = tmpv
        if tmpv > maxv:
            maxv = tmpv

    return minv, maxv

# 柱状图累加
def draw_group_bar1(datas: list, categorys: list, legends: list):
    drawing = Drawing(500, 280)
    # drawing.add(String(45, 260, "柱状图累加", fontSize=14, fontName='simsun', fillColor=colors.black))
    # 配置图表标题
    title = Label()
    title.setText("柱状图累加")
    # title.fontSize, title.fontName, title.dx, title.dy = 14, "simsun", 45, 260
    title.fontSize, title.fontName, title.x, title.y = 14, "simsun", 45, 260
    drawing.add(title)
    width                           = 350
    height                          = 200

    ### 调整step
    minv, maxv = func(datas)
    maxAxis                         = int(height/20)
    # step                            = int((maxv-minv+maxAxis-1)/maxAxis)    # 向上取整
    step                            = int((maxv-minv)/maxAxis)    # 向上取整

    bc = VerticalBarChart()
    bc.x                            = 45            # 整个图表的x坐标
    bc.y                            = 45            # 整个图表的y坐标
    bc.height                       = height        # 图表的高度
    bc.width                        = width         # 图表的宽度
    bc.data                         = datas
    bc.strokeColor                  = colors.black  # 顶部和右边轴线的颜色
    bc.valueAxis.valueMin           = minv          # 设置y坐标的最小值
    bc.valueAxis.valueMax           = maxv*1.2      # 设置y坐标的最大值
    bc.valueAxis.valueStep          = step          # 设置y坐标的步长
    bc.groupSpacing                 = 10            # 每组柱状图之间的间隔
    # bc.barSpacing                   = 1           # 每条柱状图之间的间隔
    bc.categoryAxis.labels.dx       = 2
    bc.categoryAxis.labels.dy       = -8
    bc.categoryAxis.labels.angle    = 20
    bc.categoryAxis.categoryNames   = categorys

    # 图形柱上标注文字
    # bc.barLabels.nudge              = -10           # 文字在图形柱的上下位置
    bc.barLabels.nudge              = 10            # 文字在图形柱的上下位置
    bc.barLabelFormat               = "%0.0f"

    # 柱状图累加
    bc.categoryAxis.style           = 'stacked'

    # 图形柱上标注文字
    # bc.barLabels.nudge              = -10           # 文字在图形柱的上下位置
    bc.barLabels.nudge              = 10            # 文字在图形柱的上下位置
    # bc.barLabelArray                = labels        # 要添加的文字
    # bc.barLabelFormat               = 'values'      # 以字符串类型,还有函数类型,不会用
    # bc.barLabelFormat               = "%0.0f"
    bc.barLabelFormat               = "%d"

    ## 0-3条柱形图的颜色
    # bc.bars[0].fillColor = colors.red
    # bc.bars[1].fillColor = colors.orange
    # bc.bars[2].fillColor = colors.yellow
    # bc.bars[3].fillColor = colors.green

    colorsb = [colors.yellowgreen, colors.blue, colors.purple, colors.peru, colors.pink, colors.coral] 
    colorsg = [colors.red, colors.orange, colors.yellow, colors.green] 
    for idxi in range(len(datas)):
        setattr(bc.bars[idxi], 'fillColor', colorsg[idxi])  # bar_color若含有多种颜色在这里分配bar_color[j]

    # 图示
    leg = Legend()
    leg.fontName        = 'simsun'
    leg.alignment       = 'right'                   # 文字在色块的左或者右
    leg.boxAnchor       = 'ne'
    leg.x               = 475                       # 图例的x坐标
    leg.y               = 240
    leg.dxTextSpace     = 10                        # 色块与文字之间的间距
    leg.columnMaximum   = len(legends)
    leg.colorNamePairs  = legends
    drawing.add(leg)
    drawing.add(bc)
    return drawing

def draw_group_bar2(datas: list, categorys: list, legends: list):
    drawing = Drawing(500, 280)
    drawing.add(String(45, 260, "多组单条柱状图", fontSize=14, fontName='simsun', fillColor=colors.black))

    width                           = 350
    height                          = 200

    # 调整step
    minv, maxv = func(datas)
    maxAxis                         = int(height/20)
    # step                            = int((maxv-minv+maxAxis-1)/maxAxis)    # 向上取整
    step                            = int((maxv-minv)/maxAxis)    # 向上取整

    bc = VerticalBarChart()
    bc.x                            = 45            # 整个图表的x坐标
    bc.y                            = 45            # 整个图表的y坐标
    bc.height                       = height        # 图表的高度
    bc.width                        = width         # 图表的宽度
    bc.data                         = datas
    bc.strokeColor                  = colors.black  # 顶部和右边轴线的颜色
    bc.valueAxis.valueMin           = minv          # 设置y坐标的最小值
    bc.valueAxis.valueMax           = maxv*1.2      # 设置y坐标的最大值
    bc.valueAxis.valueStep          = step          # 设置y坐标的步长
    bc.groupSpacing                 = 10            # 每组柱状图之间的间隔
    # bc.barSpacing                   = 1           # 每条柱状图之间的间隔
    bc.categoryAxis.labels.dx       = 2
    bc.categoryAxis.labels.dy       = -8
    bc.categoryAxis.labels.angle    = 20
    bc.categoryAxis.categoryNames   = categorys

    # 图形柱上标注文字
    # bc.barLabels.nudge              = -10           # 文字在图形柱的上下位置
    bc.barLabels.nudge              = 10            # 文字在图形柱的上下位置
    bc.barLabelFormat               = "%0.0f"

    # 柱状图累加
    bc.categoryAxis.style           = 'stacked'

    colorsb = [colors.yellowgreen, colors.blue, colors.purple, colors.peru, colors.pink, colors.coral] 
    colorsg = [colors.red, colors.orange, colors.yellow, colors.green] 
    for idxi in range(len(datas)):
        for idxj in range(len(datas[0])):
            if idxi == 0:
                setattr(bc.bars[(idxi, idxj)], 'fillColor', colorsb[idxj])
            else:
                setattr(bc.bars[(idxi, idxj)], 'fillColor', colorsg[idxi])

    # 图示
    leg = Legend()
    leg.fontName        = 'simsun'
    leg.alignment       = 'left'                    # 文字在色块的左或者右
    leg.boxAnchor       = 'ne'
    leg.x               = 475                       # 图例的x坐标
    leg.y               = 240
    leg.dxTextSpace     = 10                        # 色块与文字之间的间距
    leg.columnMaximum   = len(legends)
    leg.colorNamePairs  = legends
    # drawing.add(leg)
    drawing.add(bc)
    return drawing

def main(filename):
    # pdfmetrics.registerFont(TTFont('微软雅黑', 'msyh.ttf'))
    pdfmetrics.registerFont(TTFont('simsun', "simsun.ttc"))

    doc = SimpleDocTemplate(filename, pagesize=A4)
    Story = []
    datas = [(25400, 12900, 20100, 20300, 20300, 17400),
              (15800, 9700, 12982, 20100, 13900, 7623),]
    categorys = ['BeiJing', 'ChengDu', 'ShenZhen', 'ShangHai', 'HangZhou', 'NanJing']
    legends = [(colors.red, '标准1'), (colors.orange, '标准2'), (colors.yellow, '标准3'), (colors.green, '标准4')]
    Story.append(draw_group_bar1(datas, categorys, legends))
    Story.append(draw_group_bar2(datas, categorys, legends))

    doc.build(Story)

if __name__ == '__main__': 
    main(filename='example.pdf')

4. 饼状图

5. Image(图像)

6. 常用颜色

7. 字体与编码

https://blog.csdn.net/qq_40596572/article/details/102896520

字体

https://blog.csdn.net/qtlyx/article/details/99653081

相关推荐
陈苏同学13 分钟前
MPC控制器从入门到进阶(小车动态避障变道仿真 - Python)
人工智能·python·机器学习·数学建模·机器人·自动驾驶
mahuifa17 分钟前
python实现usb热插拔检测(linux)
linux·服务器·python
MyhEhud1 小时前
kotlin @JvmStatic注解的作用和使用场景
开发语言·python·kotlin
狐凄1 小时前
Python实例题:pygame开发打飞机游戏
python·游戏·pygame
漫谈网络1 小时前
Telnet 类图解析
python·自动化·netdevops·telnetlib·网络自动化运维
农夫山泉2号2 小时前
【python】—conda新建python3.11的环境报错
python·conda·python3.11
ZHOU_WUYI3 小时前
Flask Docker Demo 项目指南
python·docker·flask
Lauren_Lu7 小时前
pdf 不是扫描件,但却无法搜索关键词【问题尝试解决未果记录】
pdf
码上淘金8 小时前
【Python】Python常用控制结构详解:条件判断、遍历与循环控制
开发语言·python
Brilliant Nemo8 小时前
四、SpringMVC实战:构建高效表述层框架
开发语言·python