python 使用reportlab打造29页图文并茂pdf(全网reportlab最强pdf自动化生成代码)

python 使用reportlab打造29页图文并茂pdf(全网reportlab最强pdf自动化生成代码)

这次项目所使用的代码如果同志们可以灵活使用,基本上可以解决百分之九十以上的pdf模板自动化生成。

最近博主,做了一个项目,使用reportlab制作pdf,博主打算把代码分享出来,先看一下博主生成的pdf:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以上就是,这次项目生成的pdf,使用的数据,我就不分享了,下面是代码。

注:代码需要有一点编程灵性才能看懂,另外,数据集博主就不分享了,设计一些商业机密,感兴趣的同学可以好好学习一下。


#encoding=gbk
import cv2
from reportlab.pdfgen import canvas
from PIL import Image
#encoding=gbk
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
from reportlab.platypus import BaseDocTemplate, Paragraph, Table, Spacer, PageBreak, Image, PageTemplate, \Frame, NextPageTemplate, FrameBreak
from reportlab.lib.units import inch
import json
with open("./res_summary.json", "r", encoding="utf-8") as f:contentz = json.load(f)# for key in contentz.keys():
#     print(key,contentz[key])# 注册字体(提前准备好字体文件, 如果同一个文件需要多种字体可以注册多个)
pdfmetrics.registerFont(TTFont('SimSun', 'simsun.ttc'))
pdfmetrics.registerFont(TTFont('SimSunb', 'ssb.ttf'))
#C:\Users\Administrator\source\repos\latex\latex\simsun.ttc
class Graphs:# 绘制标题@staticmethoddef draw_title(title: str):# 获取所有样式表style = getSampleStyleSheet()# 拿到标题样式ct = style['Heading1']# 单独设置样式相关属性ct.fontName = 'SimSunb'      # 字体名ct.fontSize = 23            # 字体大小ct.leading = 40             # 行间距ct.textColor = colors.black     # 字体颜色ct.alignment = 1    # 居中ct.bold = 10ct.leftMargin = 120#改左边距ct.rightMargin = 120# 创建标题对应的段落,并且返回return Paragraph(title, ct)# 绘制小标题@staticmethoddef 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)# 绘制普通段落内容@staticmethoddef draw_text(text: str):# 获取所有样式表style = getSampleStyleSheet()# 获取普通样式ct = style['Normal']ct.fontName = 'SimSun'ct.fontSize = 12ct.wordWrap = 'CJK'     # 设置自动换行ct.alignment = 0        # 左对齐ct.firstLineIndent = 32     # 第一行开头空格ct.leading = 30return Paragraph(str(text), ct)def draw_text_2(text: str):# 获取所有样式表style = getSampleStyleSheet()# 获取普通样式ct = style['Normal']ct.fontName = 'SimSunb'ct.fontSize = 12ct.wordWrap = 'CJK'     # 设置自动换行ct.alignment = 0        # 左对齐ct.firstLineIndent = 32     # 第一行开头空格ct.leading = 25return Paragraph(str(text), ct)def draw_text_23(text: str):# 获取所有样式表style = getSampleStyleSheet()# 获取普通样式ct = style['Normal']ct.fontName = 'SimSunb'ct.fontSize = 12ct.wordWrap = 'CJK'     # 设置自动换行ct.alignment = 1        # 左对齐ct.firstLineIndent = 32     # 第一行开头空格ct.leading = 25return Paragraph(str(text), ct)def draw_text_5(text: str):# 获取所有样式表style = getSampleStyleSheet()# 获取普通样式ct = style['Normal']ct.fontName = 'SimSunb'ct.fontSize = 12ct.wordWrap = 'CJK'     # 设置自动换行ct.alignment = 0        # 左对齐ct.firstLineIndent = 0     # 第一行开头空格ct.leading = 30return Paragraph(str(text), ct)def draw_text_4(text: str):# 获取所有样式表style = getSampleStyleSheet()# 获取普通样式ct = style['Normal']ct.fontName = 'SimSun'ct.fontSize = 12ct.wordWrap = 'CJK'     # 设置自动换行ct.alignment = 0        # 左对齐ct.firstLineIndent = 0     # 第一行开头空格ct.leading = 30return Paragraph(str(text), ct)# 绘制表格def draw_text_3(text: str):# 获取所有样式表style = getSampleStyleSheet()# 获取普通样式ct = style['Normal']ct.fontName = 'SimSun'ct.fontSize = 12ct.wordWrap = 'CJK'     # 设置自动换行ct.alignment = 0        # 左对齐ct.firstLineIndent = 32     # 第一行开头空格ct.leading = 30return Paragraph(str(text), ct)# 绘制表格@staticmethoddef draw_table(*args):# 列宽度col_width = 120style = [('FONTNAME', (0, 0), (-1, -1), 'SimSunb'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 12),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 10),  # 第二行到最后一行的字体大小#('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中('ALIGN', (0, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.black),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.01, colors.black),  # 设置表格框线为grey色,线宽为0.5# ('SPAN', (0, 1), (0, 2)),  # 合并第一列二三行# ('SPAN', (0, 3), (0, 4)),  # 合并第一列三四行# ('SPAN', (0, 5), (0, 6)),  # 合并第一列五六行# ('SPAN', (0, 7), (0, 8)),  # 合并第一列五六行]table = Table(args, rowHeights=48,colWidths=70 ,style=style)return table@staticmethoddef draw_table_z(*args):# 列宽度col_width = 120style = [('FONTNAME', (0, 0), (-1, -1), 'SimSunb'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 15),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 15),  # 第二行到最后一行的字体大小#'BACKGROUND', (0, 0), (-1, 0), 'blue'),  # 设置第一行背景颜色('ALIGN', (0, 0), (0, -1), 'CENTER'),  # 第水平居中('ALIGN', (1, 0), (-1, -1), 'LEFT'),  # 第二行到最后一行左右左对齐#    ('BACKGROUND', (0, 0), (-1, 0), 'blue'),  # 设置第一行背景颜色('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.5, colors.grey),  # 设置表格框线为grey色,线宽为0.5# ('SPAN', (0, 1), (0, 2)),  # 合并第一列二三行# ('SPAN', (0, 3), (0, 4)),  # 合并第一列三四行# ('SPAN', (0, 5), (0, 6)),  # 合并第一列五六行# ('SPAN', (0, 7), (0, 8)),  # 合并第一列五六行('SPAN', (1, 0), (3, 0)),  # 合并第一列二三行('SPAN', (1, 1), (3, 1)),  # 合并第一列三四行('SPAN', (1, 2), (3, 2)),  # 合并第一列五六行]table = Table(args, rowHeights=30,colWidths=110 ,style=style)return table@staticmethoddef draw_table_2(*args):# 列宽度col_width = 120style = [('FONTNAME', (0, 0), (-1, -1), 'SimSunb'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 12),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 10),  # 第二行到最后一行的字体大小#('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中('ALIGN', (0, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.black),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.01, colors.black),  # 设置表格框线为grey色,线宽为0.5# ('SPAN', (0, 1), (0, 2)),  # 合并第一列二三行# ('SPAN', (0, 3), (0, 4)),  # 合并第一列三四行# ('SPAN', (0, 5), (0, 6)),  # 合并第一列五六行# ('SPAN', (0, 7), (0, 8)),  # 合并第一列五六行]table = Table(args, rowHeights=48,colWidths=60 ,style=style)return table@staticmethoddef draw_table_3(*args):# 列宽度col_width = 120style = [('FONTNAME', (0, 0), (-1, -1), 'SimSunb'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 12),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 10),  # 第二行到最后一行的字体大小#('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中('ALIGN', (0, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.1, colors.black),  # 设置表格框线为grey色,线宽为0.5# ('SPAN', (0, 1), (0, 2)),  # 合并第一列二三行# ('SPAN', (0, 3), (0, 4)),  # 合并第一列三四行# ('SPAN', (0, 5), (0, 6)),  # 合并第一列五六行# ('SPAN', (0, 7), (0, 8)),  # 合并第一列五六行]table = Table(args, rowHeights=48,colWidths=60 ,style=style)return table@staticmethoddef draw_table_first(*args):# 列宽度col_width = 100style = [('FONTNAME', (0, 0), (-1, -1), 'SimSunb'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 15),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 15),  # 第二行到最后一行的字体大小#'BACKGROUND', (0, 0), (-1, 0), 'blue'),  # 设置第一行背景颜色('ALIGN', (0, 0), (0, -1), 'CENTER'),  # 第水平居中('ALIGN', (1, 0), (-1, -1), 'LEFT'),  # 第二行到最后一行左右左对齐('BACKGROUND', (0, 0), (-1, 0), 'blue'),  # 设置第一行背景颜色('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.5, colors.grey),  # 设置表格框线为grey色,线宽为0.5('SPAN', (1, 0), (3, 0)),  # 合并第一列二三行('SPAN', (1, 1), (3, 1)),  # 合并第一列三四行('SPAN', (1, 2), (3, 2)),  # 合并第一列五六行('SPAN', (1, 3), (3, 3)),  # 合并第一列五六行('SPAN', (1, 4), (3, 4)),  # 合并第一列五六行('SPAN', (1, 5), (3, 5)),  # 合并第一列五六行('SPAN', (1, 6), (3, 6)),  # 合并第一列五六行]table = Table(args, rowHeights=43,colWidths=110, style=style)return table# 创建图表# 绘制图片@staticmethoddef draw_img_first(path):image = cv2.imread(path)  # 逐个读取img = Image(path)       # 读取指定路径下的图片img.drawWidth = 10*cm        # 设置图片的宽度img.drawHeight = 10*cm       # 设置图片的高度return img@staticmethoddef draw_img_first(path):image = cv2.imread(path)  # 逐个读取if(image.shape[0]*image.shape[1]>30000000):print("dd",image.shape)image=cv2.resize(image,(int(image.shape[0]*0.6),int(image.shape[1]*0.6)))cv2.imwrite("E:\\work\\10-23\\input\\results\\secs\\z.png",image)img = Image("E:\\work\\10-23\\input\\results\\secs\\z.png")       # 读取指定路径下的图片# img.drawWidth = 5*cm        # 设置图片的宽度# img.drawHeight = 8*cm       # 设置图片的高度return imgimg = Image(path)       # 读取指定路径下的图片img.drawWidth = 3*cm        # 设置图片的宽度img.drawHeight = 3*cm       # 设置图片的高度return imgimport csv
def read_csv(path):listz=[]p=0with open(path, 'r', encoding='utf-8') as csv_f:reader = csv.reader(csv_f)for row in reader:#   print(row)if p!=0:print(row[0])st=''for s in row[0][0:]:if '0'<=s and  s<='9':st=st+sif s in [',',' ']:breakrow[0]=int(st)p=p+1listz.append(row)return listz
import datetime
from reportlab.lib.units import inch, cm
from reportlab.pdfbase import pdfmetrics, ttfonts
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import SimpleDocTemplate, Paragraph, PageBreak, Spacer
def myFirstPage(canvas, doc):"""第一页页眉页脚配置:param canvas: 绘画对象,用来写入页眉页脚:param doc: 文档对象,可以以此得知文档的页边距信息:return:"""# 文档宽度高度(width、height),左右页边距(leftMargin、rightMargin)、上下页边距(topMargin、bottomMargin)totalPageHeight = doc.bottomMargin + doc.height + doc.topMargin  # 页面总高度totalPageWidth = doc.leftMargin + doc.width + doc.rightMargin  # 页面总宽度# 保存之前的画笔格式等状态,并设置新的状态canvas.saveState()   # 设置字体及大小canvas.setFont('SimSun', 12)# 添置靠左页眉print(doc.leftMargin, totalPageHeight - doc.topMargin)canvas.drawImage(r"MD_logo.png", 0, 785, 5.2* cm, 2 * cm)canvas.restoreState()def myLaterPages(canvas, doc):"""除第一页外其它页的页眉页脚配置:param self::param canvas::param doc::return:"""totalPageWidth = doc.leftMargin + doc.width + doc.rightMargincanvas.saveState()canvas.setFont('SimSun', 9)# 添置居中页脚canvas.drawString(totalPageWidth / 2.0, doc.bottomMargin, "{}".format(doc.page))canvas.restoreState()#  #   print("fdsfdsa",res_summary['project_bird_view_path'])#     content.append(Graphs.draw_text(res_summary['project_name']))#003#     content.append(Graphs.draw_text(res_summary['project_unit']))#004#     content.append(Graphs.draw_text(res_summary['manage_unit']))#005#     content.append(Graphs.draw_text(res_summary['construction_unit']))#006
#     content.append(Graphs.draw_text(res_summary['inspection_unit']))##007
#     content.append(Graphs.draw_text(res_summary['inspector']))#008
#     content.append(Graphs.draw_text(res_summary['inspection_time']))#009##
#     content.append(Graphs.draw_text(res_summary['wall_loc']))#010
#     content.append(Graphs.draw_text(res_summary['wall_stage']))#011#     content.append(Graphs.draw_text(res_summary['scoring_dist_thresh_flatness']))#012
#     content.append(Graphs.draw_text(res_summary['scoring_dist_thresh_perpendicularity']))#012# content.append(Graphs.draw_img(res_summary['wall_camera_view_path']))#013# content.append(Graphs.draw_img(res_summary['pcd_camera_view_path']))#014#     content.append(Graphs.draw_img(res_summary['sec_heat_info']['heat_map_path']))#015#     #print(res_summary['flatness_secs_info']['statistics_measure'])
#     
#    # print(list_data)#for key in res_summary['flatness_secs_info']['defect_map_infos']:#          content.append(Graphs.draw_text(key['floors_num']))#023#          content.append(Graphs.draw_img(key['img_path']))#023
#     
#     #print(res_summary['sec_heat_info']['statistics_pts']['secs_res_path'])
#     list_data=read_csv(res_summary['sec_heat_info']['statistics_pts']['secs_res_path'])#     content.append(Graphs.draw_table(*list_data))#017#     content.append(Graphs.draw_text(res_summary['sec_heat_info']['statistics_pts']['valid_avg']))#018
#     content.append(Graphs.draw_text(res_summary['sec_heat_info']['statistics_pts']['score_avg']))#019
#     #content.append(Graphs.draw_text(res_summary['scoring_dist_thresh_perpendicularity']))#012#     lsiz= res_summary['perpendicularity_secs_info']['worst_se_map_infos']
#     for key in res_summary['flatness_secs_info']['worst_se_map_infos']:
#        # print(key['floors_num'])
#         content.append(Graphs.draw_text(key['floors_num']))#020#         content.append(Graphs.draw_img(key['img_path']))#021#         for k in lsiz:
#         #    print(k)
#             if(k['floors_num']==key['floors_num']) :
#                 content.append(Graphs.draw_img(k['img_path']))#022
#                # print(k['img_path']) #     for key in res_summary['flatness_secs_info']['defect_map_infos']:
#              content.append(Graphs.draw_text(key['floors_num']))#023#              content.append(Graphs.draw_img(key['img_path']))#023
#     content.append(Graphs.draw_img(res_summary['sec_heat_info']['heat_map_path']))#024
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle, Image
if __name__ == '__main__':# 创建内容对应的空列表content = list()res_summary=contentzcontent.append(Graphs.draw_title('元宇智数(深圳)科技有限公司'))content.append(Graphs.draw_title('外墙检测诊断报告书'))b=[['项目名称',res_summary['project_name'],'',''],['建设单位',res_summary['project_unit'],'',''],['监理单位',res_summary['manage_unit'],'',''],['施工单位',res_summary['construction_unit'],'',''],['检测单位',res_summary['inspection_unit'],'',''],['测量员',res_summary['inspector'],'',''],['测量时间',res_summary['inspection_time'],'','']]# 添加图片#   #  print("fdsfdsa",res_summary['project_bird_view_path'])p1 = Image(res_summary['project_bird_view_path'],250,250)content.append(p1)content.append(Graphs.draw_text_3('<i>   </i><br/>'))content.append(Graphs.draw_table_first(*b))content.append(Graphs.draw_title(res_summary['wall_loc']+"外墙检测现场情况"))#  content.append(Graphs.draw_text_3('<i>   </i><br/>'))a="检测阶段:"+res_summary['wall_stage']b="检测标准:"+str(res_summary['scoring_dist_thresh_flatness'])c="检测设备:"+str(res_summary['scoring_dist_thresh_flatness'])s=a+'<br/>'+b+"<br/>"+clb=[['检测阶段',res_summary['wall_stage'],'',''],['检测标准',str(res_summary['scoring_dist_thresh_flatness']),'',''],['检测设备',str(res_summary['scoring_dist_thresh_flatness']),'','']]#draw_table_zcontent.append(Graphs.draw_table_z(*lb))#  content.append(Graphs.draw_text_2(b))# content.append(Graphs.draw_text_2(c))# canvas.drawImage(res_summary['wall_camera_view_path'], inch*.25, inch*.25, 100-(.5*inch), (.316*inch))#canvas.drawImage(res_summary['wall_camera_view_path'], inch*.25, inch*.25, 100-(.5*inch), (.316*inch))p13 = Image(res_summary['wall_camera_view_path'],200,455)p14=Image(res_summary['pcd_camera_view_path'],200,455)data= [[p13,p14 ]]t=Table(data,style=[('GRID',(0,0),(-1,-1),2,colors.white),('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐], rowHeights=460,colWidths=220)content.append(Graphs.draw_text('<br/><br/>'))content.append(t)content.append(Graphs.draw_title("检测设备参数"))s="FARO P350 双轴补偿器:对每次扫描进行水平校准,精度达到 19 角秒,\误差范围±2° 高度传感器:通过电子气压计,可测得与固定点相对的高度并将其<br/>添加至扫描指南针 :电子指南针可指示扫描的方向 GNSS:集成 GPS 和<br/>GLONASS 现场补偿:创建当前质量报告并为自动改进设备补偿提供了选项。<br/>"s3="外部环境<br/>"s2="重量(包括电池): 4.2kg 尺寸: 230 x 183 x 103mm<br/>电源电压: 19V (外置电源)14.4V (内部电池)<br/>功耗: 15W(待机时),25W(扫描时),80W(充电时)<br/>\
电池使用时间: 4.5 小时<br/>\
工作温度: 5° - 40°C<br/>\
扩展工作温度: -20° - 55°C<br/>\
贮存温度: -10° - 60°C<br/>\
防护等级: IP54<br/>\
湿度: 无凝结。<br/><br/><br/>"p4 = Image('p2.png',100,150)content.append(p4)content.append(Graphs.draw_text_3(s))content.append(Graphs.draw_text_5(s3))content.append(Graphs.draw_text_4(s2))content.append(Graphs.draw_text_3('<i>   </i><br/>'))#  content.append(Graphs.draw_text(''))content.append(Graphs.draw_title("外墙面热力图"))# content.append(Graphs.draw_text_3("<i>  </i><br/>"))p13 = Image(res_summary['wall_camera_view_path'],200,590)patz="D:\work\latex\data\\z.png"def p_z(path):image = cv2.imread(path)  # 逐个读取if(image.shape[0]*image.shape[1]>1000000):print("dd",image.shape)image=cv2.resize(image,(int(image.shape[0]*0.5),int(image.shape[1]*0.5)))cv2.imwrite(patz,image)# img = Image("E:\\work\\10-23\\input\\results\\secs\\z.png") else:cv2.imwrite(patz,image)p_z(res_summary['sec_heat_info']['heat_map_path'])p15=Image(patz,7*cm,21*cm)data= [[p13,p15 ]]t=Table(data,style=[('GRID',(0,0),(-1,-1),2,colors.white)], rowHeights=600,colWidths=240)content.append(t)content.append(Graphs.draw_title("墙面各层区间下尺检测结果"))list_data=read_csv(res_summary['flatness_secs_info']['statistics_measure'])content.append(Graphs.draw_table(*list_data))#016content.append(Graphs.draw_text_3('<i>   </i><br/>'))content.append(Graphs.draw_title("墙面满测检测结果"))list_data=read_csv(res_summary['sec_heat_info']['statistics_pts']['secs_res_path'])content.append(Graphs.draw_table_2(*list_data))#017content.append(Graphs.draw_text_3('<i>   </i><br/>'))lsiz= res_summary['perpendicularity_secs_info']['worst_se_map_infos']# data= [[p13,p14 ]]sty=[ ('SPAN', (0, 0), (3, 0)),('SPAN', (4, 0), (7, 0)) ,  ('SPAN', (0, 1), (3, 11)) , ('SPAN', (4, 1), (7, 11)) , ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 15),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 15),  # 第二行到最后一行的字体大小#('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中('ALIGN', (0, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.1, colors.black),  # 设置表格框线为grey色,线宽为0.5] # 合并第一列二三行,]#('GRID',(0,0),(-1,-1),2,colors.white)####**********z=list_datafor key in res_summary['flatness_secs_info']['worst_se_map_infos']:# print(key['floors_num'])#  content.append(Graphs.draw_text(key['floors_num']))#020if key['floors_num'][0]!=33:content.append(Graphs.draw_title(str(key['floors_num'][0])+"-"+str(key['floors_num'][1])+"层区间-垂平数据结果"))else:content.append(Graphs.draw_title(str(key['floors_num'][0])+"层以上-垂平数据结果"))p16=Image(key['img_path'],8*cm,16*cm)list_data=zlist_data[0][0]='外墙平整度'list_data[0][4]='外墙垂直度'list_data[1][0]=p16#  content.append(p16)#021for k in lsiz:#    print(k)if(k['floors_num']==key['floors_num']) :#  content.append(Graphs.draw_img(k['img_path']))#022p16=Image(k['img_path'],8*cm,16*cm)#  content.append(p16)#021list_data[1][4]=p16t=Table(list_data,style=sty, rowHeights=50,colWidths=65)content.append(t)# print(k['img_path']) content.append(Graphs.draw_text_3('<i>   </i><br/>'))sty2=[ ('SPAN', (0, 0), (7, 0)),('SPAN', (0, 1), (7, 11)) , ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 15),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 15),  # 第二行到最后一行的字体大小#('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中('ALIGN', (0, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.1, colors.black),  # 设置表格框线为grey色,线宽为0.5] # 合并第一列二三行,]#('GRID',(0,0),(-1,-1),2,colors.white)list_z=res_summary['flatness_secs_info']['defect_map_infos']for i in range(0,len(list_z),2):content.append(Graphs.draw_title("缺陷修补建议图"))list_data=zlist_data[0][0]=str(list_z[i]['floors_num'][0])+"-"+str(list_z[i]['floors_num'][1])+"层区间"p16=Image(list_z[i]['img_path'],8*cm,16*cm)list_data[1][0]=p16try:list_data[0][4]=str(list_z[i+1]['floors_num'][0])+"-"+str(list_z[i+1]['floors_num'][1])+"层区间"p16=Image(list_z[i+1]['img_path'],8*cm,16*cm)list_data[1][4]=p16t=Table(list_data,style=sty, rowHeights=50,colWidths=65)content.append(t)content.append(Graphs.draw_text_3('<i>   </i><br/>'))i=i+1except:#list_data[0][4]=''#list_data[1][4]=''list_data[0][0]=str(list_z[i]['floors_num'][0])+"层以上"p16=Image(list_z[i]['img_path'],12*cm,16*cm)list_data[1][0]=p16t=Table(list_data,style=sty2, rowHeights=50,colWidths=65)content.append(t)content.append(Graphs.draw_text_3('<i>   </i><br/>'))i=i+1content.append(Graphs.draw_title("层间K板接缝处检测数据结果"))content.append(Graphs.draw_text_23("(上下各延展1.2米)客户定制检测内容"))# p16=Image(res_summary['sec_heat_info']['heat_map_path'],300,600)print(res_summary['sec_heat_info']['heat_map_path'])p_z(res_summary['sec_heat_info']['heat_map_path'])p15=Image(patz,300,600)content.append(p15)#024styz=[ ('SPAN', (0, 0), (3, 0)),('SPAN', (4, 0), (7, 0)) ,  ('SPAN', (0, 1), (3, 5)) , ('SPAN', (4, 1), (7, 5)) , ('SPAN', (0, 6), (3, 6)),('SPAN', (4, 6), (7, 6)) ,  ('SPAN', (0, 7), (3, 11)) , ('SPAN', (4, 7), (7, 11)) , ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 字体('FONTSIZE', (0, 0), (-1, 0), 12),  # 第一行的字体大小('FONTSIZE', (0, 1), (-1, -1), 12),  # 第二行到最后一行的字体大小#('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中('ALIGN', (0, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色('GRID', (0, 0), (-1, -1), 0.1, colors.black),  # 设置表格框线为grey色,线宽为0.5] # 合并第一列二三行,]#('GRID',(0,0),(-1,-1),2,colors.white)# res_summary['flatness_gaps_info']['worst_se_map_infos'][*]['floors_num']# 和# res_summary['flatness_gaps_info']['defect_map_infos'][*]['floors_num']lsiz= res_summary['flatness_gaps_info']['defect_map_infos']piz=0for key in res_summary['flatness_gaps_info']['worst_se_map_infos']:list_data=zif  piz%2==0:piz=piz+1content.append(Graphs.draw_title("层间接缝处爆尺及缺陷修补建议图"))#   print("fdsfds")list_data[0][0]=str(key['floors_num'][0])+'层接缝处爆尺数据'list_data[0][4]=str(key['floors_num'][0])+'层接缝处缺陷修补'p16=Image(key['img_path'],212,160)list_data[1][0]=p16#  content.append(Graphs.draw_img(key['img_path']))#026for k in lsiz:#    print(k)if(k['floors_num']==key['floors_num']) :p16=Image(k['img_path'],212,160)list_data[1][4]=p16# content.append(Graphs.draw_img(k['img_path']))#027else:piz=piz+1list_data[6][0]=str(key['floors_num'][0])+'层接缝处爆尺数据'list_data[6][4]=str(key['floors_num'][0])+'层接缝处缺陷修补'p16=Image(key['img_path'],212,160)list_data[7][0]=p16for k in lsiz:#    print(k)if(k['floors_num']==key['floors_num']) :p16=Image(k['img_path'],212,160)list_data[7][4]=p16# content.append(Graphs.draw_img(k['img_path']))#027t=Table(list_data,style=styz, rowHeights=50,colWidths=65)content.append(t)content.append(Graphs.draw_text_3('<i>   </i><br/>'))# # res_summary['flatness_gaps_info']['worst_se_map_infos'][*]['floors_num']
# # 和
# # res_summary['flatness_gaps_info']['defect_map_infos'][*]['floors_num']#     lsiz= res_summary['flatness_gaps_info']['defect_map_infos']
#     for key in res_summary['flatness_gaps_info']['worst_se_map_infos']:
#        # print(key['floors_num'])
#         content.append(Graphs.draw_text(key['floors_num']))#025#         content.append(Graphs.draw_img(key['img_path']))#026#         for k in lsiz:
#         #    print(k)
#             if(k['floors_num']==key['floors_num']) :
#                 content.append(Graphs.draw_img(k['img_path']))#027# print(k['img_path']) #print("fdsfdsa",res_summary['project_bird_view_path'])#content.append(Graphs.draw_img(contentz['sec_heat_info']['heat_map_path']))#other/MD_logo.png# for key in contentz.keys():#     path=contentz[key]#     if isinstance(path,dict):#        for keyp in path.keys():#            print(path[keyp]) #     else:#          print(path) # if path.endwith("png"):#     # 添加段落文字# content.append(Graphs.draw_text('众所周知,大数据分析师岗位是香饽饽,近几年数据分析热席卷了整个互联网行业,与数据分析的相关的岗位招聘、培训数不胜数。很多人前赴后继,想要参与到这波红利当中。那么数据分析师就业前景到底怎么样呢?'))# # 添加小标题# content.append(Graphs.draw_title(''))# content.append(Graphs.draw_little_title('不同级别的平均薪资'))# # 添加表格# data = [#     ('职位名称', '平均薪资', '较上年增长率'),#     ('数据分析师', '18.5K', '25%'),#     ('高级数据分析师', '25.5K', '14%'),#     ('资深数据分析师', '29.3K', '10%')# ]# content.append(Graphs.draw_table(*data))# # 生成图表# content.append(Graphs.draw_title(''))# content.append(Graphs.draw_little_title('热门城市的就业情况'))# b_data = [(25400, 12900, 20100, 20300, 20300, 17400), (15800, 9700, 12982, 9283, 13900, 7623)]# ax_data = ['BeiJing', 'ChengDu', 'ShenZhen', 'ShangHai', 'HangZhou', 'NanJing']# leg_items = [(colors.red, '平均薪资'), (colors.green, '招聘量')]# content.append(Graphs.draw_bar(b_data, ax_data, leg_items))# 生成pdf文件doc = SimpleDocTemplate(r'D:\work\latex\data\report.pdf', pagesize=A4)doc.build(content,onFirstPage=myFirstPage, onLaterPages=myFirstPage)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/188928.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序包不存在

