使用ReportLab生成带表格和图文的PDF

本文详细介绍了如何使用Python的reportlab库创建PDF文档,包括设置页面布局、注册中文字体、创建样式、绘制折线图、表格和图像。展示了如何在文档中插入图表和数据,以及如何使用线程和调度来组织生成过程。
摘要由CSDN通过智能技术生成

1.引用包

import os

from reportlab.graphics.charts.lineplots import LinePlot

from reportlab.graphics.charts.piecharts import Pie

from reportlab.graphics.shapes import Drawing

from reportlab.lib import colors

from reportlab.lib.styles import ParagraphStyle

from reportlab.pdfbase import pdfmetrics

from reportlab.pdfbase.pdfmetrics import registerFontFamily

from reportlab.pdfbase.ttfonts import TTFont

from reportlab.platypus import Paragraph

from reportlab.platypus import Spacer, SimpleDocTemplate, Table, Paragraph, Image,TableStyle

import datetime

import matplotlib.pyplot as plt

import pymysql

from reportlab.graphics.charts.barcharts import VerticalBarChart

from reportlab.graphics.charts.linecharts import HorizontalLineChart

from reportlab.graphics.charts.lineplots import LinePlot

from reportlab.graphics.charts.piecharts import Pie

from reportlab.graphics.shapes import *

from reportlab.graphics.widgets.markers import makeMarker

from reportlab.lib.enums import TA_CENTER

from reportlab.lib.pagesizes import A4

from reportlab.lib.pagesizes import letter, landscape

from reportlab.lib.styles import ParagraphStyle

from reportlab.pdfbase import pdfmetrics

from reportlab.pdfbase.ttfonts import TTFont

from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer

import numpy as np

import time

from reportlab.lib.units import inch

from reportlab.graphics.shapes import Image as DrawingImage

from reportlab.graphics.charts.textlabels import Label

import queue

import threading

import schedule

from reportlab.pdfgen.canvas import Canvas

from reportlab.lib.styles import getSampleStyleSheet

 

2. # 创建文档,设置页边距,纸张大小,横向

  doc= SimpleDocTemplate("output/"+textName+".pdf",rightMargin=22,leftMargin=22,topMargin=10,bottomMargin=18,pagesize=landscape(letter))

3.设置样式及字体,解决中文乱码问题

home = os.path.expanduser("~")

msyh = "msyh"

msyhbd = "msyhbd"

song = "simsun"

xinsong ="xinsong"

pdfmetrics.registerFont(TTFont(song, "simsun.ttc"))

pdfmetrics.registerFont(TTFont(msyh, "msyh.ttc"))

pdfmetrics.registerFont(TTFont(msyhbd, "msyhbd.ttc"))

pdfmetrics.registerFont(TTFont(xinsong, "STXINGKA.TTF"))

current_date = datetime.date.today()

# 创建样式

styles = getSampleStyleSheet()

normal_style = styles['Normal']

custom_style = ParagraphStyle(

    'CustomStyle',                     # 样式名称

    parent=styles['Normal'],           # 继承默认样式

    fontName=song,              # 设置字体

    fontSize=8,                       # 设置字体大小

)

# 设置文本样式

class MyCSS:

    h1 = ParagraphStyle(name="h1", fontName=xinsong, fontSize=20, leading=21, alignment=1,colors=colors.blue,fontColor=colors.blue)

    h3 = ParagraphStyle(name="h3", fontName=xinsong, fontSize=14, leading=21, alignment=1)

    p = ParagraphStyle(name="p", fontName= msyhbd, fontSize=12, leading=15, firstLineIndent=15)

    p2 = ParagraphStyle(name="p2", fontName=msyh, fontSize=12, leading=15, alignment=0,firstLineIndent=20)

    p3 = ParagraphStyle(name="p3", fontName=msyh, fontSize=12, leading=15, alignment=2)


 

