說到pdf文件,大家應該都很熟悉吧,特別是那些經(jīng)常在網(wǎng)上搜索某本書pdf版的人。別裝了,那些人當中應該就有你吧?--開玩笑的,知道你是一向只買正版紙質版的人。
買正版紙質的人?好像扯遠了。好吧,言歸正傳,咱說一下Python3處理pdf相關的內容。
Python3處理pdf的第3庫挺多的,當然,處理其它文件的庫也多。這次咱就說下耳熟能詳、久經(jīng)戰(zhàn)場并被最、最、最被看好的ReportLab。
若要想要獲得ReportLab的支持,得先安裝它的開發(fā)包。打開【終端】,輸入那句,閉著眼,都會輸錯的命令:pip3 install reportlab。稍等一會會,就能安裝完了,究竟多長時間,你可以用手機記一下時間,如果實在閑得無聊的話。
安裝好開發(fā)包后,咱就來寫寫如何生成pdf文件并送給經(jīng)常下載它同類的你。來,打開你喜歡的開發(fā)工具,輸入以下代碼。
from reportlab.pdfgen import canvas
def write_pdf():
c=canvas.Canvas("demo1.pdf")
# 注意,這里用英文,不是因為我英文好,而是默認不支持中文
c.drawString(200, 500, "Hello PDF")
# 不信默認不支持中文,咱走著瞧
c.drawString(200, 550, "你好,PDF文件")
c.showPage()
c.save()
write_pdf()
說明
1.1 reportlab高級制作多格式PDF:即包含文字、表格、柱狀圖。
1.2 復習python的class和裝飾器的高級基礎知識。
1.3 列表轉換字符串、讀取txt文件等python基礎知識。
1.4 經(jīng)典,通俗易懂,適合收藏和轉發(fā)。
2 reportlab高級制作多格式PDF
2.1 代碼
#---導入模塊---有點多,且繁瑣,可以優(yōu)化---
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
#---導入中文字體模塊和注冊---
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
#hwfs是hwfs字體,自己下載,放在根目錄下
pdfmetrics.registerFont(TTFont('hwfs', 'hwfs.ttf'))
#---定義類---
class Graphs:
def __init__(self):
pass
# 裝飾器:繪制標題
@staticmethod
def draw_title():
style=getSampleStyleSheet()
#格式
ct=style['Normal']
#字體名,上面已經(jīng)注冊過的
ct.fontName='hwfs'
#字體大小
ct.fontSize=18
# 設置行距
ct.leading=50
# 顏色
ct.textColor=colors.green
# 居中
ct.alignment=1
# 添加標題并居
title=Paragraph('reportlab高級制作PDF', ct)
return title
# 繪制內容
@staticmethod
def draw_text():
style=getSampleStyleSheet()
# 常規(guī)字體(非粗體或斜體)
ct=style['Normal']
# 使用的字體s
ct.fontName='hwfs'
ct.fontSize=14
# 設置自動換行
ct.wordWrap='CJK'
# 居左對齊
ct.alignment=0
# 第一行開頭空格
ct.firstLineIndent=32
# 設置行距
ct.leading=30
#格式:Paragraph(text, style, bulletText=None, frags=None, caseSensitive=1, encoding='utf8')
#注意文件目錄和文件內容,調用外部txt文件內容
with open('/home/xgj/Desktop/reportlab/2.txt','r') as f:
#讀取全部,返回一個列表
text2=f.readlines()
#列表轉換為字符串,返回是一大串字符串,如果文字較多而且有分段落的,可能就不適合。
text1=''.join(text2)
#print(text1)
text=Paragraph(text1,ct)
return text
# 繪制表格
@staticmethod
def draw_table(*args):
#寬度
col_width=60
#表格樣式設置
style=[
('FONTNAME', (0, 0), (-1, -1), 'hwfs'),# 字體
('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),# 設置第一行背景顏色
('ALIGN', (0, 0), (-1, -1), 'CENTER'),# 對齊
('VALIGN', (-1, 0), (-2, 0), 'MIDDLE'),# 對齊
('GRID', (0, 0), (-1, -1), 0.5, colors.grey),# 設置表格框線為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='hwfs'
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__":
#生成的pdf的內容
#content=list()
content=[]
# 第一:文章的標題
content.append(Graphs.draw_title())
# 第二:添加文章的文字段落
content.append(Graphs.draw_text())
# 第三:表格:
# 表格數(shù)據(jù)
data=[
('項目', '2019-11', '2019-12', '2020-1', '2020-2', '2020-3', '2020-4'),
('python', 50, 80, 60, 35, 40, 45),
('JavaScript', 25, 60, 55, 45, 60, 80),
('c++', 30, 90, 75, 80, 50, 46)]
#添加表格
content.append(Graphs.draw_table(*data))
# 第四:圖表
#圖標的數(shù)據(jù)
b_data=[
(50, 80, 60, 35, 40, 45),
(25, 60, 55, 45, 60, 80),
(30, 90, 75, 80, 50, 46)
]
ax_data=['2019-11', '2019-12', '2020-1', '2020-2', '2020-3', '2020-4']
leg_items=[(colors.red, 'python'), (colors.green, 'JavaScript'), (colors.blue, 'c++')]
# 附加:添加文章的文字段落
#content.append(Graphs.draw_text())
#添加圖標柱狀圖
content.append(Graphs.draw_bar(b_data, ax_data, leg_items))
# 生成pdf文件
newpdf=SimpleDocTemplate('/home/xgj/Desktop/reportlab/report.pdf', pagesize=letter)
newpdf.build(content)
2.2 圖
3 python的class類:
3.1 python的面向對象是一種編程方式,此編程方式的實現(xiàn)是基于對類和對象的使用。
類是一個模板,模板中包裝了多個“函數(shù)”供使用。
對象,根據(jù)模板創(chuàng)建的實例(即:對象),實例用于調用被包裝在類中的函數(shù)。
面向對象三大特性:封裝、繼承和多態(tài)。
3.2 Python 3.x中取消了經(jīng)典類,默認都是新式類。
新式類的語法 -> class 類名(object): pass
3.3 通過例子來講解新式類的語法
代碼:
#方法一
#定義person這個類
#class person(object): #與下面相同作用,也就是object這個對象就是下面的內容
class person():
#定義speak函數(shù)
def speak(self): #person對象調用了speak函數(shù)的這個方法,self就是那個對象;可以把self理解為一個形參
print("%s 說:我今年%s歲" % (self.name, self.age))
#類person 實例化一個對象chaxun
chaxun=person()
# 給對象查詢chaxun添加屬性,用‘點’
chaxun.name="李白"
chaxun.age=1000
# 調用類中的 speak()方法
chaxun.speak()
#方法二
#class person(object): #與下面相同
class person():
# 定義構造方法
#__init__() 是類的初始化方法;它在類的實例化操作后 會自動調用,不需要手動調用
def __init__(self, n, a):
# 設置屬性
self.name=n
self.age=a
# 定義普通方法
def speak(self):
print("%s 說:我今年%s歲" % (self.name, self.age))
#類person 實例化一個對象chaxun
chaxun=person("李白",1000)
# 調用類中的 speak()方法
chaxun.speak()
# 在python中使用__開頭 并以__結尾的方法,稱之為魔法方法;
# __init__(self) 是類的初始化方法,也稱構造方法,是一種特殊的魔法方法。
# __init__(self)在實例化后,會自動調用,而不用手動調用,所以一般把屬性設置在_init__()里。
# 常用到的魔法方法還有:__str__(self) 、 __del__(self)等。
============
4 python3的裝飾器:
4.1 理解裝飾器的前提:
4.1.1 所有東西都是對象(函數(shù)可以當做對象傳遞)
4.1.2.閉包
4.2 閉包的概念:
1)函數(shù)嵌套
2)內部函數(shù)使用外部函數(shù)的變量
3)外部函數(shù)的返回值為內部函數(shù)
4.3 使用裝飾器的缺點:
4.3.1.位置錯誤的代碼->不要在裝飾器之外添加邏輯功能
4.3.2.不能裝飾@staticmethod (第一個代碼中使用)或者 @classmethod已經(jīng)裝飾過的方法
4.3.3.裝飾器會對原函數(shù)的元信息進行更改,比如函數(shù)的docstring,__name__,參數(shù)列表。
裝飾器需要實例講解更清楚,暫時到這里,喜歡的收藏和轉發(fā),自己整理,分享出來。
=========未完待續(xù)==========
平時工作中,習慣了匯總與總結。匯總了相關數(shù)據(jù)后,經(jīng)常會把總結內容制作成相關報表,以供領導審閱。每當見到領導發(fā)出嘖嘖的贊嘆聲時,我也就心滿意足了。
可一想到,每次做的都是重復,寡淡無味的內容時,未免心里有了些許的失落,關鍵是領導每次都只是口頭表揚兩句,沒有實際的行動,我想你知道我說的什么意思。
好在咱是程序員,可以用Python3中的ReportLab生成pdf報表,以解眼前的尷尬。若要獲得ReportLab開發(fā)包的功能,需要在【終端】窗口,通過pip3 install reportlab命令進行安裝,安裝成功的截圖在這。
不知你的領導是如何的,反正我的領導就喜歡看圖文并茂的報表。記得有一次,實在沒數(shù)據(jù)可用,我就放一張漂亮的女明星照在上面。你還別說,這招真管用,平時反饋很慢的領導,那次一看完就馬上來找我了--直接劈頭蓋臉的把我罵了一頓,說我放的女明星是PS過的…。我一時語塞,不知怎么回答才好,只好埋下頭,眼里含著淚,默默地敲出了以下代碼。
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
# 注冊字體
pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))
class Graphs:
def __init__(self):
pass
# 繪制標題
@staticmethod
def draw_title():
style=getSampleStyleSheet()
ct=style['Normal']
ct.fontName='SimSun'
ct.fontSize=18
# 設置行距
ct.leading=50
# 顏色
ct.textColor=colors.green
# 居中
ct.alignment=1
# 添加標題并居中
title=Paragraph('程序員的興趣調查報告', ct)
return title
# 繪制內容
@staticmethod
def draw_text():
style=getSampleStyleSheet()
# 常規(guī)字體(非粗體或斜體)
ct=style['Normal']
# 使用的字體s
ct.fontName='SimSun'
ct.fontSize=14
# 設置自動換行
ct.wordWrap='CJK'
# 居左對齊
ct.alignment=0
# 第一行開頭空格
ct.firstLineIndent=32
# 設置行距
ct.leading=30
text=Paragraph('程序員,是互聯(lián)網(wǎng)、移動互聯(lián)網(wǎng)和即將到來的物聯(lián)網(wǎng)時期的弄潮兒。'
'這群特立獨行的人才,不知平時最喜歡什么?他們的興趣真想讓人一探究竟。'
'經(jīng)過七七49天的調研,終于形成了一份不具備權威性的統(tǒng)計報告--《程序員2019年上半年興趣調查報告》,現(xiàn)公布出來,以饗讀者。', ct)
return text
# 繪制表格
@staticmethod
def draw_table(*args):
col_width=60
style=[
('FONTNAME', (0, 0), (-1, -1), 'SimSun'), # 字體
('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'), # 設置第一行背景顏色
('ALIGN', (0, 0), (-1, -1), 'CENTER'), # 對齊
('VALIGN', (-1, 0), (-2, 0), 'MIDDLE'), # 對齊
('GRID', (0, 0), (-1, -1), 0.5, colors.grey), # 設置表格框線為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()
# 添加標題
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)
*請認真填寫需求信息,我們會在24小時內與您取得聯(lián)系。