idea2020会有一个小bug&#xff0c;在idea的Settings设置中进行下面配置&#xff1a; 然后在maven项目下的pom.xml中加入如下代码&#xff1a; <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifact…

【趣味JavaScript】一文让你读懂JavaScript原型对象与原型链的继承,探秘属性的查找机制! 《重置版》

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

Oracle忘记所有密码怎么办

最近遇到一个Oracle的问题&#xff0c;密码要过期了&#xff0c;但是除了用户密码&#xff0c;其他密码都不知道了&#xff0c;修改不了密码怎么办呢&#xff1f; 试了各种方法&#xff0c;最终下面的方式生效了&#xff1a; 首先&#xff0c;使用orapwd生成新的密码文件&…

云计算如何创芯:“逆向工作法”的性感之处

在整个云计算领域&#xff0c;能让芯片规模化的用起来&#xff0c;是决定造芯是否成功的天花板。在拉斯维加斯的亚马逊云科技2023 re:Invent则是完美诠释了这一论调。 亚马逊云科技2023 re:Invent开幕前两个小时&#xff0c;有一场小型的欢迎晚宴&#xff0c;《星期日泰晤士报》…

BUUCTF [GXYCTF2019]SXMgdGhpcyBiYXNlPw== 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 密文&#xff1a; 下载附件&#xff0c;解压得到flag.txt文件。 解题思路&#xff1a; 1、打开flag.txt文件&#xff0c;内容如下。 Q2V0dGUgbnVpdCwK SW50ZW5hYmxlIGluc29tbm…