class PiiPdf:

    @classmethod

    def doH1(cls, text: str):

        return Paragraph(text, MyCSS.h1)

    def doH3(cls, text: str):

        return Paragraph(text, MyCSS.h3)

    def doP2(cls, text: str):

        return Paragraph(text, MyCSS.p2)

    def doP3(cls, text: str):

        return Paragraph(text, MyCSS.p3)

    @classmethod

    def doP(cls, text: str):

        return Paragraph(text, MyCSS.p)

#设置折线图

    @classmethod

    def doLine(cls,x,y,title,title_x,title_y):

        # drawing = Drawing(x, y)

        drawing = Drawing(0, 200)

        lab =Label()

        lab.x = title_x  #x和y是文字的位置坐标

        lab.y = title_y

        lab.setText(title)

        drawing.add(lab)

        # drawing.add(String(title_x,title_y,title, fontSize=13, fontName=msyh, fillColor=colors.black,firstLineIndent=20))

        line = LinePlot()

        line.x = x

        line.y = y

        line.height = 150

        line.width = 180

        line.lines[0].strokeColor = colors.blue

        line.lines[1].strokeColor = colors.red

        line.lines[2].strokeColor = colors.green

        line.lineLabels ="1111111111111111111"

        # line.lineLabels.fontName = msyh

        line.data = [((0, 50), (100, 100), (200, 200), (250, 210), (300, 300), (400, 800)),((0, 70), (100, 110), (200, 290), (250, 260), (300, 320), (400, 820))]

        drawing.add(line)

        return drawing

4.添加具体文本内容

  timetemp ="<b>多元力学响应数据 "+str(beforeDate)+"~"+str(current_date)+"</b>"

  path ="D:/file/python/measuringPointPic/mearuring_point_new/"

  dirs = rmAssignDir1(path)

  Story = [Spacer(1, 2 * inch)]

  Story.append(Spacer(doc.width, -100)),

  # 添加标题

  Story.append(p.doH1(timetemp))

  Story.append(Spacer(doc.width, 10)),

  Story.append(p.doH1("<b></b>"))

  # Story.append(p.doH3(timetemp)),s

  Story.append(Spacer(doc.width, 30)),

  Story.append(p.doH1("<b></b>"))

5.添加表格

  data= [

  ['设备类型(单位)', '监测点名称', '当前监测值', '周变化量', '月变化量', '最大值', '预警状态', '累计预警次数'],

  ['00', '01', '02', '03', '04','05','06','07'],

  ['10', '11', '12', '13', '14','05','06','07'],

  ['20', '21', '22', '23', '24','05','06','07'],

  ['30', '31', '32', '33', '34','05','06','07']]

  dataAll =[]

  # dataList2 =['设备类型(单位)', '监测点名称', '当前监测值', '周变化量/变化速率', '月变化量/变化速率', '最大值', '预警状态', '累计预警次数']

  # dataList2 =getDate.getData()

  # dataAll = dataList+dataList2

  # dataAll.append(dataList)

  # dataAll.append(dataList2)

  t=Table(data)

  #下面的(0,0),(1,1) 表示为(起始行索引,起始列索引),(结束行索引,结束列索引)

  t.setStyle(TableStyle(

      [('GRID', (0,0), (-1,-1), 0.25, colors.black),

      ('BOX', (0, 0), (-1, -1), 0.25, colors.black),

      ('FONTNAME', (0, 0), (-1, -1), song),

      ('FONTSIZE', (0, 0), (-1, -1), 8),

  ]

      ))

  Story.append(t)

  Story.append(Spacer(doc.width, 20)),

  # 往上移动

  Story.append(Spacer(doc.width, -20)),

6.画图

  for i in range(len(dirs)):

      if i%3==0:

          d = Drawing()

          d.add(DrawingImage(0,0,250,150,path+dirs[i]))

          if i+1< len(dirs):

           d.add(DrawingImage(250,0,250,150,path+dirs[i+1]))

          if i+2< len(dirs):

           d.add(DrawingImage(500,0,250,150,path+dirs[i+2]))

          Story.append(Spacer(doc.width, -20)),

          Story.append(d)

  doc.build(Story)

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值