用python 產生 PDF檔案

一、安裝

pip install reportlab

若有問題,就用 conda 環境下安裝,比較沒問題

二、執行範例

from reportlab.platypus import SimpleDocTemplate, Paragraph
fileName = "example.pdf"
pdfTemplate = SimpleDocTemplate(fileName)
story = []
story.append(Paragraph("Hello World"))
pdfTemplate.build(story)

即可產生PDF檔案

三、解決中文問題

1.下載 SimSun.ttf

https://github.com/StellarCN/scp_zh/blob/master/fonts/SimSun.ttf

2.放到正確路徑下

C:\Users\111.conda\envs\snapcam\Lib\site-packages\reportlab\fonts

3.寫測試範例程式碼:

from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, TableStyle, Table

pdfmetrics.registerFont(TTFont('SimSun', "SimSun.ttf"))
fileName = "example2.pdf"
pdfTemplate = SimpleDocTemplate(fileName)
story = []

tableStyle = TableStyle([
    ('ALIGN', (0, 0), (-1, -1), 'CENTER'), # 置中對齊
    ('FONTNAME', (0, 0), (-1, -1), 'SimSun'), # 字體
    ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # 上下置中
    ('GRID', (0, 0), (-1, -1), 0.5, colors.black), # 框線黑色,寬度0.5
])

dataList = [
    ["測試", "2", "3", "4"],
    ["5", "測試一qweqw一", "7", "8"],
    ["9", "10", "11", "12"],
    ["13", "14", "15", "16"],
]

table = Table(dataList, style=tableStyle)
story.append(table)
pdfTemplate.build(story)

四、產生報表範例

from reportlab.pdfbase import pdfmetrics   # 注册字体
from reportlab.pdfbase.ttfonts import TTFont # 字体类
from reportlab.platypus import Table, SimpleDocTemplate, Paragraph, Image  # 报告内容相关类
from reportlab.lib.pagesizes import letter  # 页面的标志尺寸(8.5*inch, 11*inch)
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.lib.units import cm  # 单位:cm

# 注册字体(提前准备好字体文件, 如果同一个文件需要多种字体可以注册多个)
pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))

