from reportlab.lib.colors import HexColor from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.lib.styles import ParagraphStyle as PS, ParagraphStyle from reportlab.lib.styles import getSampleStyleSheet from reportlab.platypus import TableStyle, Paragraph from reportlab.lib import colors import pandas as pd import numpy as np from Report.scripts.path_tool import get_font_path # rgb darkGolden = '#C8A063' lightGrey = '#F4F2EF' darkGrey = '#A1A8AB' Seashell4 = '#8B8682' # font pdfmetrics.registerFont(TTFont('pingbold', get_font_path(font='PingBold.ttf'))) pdfmetrics.registerFont(TTFont('SimHei', get_font_path(font='simhei.ttf'))) pdfmetrics.registerFont(TTFont('SIMSUN', get_font_path(font='SIMSUN.ttf'))) pdfmetrics.registerFont(TTFont('SourceHanSerifCN-Bold', get_font_path(font='SourceHanSerifCN-Bold.ttf'))) # toc toc_style_1 = PS(name='TOCHeading1', fontName='pingbold', fontSize=16, leftIndent=20, firstLineIndent=-20, spaceBefore=10, leading=16) toc_style_2 = PS(name='TOCHeading2', fontName='pingbold', fontSize=12, leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12) # table of content table_content_style = PS(name="table_content_style", fontName="pingbold", fontSize=18, leading=40, alignment=TA_CENTER) # cover cover_space = PS(name='cover_space', fontSize=0, leading=75, alignment=TA_CENTER) cover_company_style = PS(name="cover_company_style", fontName="pingbold", fontSize=30, leading=60, alignment=TA_CENTER) cover_report_style = PS(name="cover_report_style", fontName="pingbold", fontSize=18, leading=400, alignment=TA_CENTER) cover_fecr_style = PS(name="cover_fecr_style", fontName="pingbold", fontSize=18, leading=20, alignment=TA_CENTER) cover_time_style = PS(name="cover_time_style", fontName="pingbold", fontSize=16, leading=40, alignment=TA_CENTER, spaceBefore=20) # chapter & section chapter_style = PS(name="chapter_style", fontName="pingbold", fontSize=18, leading=40, alignment=TA_LEFT, spaceBefore=6) section_style = PS(name="section_style", fontName="pingbold", fontSize=12, leading=30, alignment=TA_LEFT, spaceBefore=6, textColor=HexColor(darkGolden)) # table table_name = PS(name="table_name", fontName="pingbold", fontSize=8, leading=16, alignment=TA_CENTER, spaceBefore=2, textColor=HexColor(darkGrey)) table_unit = PS(name="table_unit", fontName="SimHei", fontSize=6, leading=8, alignment=TA_RIGHT, spaceBefore=2) table_mark = PS(name="table_mark", fontName="SimHei", fontSize=6, leading=16, alignment=TA_LEFT, spaceBefore=2) table_style = getSampleStyleSheet() table_style.add(ParagraphStyle(fontName='SimHei', name='Song', leading=12, fontSize=8, spaceBefore=2, alignment=TA_CENTER)) table_style.add(ParagraphStyle(fontName='SimHei', name='Long', leading=12, fontSize=8, spaceBefore=2, alignment=TA_LEFT)) table_style.add(ParagraphStyle(fontName='SimHei', name='Longs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_LEFT)) table_style.add(ParagraphStyle(fontName='SimHei', name='Songs', leading=9, fontSize=6, spaceBefore=2, alignment=TA_CENTER)) table_style.add(ParagraphStyle(fontName='SimHei', name='Song_small', leading=7, fontSize=5, spaceBefore=2, alignment=TA_CENTER)) # para para_style_single = PS(name="para_style_single", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT, spaceBefore=6) para_style_normal = PS(name="para_style_normal", fontName="SimHei", fontSize=8, leading=18, alignment=TA_LEFT, spaceBefore=6, firstLineIndent=16) para_style_bold = PS(name="para_style_bold", fontName="pingbold", fontSize=10, leading=18, alignment=TA_LEFT, spaceBefore=6) para_bold_style = PS(name="para_style", fontName="pingbold", fontSize=9, leading=18, alignment=TA_LEFT, spaceBefore=6) # table def adjust_table_widths(list_): """ 计算表格每列宽度 Parameters: list_: list 表格数据 Returns: result: list 表格宽度列表 """ # 表格默认宽度 total_width = 410 df = pd.DataFrame() for list__ in list_: df = df.append(dict(zip(range(len(list__)), list__)), ignore_index=True) # 将列表中的数据替换成数据的长度,并将0置为NaN df = df.apply(lambda x: x.str.len()) df = df.replace(0, np.NaN) # 计算每列数据长度平均值占总数的多少,并转为列表 width_rate = (df.mean() / df.mean().sum()).values.tolist() # 列数 cols_num = len(width_rate) # 判断首列是否小于默认宽度 if width_rate[0] < 0.33: # 小于默认宽度,用当前数据重新计算各列宽度 widths = [width_rate[0] * total_width] + [((1 - width_rate[0]) / (cols_num - 1)) * total_width] * (cols_num - 1) else: # 大于默认宽度,则继续使用默认宽度继续各列宽度 widths = [0.33 * total_width] + [(0.67 / (cols_num - 1)) * total_width] * (cols_num - 1) return widths def adjust_table_data(list_): """ 调整表格数据样式 Parameters: list_: list 表格数据 Returns: result: list 处理好的表格数据 """ for item_ in list_: if len(item_) > 6: for index in range(len(item_)): if item_[index] != '报告期' and index == 0: item_[index] = Paragraph(item_[index], table_style['Longs']) else: if index == 5 and len(item_[index]) > 10: item_[index] = Paragraph(item_[index], table_style['Song_small']) else: item_[index] = Paragraph(item_[index], table_style['Songs']) else: for index in range(len(item_)): if item_[index] != '报告期' and index == 0: item_[index] = Paragraph(item_[index], table_style['Long']) else: item_[index] = Paragraph(item_[index], table_style['Song']) return list_ def adjust_table_style(list_): return TableStyle([ # 边框 ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.grey), ('BOX', (0, 0), (-1, -1), 1, colors.black), # 文字 ('FONTNAME', (0, 0), (-1, -1), 'SimHei'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), # 排版 ('ALIGN', (1, 0), (-1, -1), 'CENTER'), # 背景 # ('BACKGROUND', (0, 0), (0, -1), HexColor(lightGrey)), ('BACKGROUND', (0, 0), (-1, 0), HexColor(darkGolden)), ]) def adjust_line_width(str_, font_size): mark_length = 400 trans_length = mark_length / font_size - 1 if len(str_) < trans_length: return str_ n = 0 s1 = '' s2 = '' for i in range(len(str_)): if n == 0 and str_[i] in [',', '。', '、', ';']: continue if u'\u4e00' <= str_[i] <= u'\u9fa5': s2 += str_[i] n = n + 1 elif str_[i] in ['!', '?', '。', '"', '#', '$', '%', '&', ''', '(', ')', '*', '+', ',', '-', '-', '/', ':', ';', '<', '=', '>', '@', '[', '\', ']', '^', '_', '`', '{', '|', '}', '~', '、', '〃', '》', '《', '「', '」', '『', '』', '【', '】', '〔', '〕', '〖', '〗', '〝', '〞', '“', '”']: s2 += str_[i] n = n + 1 else: s2 += str_[i] n = n + 0.5 if (n > trans_length) and (i != len(str_) - 1): if str_[i + 1] in [',', '。', '、', ';']: s2 += str_[i + 1] s2 += '
' n = 0 s1 += s2 s2 = '' else: s2 += '
' n = 0 s1 += s2 s2 = '' elif i == len(str_) - 1: s1 += s2 return s1