tfse-model-api-v0.2/Report/PdfReport.py

236 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from hashlib import sha1
from reportlab.lib.colors import HexColor
from reportlab.lib.units import cm, inch
from reportlab.platypus import Paragraph, Image, PageBreak, Frame, Table
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.pdfgen import canvas
from Report.scripts.PdfStyle import cover_space, cover_company_style, cover_report_style, cover_time_style, \
chapter_style, \
section_style, adjust_line_width, para_style_single, para_style_bold, table_name, table_unit, table_mark, \
adjust_table_widths, adjust_table_style, Seashell4, toc_style_1, table_content_style, toc_style_2, darkGolden, \
adjust_table_data, para_bold_style, para_style_esg, para_style_special
from Report.scripts.path_tool import gen_pdf_path, get_pic_path
from common.scripts import read_json_file
class HeaderAndFooterCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
self.offeset = 3
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
def draw_header_and_footer(self, page_count):
self.setFont("Helvetica", 7)
if self._pageNumber > self.offeset:
self.setFont('pingbold', 8)
self.setFillColor(HexColor(Seashell4))
self.drawString(74, 805, "远东资信评估有限公司")
self.drawString(74, 40, "%d / %d" % (self._pageNumber - self.offeset, page_count - self.offeset))
self.setStrokeColor(darkGolden)
self.setLineWidth(2.5)
self.line(74, 820, 6.8 * inch, 820)
self.setLineWidth(1)
self.line(74, 50, 6.8 * inch, 50)
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_header_and_footer(num_pages)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
class EsgHeaderAndFooterCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
self.offeset = 2
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
def draw_header_and_footer(self, page_count):
self.setFont("Helvetica", 7)
if self._pageNumber > self.offeset:
self.setFont('pingbold', 8)
self.setFillColor(HexColor(Seashell4))
self.drawString(74, 805, "远东资信评估有限公司")
self.drawString(74, 40, "%d / %d" % (self._pageNumber - self.offeset, page_count - self.offeset))
self.setStrokeColor(darkGolden)
self.setLineWidth(2.5)
self.line(74, 820, 6.8 * inch, 820)
self.setLineWidth(1)
self.line(74, 50, 6.8 * inch, 50)
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_header_and_footer(num_pages)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
self.allowSplitting = 1
BaseDocTemplate.__init__(self, filename, **kw)
template = PageTemplate('normal', [Frame(2.5 * cm, 2.5 * cm, 15 * cm, 25 * cm, id='F1')])
self.addPageTemplates(template)
self.offeset = kw['offeset']
def afterFlowable(self, flowable):
if flowable.__class__.__name__ == 'Paragraph':
text = flowable.getPlainText()
style = flowable.style.name
if style == 'chapter_style':
level = 1
elif style == 'section_style':
level = 2
else:
return
e = (level, text, self.page - self.offeset)
self.notify('TOCEntry', e)
class ReportGenerator:
def __init__(self, **kwargs):
# 文本数据
self.text_model = kwargs['text_model']
if '报告类型' in self.text_model:
# 调用模板在临时报告文件夹中创建指定名称的PDF文档
self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']), offeset=2)
else:
self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']), offeset=3)
# 内容框
self.story = list()
# 生成报告
def gen_report(self):
if '报告类型' in self.text_model:
self.gen_esg_cover()
self.gen_menu()
self.gen_esg_part()
self.doc.multiBuild(self.story, canvasmaker=EsgHeaderAndFooterCanvas)
else:
self.gen_cover()
self.gen_menu()
self.gen_main_part()
self.doc.multiBuild(self.story, canvasmaker=HeaderAndFooterCanvas)
# 设置章节、小节标题
def set_head(self, text, sty):
bn = sha1("Vintage".encode('utf-8')).hexdigest()
h = Paragraph(text + '<a name="%s"/>' % bn, sty)
h._bookmarkName = bn
self.story.append(h)
# 目录
def gen_menu(self):
toc = TableOfContents()
toc.levelStyles = [toc_style_1, toc_style_2]
self.story.append(Paragraph('目录', table_content_style))
self.story.append(toc)
self.story.append(PageBreak())
# 封面
def gen_cover(self):
data = self.text_model
# self.story.append(PageBreak())
self.story.append(Paragraph('.', cover_space))
self.story.append(Paragraph(data['企业名称'], cover_company_style))
self.story.append(Paragraph('综合信用等级评价报告', cover_report_style))
self.story.append(Image(get_pic_path(pic_name='ydzx.png'), width=202, height=37))
self.story.append(Paragraph(data['生成日期'], cover_time_style))
self.story.append(PageBreak())
# esg封面
def gen_esg_cover(self):
data = self.text_model
self.story.append(Paragraph('.', cover_space))
self.story.append(Paragraph(data['企业名称'], cover_company_style))
self.story.append(Paragraph('ESG评价报告', cover_report_style))
self.story.append(Image(get_pic_path(pic_name='ydzx.png'), width=202, height=37))
self.story.append(Paragraph(data['生成日期'], cover_time_style))
self.story.append(PageBreak())
# 正文
def gen_main_part(self):
data = self.text_model['报告内容']
for chapter in data:
self.set_head(chapter['章节'], chapter_style)
for section in chapter['章节内容']:
self.set_head(section['小节'], section_style)
for part in section['小节内容']:
# 段落
if list(part.keys())[0] == '段落':
self.story.append(Paragraph(adjust_line_width(part['段落'], 8), para_style_single))
# self.story.append(Paragraph(part['段落'], para_style_single))
# 节点
elif list(part.keys())[0] == '节点':
self.story.append(Paragraph(part['节点'], para_style_bold))
# 表名
elif list(part.keys())[0] == '表名':
self.story.append(Paragraph(part['表名'], table_name))
# 单位
elif list(part.keys())[0] == '单位':
self.story.append(Paragraph(part['单位'], table_unit))
# 注释
elif list(part.keys())[0] == '注释':
self.story.append(Paragraph(part['注释'], table_mark))
# 表格
elif list(part.keys())[0] == '表格':
style = adjust_table_style(part['表格'])
td = adjust_table_data(part['表格'])
self.story.append(Table(td, style=style))
# esg正文
def gen_esg_part(self):
data = self.text_model['报告内容']
for chapter in data:
self.set_head(chapter['章节'], chapter_style)
for section in chapter['章节内容']:
# 段落
if list(section.keys())[0] == '段落':
factor_01 = True if '绿色业务收入占比(%' in section['段落'] else False
factor_02 = True if '公司在近三年因环境问题受到监管处罚' in section['段落'] else False
factor_03 = True if '这影响了公司的社会得分' in section['段落'] else False
factor_04 = True if '公司在近三年有过扶贫、捐赠行为' in section['段落'] else False
factor_05 = True if '经查公司存在1项或多项的法律诉讼' in section['段落'] else False
factor_06 = True if '这影响了公司在治理方面的得分' in section['段落'] else False
if factor_01 or factor_02 or factor_03 or factor_04 or factor_05 or factor_06:
self.story.append(Paragraph(adjust_line_width(section['段落'], 8), para_style_special))
else:
self.story.append(Paragraph(adjust_line_width(section['段落'], 8), para_style_single))
if __name__ == '__main__':
text_data = read_json_file('/Report/static/ReportTemplates/ESG报告.json')
m = ReportGenerator(name=text_data['企业名称'], text_model=text_data)
m.gen_report()