class Graphs:
    # 绘制标题
    @staticmethod
    def draw_title(title: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 拿到标题样式
        ct = style['Heading1']
        # 单独设置样式相关属性
        ct.fontName = 'SimSun'      # 字体名
        ct.fontSize = 24            # 字体大小
        ct.leading = 50             # 行间距
        ct.textColor = colors.green     # 字体颜色
        ct.alignment = 1    # 居中
        ct.bold = True
        # 创建标题对应的段落,并且返回
        return Paragraph(title, ct)
 
  # 绘制小标题
    @staticmethod
    def draw_little_title(title: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 拿到标题样式
        ct = style['Normal']
        # 单独设置样式相关属性
        ct.fontName = 'SimSun'  # 字体名
        ct.fontSize = 15  # 字体大小
        ct.leading = 30  # 行间距
        ct.textColor = colors.red  # 字体颜色
        # 创建标题对应的段落,并且返回
        return Paragraph(title, ct)

    # 绘制普通段落内容
    @staticmethod
    def draw_text(text: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 获取普通样式
        ct = style['Normal']
        ct.fontName = 'SimSun'
        ct.fontSize = 12
        ct.wordWrap = 'CJK'     # 设置自动换行
        ct.alignment = 0        # 左对齐
        ct.firstLineIndent = 32     # 第一行开头空格
        ct.leading = 25
        return Paragraph(text, ct)

    # 绘制表格
    @staticmethod
    def draw_table(*args):
        # 列宽度
        col_width = 120
        style = [
            ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 字体
           # ('FONTSIZE', (0, 0), (-1, 0), 12),  # 第一行的字体大小
           # ('FONTSIZE', (0, 1), (-1, -1), 10),  # 第二行到最后一行的字体大小
            ('FONTSIZE', (0, 0), (-1, -1), 12),
           # ('BACKGROUND', (0, 0), (0, -1), '#d5dae6'),  # 设置第一行背景颜色
          #  ('ALIGN', (0, 0), (-1, -1), 'DECIMAL'),  # 第一行水平居中
          
            ('ALIGN', (0, 0), (-1, -1), 'RIGHT'),  # 第二行到最后一行左右左对齐
            ('ALIGN', (1, 0), (-1, -1), 'LEFT'),  # 第二行到最后一行左右左对齐  
            ('ALIGN', (2, 0), (-1, -1), 'RIGHT'),  # 第二行到最后一行左右左对齐            
            ('ALIGN', (3, 0), (-1, -1), 'LEFT'),  # 第二行到最后一行左右左对齐              
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色
            ('GRID', (0, 0), (-1, -1), 0.5, colors.white),  # 设置表格框线为grey色,线宽为0.5

        ]
        table = Table(args, colWidths=col_width, style=style)
        return table

    def draw_table1(*args):
        # 列宽度
        col_width1 = 100
        style = [
            ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 字体
            ('FONTSIZE', (0, 0), (-1, -1), 12),      
            ('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色   
            ('ALIGN', (0, 0), (-1, 0), 'CENTER'),  # 名稱            
            ('ALIGN', (0, 1), (-1, -1), 'LEFT'),  # 名稱
            ('ALIGN', (1, 1), (-1, -1), 'CENTER'),  # 數量            
            ('ALIGN', (2, 1), (-1, -1), 'RIGHT'),  # 單價    
            ('ALIGN', (3, 1), (-1, -1), 'RIGHT'),  # 總價            
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色
            ('GRID', (0, 0), (-1, -1), 0.5, colors.black),  # 设置表格框线为grey色,线宽为0.5

        ]
        table1 = Table(args, colWidths=col_width1, style=style)
        return table1


    # 绘制图片
    @staticmethod
    def draw_img(path):
        img = Image(path)       # 读取指定路径下的图片
        img.drawWidth = 5*cm        # 设置图片的宽度
        img.drawHeight = 8*cm       # 设置图片的高度
        return img
        

if __name__ == '__main__':
    # 创建内容对应的空列表
    content = list()

    # 添加标题
    content.append(Graphs.draw_title('思納捷充電樁估價單'))

    # 添加表格
    data = [
        ('社區名稱:', '國泰皇家',         '估價日期:','113/1/1'),
        ('社區住址:', '台北市',           '估價編號:','0001'),        
        ('聯絡姓名:', '吳大濱',           '負責人員:','陳彥甫'),
        ('連絡電話:', '0912882881',       '負責電話:','0912882881'),
        ('電子郵件:', 'chencef@gmail.com','電子郵件:','chencef@gmail.com')
    ]   
    content.append(Graphs.draw_table(*data))
    content.append(Graphs.draw_title(''))  
    content.append(Graphs.draw_title(''))
    
    data = [
        ('品  名', '數  量','單  價','總  價'),
        ('項目一', '1','100','100'),
        ('項目一', '1','2000','2000'),        
        ('項目一', '1','3000','3000'),
        ('項目一', '2','2000','4000'),
        ('項目一', '4','2222','8888'),
        ('項目一', '1','100','100'),
        ('項目一', '1','2000','2000'),        
        ('項目一', '1','3000','3000'),
        ('項目一', '2','2000','4000'),
        ('項目一', '4','2222','8888'),
        ('', '','總金額','48888'),        
    ] 
    content.append(Graphs.draw_table1(*data))
    content.append(Graphs.draw_title('')) 
    content.append(Graphs.draw_title(''))
    
    content.append(Graphs.draw_little_title('估價說明:'))    
    # 添加段落文字
    content.append(Graphs.draw_text('近几年数据分析热席卷了整个互联网行业,与数据分析的相关的岗位招聘、培训数不胜数。很多人前赴后继,想要参与到这波红利当中。那么数据分析师就业前景到底怎么样呢?'))

    content.append(Graphs.draw_little_title('現場照片:')) 
    # 添加图片
    content.append(Graphs.draw_img('1111.png'))

    # 生成pdf文件
    doc = SimpleDocTemplate('report.pdf', pagesize=letter)
    doc.build(content)        
相关推荐
Am心若依旧40916 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生18 分钟前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
大G哥28 分钟前
java提高正则处理效率
java·开发语言
ROBOT玲玉32 分钟前
Milvus 中,FieldSchema 的 dim 参数和索引参数中的 “nlist“ 的区别
python·机器学习·numpy
VBA633738 分钟前
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
开发语言
轩辰~40 分钟前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
小_太_阳1 小时前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it1 小时前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
Kai HVZ1 小时前
python爬虫----爬取视频实战
爬虫·python·音视频
古希腊掌管学习的神1 小时前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode