Reportlab生成PDF文件

     - 使用类TableWidget生成的对象添加表格列出直方图数据柱代表的数据

     - 数据柱指定填充颜色,带黑边

     - 两种情况下不显示数据柱标签,一个是设置直方图的barLabels.visible为False(默认为True),一个是直方图的self.chart.barLabelFormat为None(默认就是None)

"带表格的直方图"
from reportlab.lib.colors import PCMYKColor, black, red
from reportlab.graphics.charts.legends import Legend
from reportlab.graphics.shapes import Drawing, _DrawingEditorMixin, String, Line
from reportlab.lib.validators import Auto
from reportlab.graphics.widgets.table import TableWidget
from reportlab.lib.formatters import DecimalFormatter
from reportlab.graphics.charts.barcharts import VerticalBarChart

class BarChart_Table(_DrawingEditorMixin,Drawing):
    def __init__(self,width=403,height=163,*args,**kw):
        Drawing.__init__(self,width,height,*args,**kw)
        fontName = 'Helvetica'
        fontSize = 5
        bFontName = 'Times-Bold'    # 刻度标签和表格中的字体
        bFontSize = 7               # 刻度标签和表格中的字体大小

        self._add(self,VerticalBarChart(),name='chart',validate=None,desc=None)
        self.chart.height                  = 73
        self.chart.width           = 250
        self.chart.fillColor               = PCMYKColor(0, 3, 7, 6) # 图表的背景色
        self.chart.data                    = \
        [[7.7199999999999998, 7.9400000000000004, 9.1699999999999999, 7.04, 7.7199999999999998, 8.1699999999999999],
         [4.46, 1.97, 13.220000000000001, 10.49, 8.5800000000000001, 10.74],
         [5.1399999999999997, 9.5999999999999996, 5.3099999999999996, 4.4699999999999998, 3.5099999999999998, 4.8399999999999999]]
        # 数据柱周线的宽度和颜色
        self.chart.bars.strokeWidth        = 0.5
        self.chart.bars.strokeColor        = PCMYKColor(0,0,0,100)
        self.chart.barWidth        = 2
        self.chart.barSpacing      = 0.5        # 同组数据柱的间距
        self.chart.groupSpacing    = 5          # 组与组的间距

        # 指定数据柱的颜色
        colorsList = [PCMYKColor(0, 73, 69, 56), PCMYKColor(23,51,0,4),
                      PCMYKColor(41, 25, 0, 21)]
        for i, color in enumerate(colorsList):
            self.chart.bars[i].fillColor = color

        # 设置数据轴(y轴)的属性
        self.chart.valueAxis.labels.fontName       = fontName       # 刻度标签的字体和字体大小
        self.chart.valueAxis.labels.fontSize       = fontSize
        self.chart.valueAxis.visibleGrid           = False          # 格子线不可见
        self.chart.valueAxis.visibleTicks          = False          # 刻度线不可见
        self.chart.valueAxis.strokeWidth           = 0.25           # 轴线宽度
        self.chart.valueAxis.avoidBoundFrac        = 0              # 影响数轴刻度值表达范围
        # self.chart.valueAxis.avoidBoundFrac        = 1
        self.chart.valueAxis.rangeRound             ='both'
        self.chart.valueAxis.labelTextFormat        = None          # 刻度的格式
        # self.chart.valueAxis.labelTextFormat        = DecimalFormatter(1, suffix=None, prefix=None)
        self.chart.valueAxis.forceZero              = True          # 强制显示0刻度
        self.chart.valueAxis.labels.boxAnchor       = 'e'           # 刻度标签的锚点
        self.chart.valueAxis.labels.dx              = -1            # 微调刻度标签的位置

        # 设置类别轴(x轴)的属性
        self.chart.categoryAxis.visibleGrid         = False         # 格子线不可见
        self.chart.categoryAxis.visibleTicks        = False         # 刻度线不可见
        self.chart.categoryAxis.strokeWidth         = 0.25          # 轴线宽度
        self.chart.categoryAxis.labelAxisMode       ='low'          # 刻度标签显示在图表底部
        # self.chart.categoryAxis.labelAxisMode       ='high'       # 刻度标签显示在图表顶部
        # self.chart.categoryAxis.labelAxisMode       ='axis'       # 刻度标签显示在坐标轴
        # self.chart.categoryAxis.labelAxisMode       ='axispmv'    # 刻度标签显示在坐标轴附近
        self.chart.categoryAxis.labels.fillColor    = black         # 刻度标签的颜色
        # self.chart.categoryAxis.labels.fillColor    = red
        self.chart.categoryAxis.labels.angle        = 0             # 刻度标签的角度
        self.chart.categoryAxis.labels.fontName     = bFontName     # 刻度标签的字体和字体大小
        self.chart.categoryAxis.labels.fontSize     = bFontSize
        self.chart.categoryAxis.labels.boxAnchor    = 'e'           # 刻度标签的锚点
        self.chart.categoryAxis.labels.dx           = 7             # 微调刻度标签的位置
        self.chart.categoryAxis.labels.dy           = -5
        self.chart.categoryAxis.categoryNames = ['200%d'%i for i in range(1,7)]
        # 列表的每个元素是一个字符串'200%d',%d的位置放一个数字,数字是循环变量i,从1到6

        self._add(self,Legend(),name='legend',validate=None,desc=None)
        self.legend.fontName         = fontName
        self.legend.fontSize         = fontSize
        self.legend.strokeWidth      = 0.5
        self.legend.strokeColor      = PCMYKColor(0,0,0,100)
        self.legend.dx               = 8                    # 色宽的宽高
        self.legend.dy               = 5
        self.legend.variColumn       = True                 # 列宽可变
        self.legend.subCols.minWidth = self.chart.width/2   # 最小列宽
        self.legend.dxTextSpace    = 5                      # 色块与文字间距
        self.legend.deltax         = 0                      # 色块之间x方向间距
        self.legend.deltay           = 8                    # 色块之间y方向间距
        self.legend.alignment      = 'right'                # 文字在色块右边
        self.legend.columnMaximum  = 3                      # 每一列最多3行
        self.legend.boxAnchor      = 'sw'                   # 锚点在西南角(sw)
        self.legend.colorNamePairs   = Auto(obj=self.chart)
        # 启动自动模式配置色块与文字的对应关系,前提是有对bars[i].name赋值(后面又做)

        self._add(self,TableWidget(),name='table',validate=None,desc=None)
        # 表格周线的颜色和宽度
        self.table.borderStrokeColor = PCMYKColor(0, 12, 24, 36)
        self.table.borderStrokeWidth = 0.5
        # 表格填充色
        self.table.fillColor = PCMYKColor(0, 3, 7, 6)
        # 表格内部水平垂直格线的颜色和宽度
        self.table.horizontalDividerStrokeColor = PCMYKColor(0, 12, 24, 36)
        self.table.horizontalDividerStrokeWidth = 0.5
        # 垂直线不显示
        self.table.verticalDividerStrokeColor = None
        self.table.verticalDividerStrokeWidth = 0
        self.table.dividerDashArray = None      # 没有虚线样式
        # 设置表格内容
        self.table.data = [['BP', None] + self.chart.data[0],
                           ['Shell Transport & Trading', None] + self.chart.data[1],
                           ['Liberty International', None]  + self.chart.data[2]]
        # 有None是为了给第一列多些空间
        self.table.boxAnchor = 'sw'             # 表格锚点
        self.table.fontName = bFontName         # 表格内字体和字体大小
        self.table.fontSize = bFontSize
        self.table.fontColor = black            # 表格内文字的颜色
        self.table.height           = 45
        self.table.width            = 400

        for i in range(len(self.chart.data)):
            self.chart.bars[i].name = self.table.data[i][0]
        # 赋值每个数据柱的name属性

        # 调整各部分的位置和大小
        self.width                 = 400
        self.height                = 200
        self.chart.y               = 75
        self.chart.x               = 140
        self.legend.x              = 24
        self.legend.y              = 75
        self.table.x               = 0
        self.table.y               = 0

if __name__=="__main__":
    BarChart_Table().save(formats=['pdf'],outDir='.',fnRoot=None)