Python编程题集(第三部容器操作 )

Demo61 指定等级 题目描述 读入学生成绩&#xff0c;获取最高分best&#xff0c;然后根据下面的规则赋等级值&#xff1a; &#xff08;1&#xff09;如果分数≥best-10&#xff0c;等级为A &#xff08;1&#xff09;如果分数≥best-20&#xff0c;等级为B &#xff08;1…

常见基础指令【Linux】

目录 一、Linux基本指令1. ls2. pwd3. cd4. touch5. mkdir6. rm和rmdir7. man8. cp9. mv10. cat11. tac12. more13. less14. head15. tail16. date17. cal18. find19. grep20. zip/unzip21. echo22. wc23. tree24. which25. alias26. whoami27. stat28. tar29. uname30. shutdo…

如何自定义winform控件,并把它添加到工具箱,供拖动使用

首先&#xff0c;在想要用自定义控件的解决方案中新建一个项目&#xff0c;该项目用来存放所有的自定义控件。 解决方案-右键-添加-新建项目 添加新项目的界面选择Windows窗体控件库&#xff0c;点击确定。 此时&#xff0c;已经添加好了新的项目&#xff0c;默认会有一个自定…

记RocketMQ本地开发环境搭建始末

前言 最近工作中涉及到了RocketMQ的应用&#xff0c;为方便开发决定本地搭建一套RocketMQ的使用环境。 果然实践是个好东西... VMware虚拟环境搭建 这个网上有很多教程&#xff0c;只会比我写的详细有条理&#xff0c;这里就不在赘述了。 虚拟机搭建好之后每次重启电脑都无…

