在平時(shí)工作中廊酣,習(xí)慣了匯總與總結(jié)能耻。匯總了相關(guān)數(shù)據(jù)后,經(jīng)常會(huì)把總結(jié)內(nèi)容制作成相關(guān)報(bào)表亡驰,以供領(lǐng)導(dǎo)審閱晓猛。每當(dāng)見到領(lǐng)導(dǎo)發(fā)出嘖嘖的贊嘆聲時(shí),我也就心滿意足了隐解。
可一想到鞍帝,每次做的都是重復(fù),寡淡無(wú)味的內(nèi)容時(shí)煞茫,未免心里有了些許的失落帕涌,關(guān)鍵是領(lǐng)導(dǎo)每次都只是口頭表?yè)P(yáng)兩句,沒有實(shí)際的行動(dòng)续徽,我想你知道我說(shuō)的什么意思蚓曼。
1
好在咱是程序員,可以用Python3中的ReportLab生成pdf報(bào)表钦扭,以解眼前的尷尬纫版。若要獲得ReportLab開發(fā)包的功能,需要在【終端】窗口客情,通過(guò)pip3 install reportlab命令進(jìn)行安裝其弊,安裝成功的截圖在這。
2
不知你的領(lǐng)導(dǎo)是如何的膀斋,反正我的領(lǐng)導(dǎo)就喜歡看圖文并茂的報(bào)表梭伐。記得有一次,實(shí)在沒數(shù)據(jù)可用仰担,我就放一張漂亮的女明星照在上面糊识。你還別說(shuō),這招真管用,平時(shí)反饋很慢的領(lǐng)導(dǎo)赂苗,那次一看完就馬上來(lái)找我了--直接劈頭蓋臉的把我罵了一頓愉耙,說(shuō)我放的女明星是PS過(guò)的…。我一時(shí)語(yǔ)塞拌滋,不知怎么回答才好朴沿,只好埋下頭,眼里含著淚鸠真,默默地敲出了以下代碼悯仙。
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import Table, SimpleDocTemplate, Paragraph
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.graphics.charts.barcharts import VerticalBarChart
from reportlab.graphics.charts.legends import Legend
from reportlab.graphics.shapes import Drawing
#?注冊(cè)字體
pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))
class Graphs:
?def __init__(self):
?pass
?#?繪制標(biāo)題
?@staticmethod
?def draw_title():
?style = getSampleStyleSheet()
?ct = style['Normal']
?ct.fontName = 'SimSun'
?ct.fontSize = 18
?#?設(shè)置行距
?ct.leading = 50
?#?顏色
?ct.textColor = colors.green
?#?居中
?ct.alignment = 1
?#?添加標(biāo)題并居中
?title = Paragraph('程序員的興趣調(diào)查報(bào)告', ct)
?return title
?#?繪制內(nèi)容
?@staticmethod
?def draw_text():
?style = getSampleStyleSheet()
?#?常規(guī)字體(非粗體或斜體)
?ct = style['Normal']
?#?使用的字體s
?ct.fontName = 'SimSun'
?ct.fontSize = 14
?#?設(shè)置自動(dòng)換行
?ct.wordWrap = 'CJK'
?#?居左對(duì)齊
?ct.alignment = 0
?#?第一行開頭空格
?ct.firstLineIndent = 32
?#?設(shè)置行距
?ct.leading = 30
?text = Paragraph('程序員龄毡,是互聯(lián)網(wǎng)吠卷、移動(dòng)互聯(lián)網(wǎng)和即將到來(lái)的物聯(lián)網(wǎng)時(shí)期的弄潮兒。'
?'這群特立獨(dú)行的人才沦零,不知平時(shí)最喜歡什么?他們的興趣真想讓人一探究竟祭隔。'
?'經(jīng)過(guò)七七49天的調(diào)研,終于形成了一份不具備權(quán)威性的統(tǒng)計(jì)報(bào)告--《程序員2019年上半年興趣調(diào)查報(bào)告》路操,現(xiàn)公布出來(lái)疾渴,以饗讀者。', ct)
???????return text
?#?繪制表格
?@staticmethod
?def draw_table(*args):
?col_width = 60
?style = [
?('FONTNAME', (0, 0), (-1, -1), 'SimSun'),?#?字體
?('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),?#?設(shè)置第一行背景顏色
???('ALIGN', (0, 0), (-1, -1), 'CENTER'),?#?對(duì)齊
?('VALIGN', (-1, 0), (-2, 0), 'MIDDLE'),?#?對(duì)齊
?('GRID', (0, 0), (-1, -1), 0.5, colors.grey),?#?設(shè)置表格框線為grey色屯仗,線寬為0.5
?]
?table = Table(args, colWidths=col_width, style=style)
?return table
?#?創(chuàng)建圖表
?@staticmethod
?def draw_bar(bar_data=[], ax=[], items=[]):
?drawing = Drawing(500, 250)
?bc = VerticalBarChart()
?bc.x = 35
?bc.y = 100
?bc.height = 120
?bc.width = 350
?bc.data = bar_data
?bc.strokeColor = colors.black
?bc.valueAxis.valueMin = 0
?bc.valueAxis.valueMax = 100
?bc.valueAxis.valueStep = 10
?bc.categoryAxis.labels.dx = 8
?bc.categoryAxis.labels.dy = -10
??bc.categoryAxis.labels.angle = 20
?bc.categoryAxis.categoryNames = ax
?#?圖示
?leg = Legend()
?leg.fontName = 'SimSun'
?leg.alignment = 'right'
?leg.boxAnchor = 'ne'
?leg.x = 465
?leg.y = 220
?leg.dxTextSpace = 10
?leg.columnMaximum = 3
?leg.colorNamePairs = items
?drawing.add(leg)
?drawing.add(bc)
?return drawing
if __name__ == "__main__":
?content = list()
?#?添加標(biāo)題
?content.append(Graphs.draw_title())
?#?添加段落
?content.append(Graphs.draw_text())
?#?添加表格數(shù)據(jù)
?data = [('興趣', '2019-1', '2019-2', '2019-3', '2019-4', '2019-5', '2019-6'),
?('開發(fā)', 50, 80, 60, 35, 40, 45),
?('編程', 25, 60, 55, 45, 60, 80),
?('敲代碼', 30, 90, 75, 80, 50, 46)]
?content.append(Graphs.draw_table(*data))
?#?添加圖表
?b_data = [(50, 80, 60, 35, 40, 45), (25, 60, 55, 45, 60, 80), (30, 90, 75, 80, 50, 46)]
?ax_data = ['2019-1', '2019-2', '2019-3', '2019-4', '2019-5', '2019-6']
?leg_items = [(colors.red, '開發(fā)'), (colors.green, '編程'), (colors.blue, '敲代碼')]
?content.append(Graphs.draw_bar(b_data, ax_data, leg_items))
?#?生成pdf文件
?doc = SimpleDocTemplate('report.pdf', pagesize=letter)
?doc.build(content)