from hashlib import sha1 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 Modules.Reports.ReportPathImpl import gen_pdf_path, get_pic_path from Modules.Reports.PdfStyleIpml import * 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 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'] self.doc = MyDocTemplate(gen_pdf_path(name=kwargs['name']), offeset=3) # 内容框 self.story = list() # 生成报告 def gen_report(self): 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 + '' % 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(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()) # 正文 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)) # 节点 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] == '表格' and part[list(part.keys())[0]]: style = adjust_table_style(part['表格']) td = adjust_table_data(part['表格']) self.story.append(Table(td, style=style))