nginx配置反向代理及负载均衡

目录 1.前端发送的请求&#xff0c;是如何请求到后端服务的1.nginx 反向代理的好处&#xff1a;2.nginx 反向代理的配置方式&#xff1a;3. nginx 负载均衡的配置方式 1.前端发送的请求&#xff0c;是如何请求到后端服务的 1.nginx 反向代理的好处&#xff1a; 提高访问速度 因…

全系降3万,一把干到底,极越「智取」特斯拉

作者|德新 编辑|王博 11月30日&#xff0c;极越01官宣全系降价3万。 这意味着21.99万起步的极越01 Max&#xff0c;成为这个市场上入门门槛最低的带有城市智能驾驶辅助功能的车型。 要知道这是一台比Model Y大了一圈&#xff0c;全系配置了高阶智驾硬件&#xff0c;全系配高…

Apache HTTPD 2.448 mod_proxy SSRF漏洞(CVE-2021-40438)

任务一&#xff1a; 复现漏洞 任务二&#xff1a; 尝试利用SSRF漏洞&#xff0c;访问重庆邮电大学官网&#xff08;http://www.cqupt.edu.cn) 1.搭建环境 2.了解这个地方是httpd作为了一个反向代理服务器&#xff0c;也就是先是客户端发送请求给代理服务器&#xff0c;然后…

