# -*- coding: utf-8 -*- import json 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 sqlalchemy.orm import Session from docx.shared import Pt, Inches from starlette.responses import FileResponse from Utils.DataBase.MongoHelperUtils import MongoHelper, get_mongodb from Utils.DataBase.SqlAlchemyUtils import get_db router = APIRouter( prefix="/api/report_generation" ) # 文件路径 data_template = os.path.join(os.getcwd(), 'Utils', 'File', 'template', 'report_temp.json') report_data = os.path.join(os.getcwd(), 'Utils', 'File', 'template', 'report_data.json') 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.get("/generation", summary="生成word报告", tags=["报告生成"]) def func(company_id: str = "企业ID", db: Session = Depends(get_db), mongodb: MongoHelper = Depends(get_mongodb)): # 获取报告模板 doc = DocxTemplate(file_template) # 获取填报数据 with open(report_data, encoding='gbk') as f: report_content = json.load(f) # 替换除表格以外的数据 doc.render(report_content) doc.save(file_path) # 处理表格数据 file = Document(file_path) # 处理商标表格 brand_table = file.tables[3] 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)): brand_table.add_row() # 当前行 current_row = len(brand_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', 'picture.jpg') pic = brand_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: brand_table.cell(current_row, r_i).text = str(brand_data[brand_index][r_i]) for section in brand_table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) brand_table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER brand_table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 处理专利表格 patent_table = file.tables[4] 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)): patent_table.add_row() # 当前行 current_row = len(patent_table.rows) - 1 for r_i in range(len(patent_data[patent_index])): patent_table.cell(current_row, r_i).text = str(patent_data[patent_index][r_i]) for section in patent_table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) patent_table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER patent_table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 处理软件著作权表格 software_table = file.tables[5] 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)): software_table.add_row() # 当前行 current_row = len(software_table.rows) - 1 for r_i in range(len(software_data[software_index])): software_table.cell(current_row, r_i).text = str(software_data[software_index][r_i]) for section in software_table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) software_table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER software_table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 处理供应商表格 supplier_table = file.tables[6] 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)): supplier_table.add_row() # 当前行 current_row = len(supplier_table.rows) - 1 for r_i in range(len(supplier_data[supplier_index])): supplier_table.cell(current_row, r_i).text = str(supplier_data[supplier_index][r_i]) for section in supplier_table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) supplier_table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER supplier_table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 处理招投标数据 tender_table = file.tables[7] 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)): tender_table.add_row() # 当前行 current_row = len(tender_table.rows) - 1 for r_i in range(len(tender_data[tender_index])): tender_table.cell(current_row, r_i).text = str(tender_data[tender_index][r_i]) for section in tender_table.cell(current_row, r_i).paragraphs: for block in section.runs: block.font.size = Pt(9) tender_table.cell(current_row, r_i).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER tender_table.cell(current_row, r_i).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 处理财务数据 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, '指标名称') finance_table = file.tables[8] rows = len(finance_table.rows) cols = len(finance_table.columns) for row in range(rows): for col in range(cols): if col != 0: finance_table.cell(row, col).text = str(result[row][col]) finance_table.cell(row, col).vertical_alignment = WD_PARAGRAPH_ALIGNMENT.CENTER finance_table.cell(row, col).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER for section in finance_table.cell(row, col).paragraphs: for block in section.runs: block.font.size = Pt(9) file.save(file_path) return { "code": 200, "message": "生成成功" }