# -*- coding: utf-8 -*- import os from docx import Document from docx.enum.text import WD_PARAGRAPH_ALIGNMENT from docxtpl import DocxTemplate from fastapi import APIRouter, Depends, HTTPException from docx.shared import Pt, Inches from starlette.background import BackgroundTask from starlette.responses import FileResponse from App.Schemas import ReportSchemas router = APIRouter( prefix="/api/report_generation" ) def del_file(path): os.remove(path) # 文件路径 file_template = os.path.join(os.getcwd(), 'Utils', 'File', 'template', '信用报告模板.docx') file_path = os.path.join(os.getcwd(), 'Utils', 'File', 'generate', '信用报告.docx') @router.get("/report_template", summary="查看报告模板", tags=["报告生成"]) def func(): file = '信用报告模板.docx' response = FileResponse(file_template, filename=file, media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document') return response @router.post("/generation", summary="生成word报告", tags=["报告生成"]) def func(schemas: ReportSchemas.ReportData): # 获取报告模板 doc = DocxTemplate(file_template) # 获取填报数据 report_content = schemas.dict() file_name = '{}信用报告.docx'.format(report_content.get('企业名称')) # 替换除表格以外的数据 doc.render(report_content) doc.save(file_path) # 处理表格数据 file = Document(file_path) tables = file.tables tables_to_keep = list() # 处理表格数据 for table in tables: if table.rows[0].cells[0].text == '申请日期': if report_content.get('商标信息'): brand_data = [] for item in report_content.get('商标信息'): row = [] for key in item: row.append(item[key]) brand_data.append(row) for brand_index in range(0, len(brand_data)): table.add_row() # 当前行 current_row = len(table.rows) - 1 for r_i in range(len(brand_data[brand_index])): if r_i == 1: pic_path = os.path.join(os.getcwd(), 'Utils', 'File', 'picture', 'SB.jpg') pic = table.cell(current_row, r_i).paragraphs[0].add_run().add_picture(pic_path) pic.width = Inches(0.9) pic.height = Inches(0.9) else: table.cell(current_row, r_i).text = str(brand_data[brand_index][r_i]) for section in table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER elif table.rows[0].cells[0].text == '申请日': if report_content.get('专利信息'): patent_data = [] for item in report_content.get('专利信息'): row = [] for key in item: row.append(item[key]) patent_data.append(row) for patent_index in range(0, len(patent_data)): table.add_row() # 当前行 current_row = len(table.rows) - 1 for r_i in range(len(patent_data[patent_index])): table.cell(current_row, r_i).text = str(patent_data[patent_index][r_i]) for section in table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER elif table.rows[0].cells[0].text == '批准日期': if report_content.get('软件著作权'): software_data = [] for item in report_content.get('软件著作权'): row = [] for key in item: row.append(item[key]) software_data.append(row) for software_index in range(0, len(software_data)): table.add_row() # 当前行 current_row = len(table.rows) - 1 for r_i in range(len(software_data[software_index])): table.cell(current_row, r_i).text = str(software_data[software_index][r_i]) for section in table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER elif table.rows[0].cells[0].text == '序号': if report_content.get('主要供应商情况'): supplier_data = [] for index, item in enumerate(report_content.get('主要供应商情况')): row = [index + 1] for key in item: row.append(item[key]) supplier_data.append(row) for supplier_index in range(0, len(supplier_data)): table.add_row() # 当前行 current_row = len(table.rows) - 1 for r_i in range(len(supplier_data[supplier_index])): table.cell(current_row, r_i).text = str(supplier_data[supplier_index][r_i]) for section in table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER elif table.rows[0].cells[0].text == '发布时间': if report_content.get('招投标情况'): tender_data = [] for item in report_content.get('招投标情况'): row = [] for key in item: row.append(item[key]) tender_data.append(row) for tender_index in range(0, len(tender_data)): table.add_row() # 当前行 current_row = len(table.rows) - 1 for r_i in range(len(tender_data[tender_index])): table.cell(current_row, r_i).text = str(tender_data[tender_index][r_i]) for section in table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER elif table.rows[0].cells[0].text == '指标名称': finance_data = report_content.get('主要财务数据') years = list(finance_data.keys()) result = [years] for k in finance_data[years[0]]: row = [k] for y in years: row.append(finance_data[y][k]) result.append(row) result[0].insert(0, '指标名称') rows = len(table.rows) cols = len(table.columns) for row in range(rows): for col in range(cols): if col != 0: table.cell(row, col).text = str(result[row][col]) table.cell(row, col).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER table.cell(row, col).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER for section in table.cell(row, col).paragraphs: for block in section.runs: block.font.size = Pt(9) # 删除数据为空的表格 for table in tables: txt = table.rows[0].cells[0].text if txt == '申请日期' and not report_content.get('商标信息'): tables_to_keep.append(table) elif txt == '申请日' and not report_content.get('专利信息'): tables_to_keep.append(table) elif txt == '批准日期' and not report_content.get('软件著作权'): tables_to_keep.append(table) elif txt == '序号' and not report_content.get('主要供应商情况'): tables_to_keep.append(table) elif txt == '发布时间' and not report_content.get('招投标情况'): tables_to_keep.append(table) # 删除表格 for table in tables_to_keep: tbl = table._element tbl.getparent().remove(tbl) # 新增文字 for para in file.paragraphs: if para.text == "2.3 技术成果" and not report_content.get('商标信息'): new_paragraph = file.add_paragraph("截止报告日,未查询到相关信息。") index = para._element.getparent().index(para._element) para._element.getparent().insert(index + 1, new_paragraph._element) elif para.text == "2.4 软件著作权" and not report_content.get('软件著作权'): new_paragraph = file.add_paragraph("截止报告日,未查询到相关信息。") index = para._element.getparent().index(para._element) para._element.getparent().insert(index + 1, new_paragraph._element) elif para.text == "2.5 主要供应商情况" and not report_content.get('主要供应商情况'): new_paragraph = file.add_paragraph("截止报告日,未查询到相关信息。") index = para._element.getparent().index(para._element) para._element.getparent().insert(index + 1, new_paragraph._element) elif para.text == "2.6 招投标情况" and not report_content.get('招投标情况'): new_paragraph = file.add_paragraph("截止报告日,未查询到相关信息。") index = para._element.getparent().index(para._element) para._element.getparent().insert(index + 1, new_paragraph._element) if not report_content.get('软件著作权'): for para in file.paragraphs: if para.text == '说明:技术成果包括专利、商标、科技进步奖、工法、QC 小组活动成果、参与制定标准等。': p = para._element p.getparent().remove(p) file.save(file_path) task = BackgroundTask(del_file, file_path) return FileResponse(file_path, filename=file_name, media_type='application/octet-stream', background=task)