Neo4j 程序开发 JavaAPI 嵌入式开发模式(头歌)

文章目录 第1关&#xff1a;JavaAPI 嵌入式开发模式任务描述相关知识创建 Neo4j 数据库启动 Neo4j 数据事务创建节点创建节点关系将创建的数据库设置为默认数据库 编程要求测试说明答案代码修改配置文件&#xff0c;更改默认 Neo4j 数据库代码文件 第1关&#xff1a;JavaAPI 嵌…

【文献阅读笔记】关于GANomaly的异常检测方法

文章目录 1、GANomaly: Semi-Supervised Anomaly Detection via Adversarial Training模型主要创新 2、Skip-GANomaly: Skip Connected and AdversariallyTrained Encoder-Decoder Anomaly Detection模型主要创新点 3、Industrial surface defect detection and localization u…

YOLOv8改进 | 2023 | AKConv轻量级架构下的高效检测(可变核卷积)

一、本文介绍 本文给大家带来的改进内容是AKConv&#xff08;可变核卷积&#xff09;是一种创新的卷积神经网络操作&#xff0c;它旨在解决标准卷积操作中的固有缺陷&#xff08;采样形状是固定的&#xff09;&#xff0c;AKConv的核心思想在于它为卷积核提供了任意数量的参数…

RTDETR阅读笔记

