237 lines
9.6 KiB
Python
237 lines
9.6 KiB
Python
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:
|
||
offeset = 2
|
||
self.gen_esg_cover()
|
||
self.gen_menu()
|
||
self.gen_esg_part()
|
||
self.doc.multiBuild(self.story, canvasmaker=EsgHeaderAndFooterCanvas)
|
||
else:
|
||
offeset = 3
|
||
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()
|