Django使用pdfkit生成PDF文件提供下载

需要安装wkhtmltopdf,视图中先构造数据,再渲染模板t = TemplateResponse(request, 'pdf.html',{}),t.render(),再生成pdf文件

import pdfkit
from django.http import StreamingHttpResponse
from django.template.response import TemplateResponse

# 演练查询下载报告 def workflow_job_pdf_report(request): """ pip3 install pdfkit wkhtmltopdf安装文件已经在项目中static/pages/process """ if request.user.is_authenticated(): job_id = request.GET.get("job_id", "") state_dict = { "PAUSE": "暂停", "RUN": "运行中", "STOP": "停止", "ERROR": "错误", "WARNING": "警告", "BREAK": "跳出", "SKIP": "跳过", "WAIT": "等待", "DONE": "完成", "EDIT": "未开始", "CONFIRM": "签字" } # 构造数据 # 1.获取当前流程对象 workflow_job = TSDRMJob.objects.exclude(state='9').filter(id=job_id) if workflow_job: workflow_job = workflow_job[0] else: raise Http404() # 2.报表封页文字 abstract_xml = "流程日志" # 3.章节名称 ele_xml01 = "一、流程概述" ele_xml02 = "二、步骤详情" # 4.构造第一章数据: first_el_dict # 切换概述节点下内容,有序字典中存放 first_el_dict = {} start_time = workflow_job.starttime.strftime("%Y-%m-%d %H:%M:%S") if workflow_job.starttime else "" end_time = workflow_job.endtime.strftime("%Y-%m-%d %H:%M:%S") if workflow_job.endtime else "" users = User.objects.filter(id=workflow_job.createuser_id) create_user = "" if users: create_user = users[0].userinfo.fullname first_el_dict["name"] = workflow_job.name first_el_dict["start_time"] = start_time first_el_dict["end_time"] = end_time first_el_dict["state"] = state_dict.get(workflow_job.state) first_el_dict["create_user"] = create_user first_el_dict["run_reason"] = workflow_job.reson # 计算流程RTO时间 if start_time and end_time: # 如果此流程引用了<RPO结束时间>组件:则此流程的RTO时间:大流程的开始时间至<RPO结束时间>组件的开始时间 rpo_job = TSDRMJob.objects.exclude(state='9').filter(rootnodeid=job_id,modelguid='ce74993e-307e-11ec-860c-7412b3a42edd') if rpo_job.exists(): end_time = rpo_job[0].starttime.strftime("%Y-%m-%d %H:%M:%S") delta_seconds = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') - datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') hour, minute, second = str(delta_seconds).split(":") delta_time = "{0}时{1}分{2}秒".format(hour, minute, second) first_el_dict["rto"] = delta_time else: first_el_dict["rto"] = "" # 签字人 approve_log = Approvelog.objects.exclude(state='9').filter(job_id=job_id) if approve_log.exists(): approve_user = "" user = "" for log in approve_log: users = User.objects.filter(id=log.approveuser_id) if users: user = users[0].userinfo.fullname if user: approve_user += user + "" first_el_dict["receiveuser"] = approve_user[:-1] # 构造第二章数据: step_info_list step_info_list = [] workflow = None if workflow_job.type == 'INSTANCE': instance = TSDRMInstance.objects.exclude(state="9").filter(guid=workflow_job.modelguid) if len(instance) > 0: workflow = instance[0].workflow else: workflow = TSDRMWorkflow.objects.exclude(state="9").filter(guid=workflow_job.modelguid) if len(workflow) > 0: workflow = workflow[0] all_step_info = [] if workflow: if workflow.content and len(workflow.content.strip()) > 0: tmpStep = xmltodict.parse(workflow.content) if "tsdrmworkflow" in tmpStep and "steps" in tmpStep["tsdrmworkflow"] and "step" in \ tmpStep["tsdrmworkflow"]["steps"]: tmpDTL = tmpStep["tsdrmworkflow"]["steps"]["step"] if str(type(tmpDTL)) == "<class 'collections.OrderedDict'>": tmpDTL = [tmpDTL] for curstep in tmpDTL: list_line = {} step_modeltype = curstep["baseInfo"]["modelType"] step_guid = curstep["baseInfo"]["modelguid"] step_id = curstep["baseInfo"]["stepid"] step_name = curstep["baseInfo"]["name"] # 去除组件《输出false》,组件的guid为:8a812194-a8da-11eb-8997-405bd8b00cd6 if step_guid != '8a812194-a8da-11eb-8997-405bd8b00cd6': list_line['step_name'] = step_name list_line['step_id'] = step_id list_line['step_guid'] = step_guid list_line['step_modeltype'] = step_modeltype if "lines" in curstep and curstep["lines"] and "line" in curstep["lines"]: tmpDTL = curstep["lines"]["line"] if str(type(tmpDTL)) == "<class 'collections.OrderedDict'>": tmpDTL = [tmpDTL] for line in tmpDTL: if line['criteria'] != 'False': list_line['nextPoint'] = line['nextPoint'] list_line['criteria'] = line['criteria'] all_step_info.append(list_line) # all_step_info: 排序之前流程的所有一级步骤:子流程、组件、控件 # sort_step_info: 排序之后流程的所有一级步骤:去除控件,但保留签字控件 sort_step_info = step_sort(all_step_info) for num, pstep in enumerate(sort_step_info): pnode_steprun = TSDRMJob.objects.exclude(state='9').filter(pjob_id=job_id, step=int(pstep['step'])) if pnode_steprun.exists(): pnode_steprun = pnode_steprun[0] second_el_dict = dict() step_name = "{0}.{1}".format(num + 1, pstep['name']) second_el_dict["step_name"] = step_name start_time = pnode_steprun.starttime.strftime("%Y-%m-%d %H:%M:%S") if pnode_steprun.starttime else "" end_time = pnode_steprun.endtime.strftime("%Y-%m-%d %H:%M:%S") if pnode_steprun.endtime else "" second_el_dict["start_time"] = start_time second_el_dict["end_time"] = end_time second_el_dict["state"] = state_dict.get(pnode_steprun.state) second_el_dict["log"] = pnode_steprun.log if start_time and end_time: delta_seconds = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') - datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') hour, minute, second = str(delta_seconds).split(":") delta_time = "{0}时{1}分{2}秒".format(hour, minute, second) second_el_dict["rto"] = delta_time else: second_el_dict["rto"] = "" # 步骤签字人 approve_user = "" user = "" if pnode_steprun.modelguid == 'a686208c-f36c-11eb-a871-a4bb6d10e0ef': approve_log = Approvelog.objects.exclude(state='9').filter(job_id=job_id,approvestep=pnode_steprun.step) if approve_log.exists(): for log in approve_log: users = User.objects.filter(id=log.approveuser_id) if users: user = users[0].userinfo.fullname if user: approve_user += user + "" second_el_dict["receiveuser"] = approve_user[:-1] # 递归查找子流程下执行的组件 script_list_wrapper = get_child_workflow_node(pnode_steprun, state_dict, num + 1) second_el_dict["script_list_wrapper"] = script_list_wrapper step_info_list.append(second_el_dict) t = TemplateResponse(request, 'pdf.html',{"step_info_list": step_info_list, "first_el_dict": first_el_dict, "ele_xml01": ele_xml01,"ele_xml02": ele_xml02, "abstract_xml": abstract_xml}) t.render() current_path = os.getcwd() if sys.platform.startswith("win"): # 指定wkhtmltopdf运行程序路径 wkhtmltopdf_path = current_path + os.sep + "drm" + os.sep + "static" + os.sep + "pages" + os.sep + "process" + os.sep + "wkhtmltopdf" + os.sep + "bin" + os.sep + "wkhtmltopdf.exe" config = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_path) else: config = None options = { 'page-size': 'A3', 'margin-top': '0.75in', 'margin-right': '0.75in', 'margin-bottom': '0.75in', 'margin-left': '0.75in', 'encoding': "UTF-8", 'no-outline': None } css_path = current_path + os.sep + "drm" + os.sep + "static" + os.sep + "assets" + os.sep + "global" + os.sep + "css" + os.sep + "bootstrap.css" css = [r"{0}".format(css_path)] pdfkit.from_string(t.content.decode(encoding="utf-8"), r"RecoveryReport.pdf", configuration=config,options=options, css=css) the_file_name = "RecoveryReport.pdf" response = StreamingHttpResponse(file_iterator(the_file_name)) response['Content-Type'] = 'application/octet-stream; charset=unicode' response['Content-Disposition'] = 'attachment;filename="{0}"'.format(the_file_name) return response def get_child_workflow_node(pnode_steprun, state_dict, num): """ pnode_steprun: 父流程对象 state_dict: 状态 num: 构造标题数字 1. 1.1 1.1.1 1.1.2 1.2 1.2.1 2. 3. """ script_list_wrapper = [] if pnode_steprun.type == 'WORKFLOW': # 去除控件、去除组件<RTO结束时间> child_job = TSDRMJob.objects.exclude(state='9').exclude(type='CONTROL').exclude(modelguid='ce74993e-307e-11ec-860c-7412b3a42edd').filter(pjob_id=pnode_steprun.id) if child_job: for snum, current_job in enumerate(child_job): script_el_dict = dict() # 标题数字 title_num = str(num) + "." + str(snum + 1) script_name = "{0} {1}".format(title_num, current_job.name) script_el_dict["script_name"] = script_name start_time = current_job.starttime.strftime("%Y-%m-%d %H:%M:%S") if current_job.starttime else "" end_time = current_job.endtime.strftime("%Y-%m-%d %H:%M:%S") if current_job.endtime else "" script_el_dict["start_time"] = start_time script_el_dict["end_time"] = end_time if start_time and end_time: delta_seconds = datetime.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S') - datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') hour, minute, second = str(delta_seconds).split(":") delta_time = "{0}时{1}分{2}秒".format(hour, minute, second) script_el_dict["rto"] = delta_time else: script_el_dict["rto"] = "" script_el_dict["state"] = state_dict.get(current_job.state) script_el_dict["log"] = current_job.log if current_job.type == 'WORKFLOW': script_el_dict["script_list_wrapper"] = get_child_workflow_node(current_job, state_dict, title_num) script_list_wrapper.append(script_el_dict) return script_list_wrapper

下载预览:

原文地址:https://www.cnblogs.com/zhangguosheng1121/p/15740242.html