RTDETR阅读笔记 摘要 DETR的高计算成本限制了它们的实际应用&#xff0c;并阻碍了它们充分利用无需后处理&#xff08;例如非最大抑制NMS&#xff09;的优势。文中首先分析了NMS对实施目标检测的精度和速度的负面影响。&#xff08;RTDETR是第一个实时端到端的目标检测器。具…

Word 小知识之 docx 和 doc 的区别

下面我们从4个方面为大家总结了有关于docx和doc的区别&#xff0c;一起来看一看&#xff1a; 1. 文件格式 doc和docx的区别中较大的区别就是文件格式不同&#xff0c;一个是二进制一个为XML格式。doc&#xff1a;是早期的Word文档格式&#xff0c;采用二进制文件格式。这种…

ipa应用测试平台怎么开开具发票

控制台-个人中心-发票管理 ●点击申请发票可以开具发票 ●申请发票-填写资料-勾选订单 ●个人发票开具以及公司发票开具 ●提交发票申请 ●等待申请成功开具发票 ●发票开具成功&#xff0c;我们可以开具或者查看发票

二分查找与搜索树高频问题

关卡名 逢试必考的二分查找 我会了✔️ 内容 1.山脉数组的峰顶索引 ✔️ 2.旋转数字的最小数字 ✔️ 3.寻找缺失数字 ✔️ 4.优化求平方根 ✔️ 5.中序与搜索树原理 ✔️ 6.二叉搜索树中搜索特定值 ✔️ 7.验证二叉搜索树 ✔️ 基于二分查找思想&#xff0c;可以拓展出很…

conda 安装指定Version的指定Build

入下图&#xff0c;我想装cudnn的7.6.5的指定Build版本cuda10.0_0 应该使用如下命令&#xff1a; mamba install cudnn7.6.5cuda10.0_0 没有mamba用conda install也可以