python之reportlab生成PDF文件


  項目需要,需要自動生成PDF測試報告。經過對比之后,選擇使用了reportlab模塊。

  項目背景:開發一個測試平台,供測試維護測試用例,執行測試用例,並且生成測試報告(包含PDF和excel),將生成的測試報告以郵件的形式發送相關人。

  reportlab生成PDF文件的代碼如下:

  

from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, PageBreak, Table, TableStyle
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('pingbold', 'PingBold.ttf'))
pdfmetrics.registerFont(TTFont('ping', 'ping.ttf'))
pdfmetrics.registerFont(TTFont('hv', 'Helvetica.ttf'))

# 生成PDF文件
class PDFGenerator:
    def __init__(self, filename):
        self.filename = filename
        self.file_path = '/xxx/xxx/xxx/xxx/'
        self.title_style = ParagraphStyle(name="TitleStyle", fontName="pingbold", fontSize=48, alignment=TA_LEFT,)
        self.sub_title_style = ParagraphStyle(name="SubTitleStyle", fontName="hv", fontSize=32,
                                              textColor=colors.HexColor(0x666666), alignment=TA_LEFT, )
        self.content_style = ParagraphStyle(name="ContentStyle", fontName="ping", fontSize=18, leading=25, spaceAfter=20,
                                            underlineWidth=1, alignment=TA_LEFT, )
        self.foot_style = ParagraphStyle(name="FootStyle", fontName="ping", fontSize=14, textColor=colors.HexColor(0xB4B4B4),
                                         leading=25, spaceAfter=20, alignment=TA_CENTER, )
        self.table_title_style = ParagraphStyle(name="TableTitleStyle", fontName="pingbold", fontSize=20, leading=25,
                                                spaceAfter=10, alignment=TA_LEFT, )
        self.sub_table_style = ParagraphStyle(name="SubTableTitleStyle", fontName="ping", fontSize=16, leading=25,
                                                spaceAfter=10, alignment=TA_LEFT, )
        self.basic_style = TableStyle([('FONTNAME', (0, 0), (-1, -1), 'ping'),
                                       ('FONTSIZE', (0, 0), (-1, -1), 12),
                                       ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                                       ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                       ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
                                       # 'SPAN' (列,行)坐標
                                       ('SPAN', (1, 0), (3, 0)),
                                       ('SPAN', (1, 1), (3, 1)),
                                       ('SPAN', (1, 2), (3, 2)),
                                       ('SPAN', (1, 5), (3, 5)),
                                       ('SPAN', (1, 6), (3, 6)),
                                       ('SPAN', (1, 7), (3, 7)),
                                       ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
                                       ])
        self.common_style = TableStyle([('FONTNAME', (0, 0), (-1, -1), 'ping'),
                                      ('FONTSIZE', (0, 0), (-1, -1), 12),
                                      ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
                                      ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                                      ('BOTTOMPADDING', (0, 0), (-1, -1), 6),
                                      ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
                                     ])

    def genTaskPDF(self, home_data, task_data, basic_data, case_set_data, fail_case_data, p0_case_data):
        story = []

        # 首頁內容
        story.append(Spacer(1, 20 * mm))
        img = Image('/xxx/xxx.png')
        img.drawHeight = 20 * mm
        img.drawWidth = 40 * mm
        img.hAlign = TA_LEFT
        story.append(img)
        story.append(Spacer(1, 10 * mm))
        story.append(Paragraph("測試報告", self.title_style))
        story.append(Spacer(1, 20 * mm))
        story.append(Paragraph("Test Report of XXX", self.sub_title_style))
        story.append(Spacer(1, 45 * mm))
        story.append(Paragraph("報告編號:" + home_data['report_code'], self.content_style))
        story.append(Paragraph("計划名稱:" + home_data['task_name'], self.content_style))
        story.append(Paragraph("報告日期:" + home_data['report_date'], self.content_style))
        story.append(Paragraph(" 負責人:" + home_data['report_creator'], self.content_style))
        story.append(Spacer(1, 55 * mm))
        story.append(Paragraph("內部文檔,請勿外傳", self.foot_style))
        story.append(PageBreak())

        # 表格允許單元格內容自動換行格式設置
        stylesheet = getSampleStyleSheet()
        body_style = stylesheet["BodyText"]
        body_style.wordWrap = 'CJK'
        body_style.fontName = 'ping'
        body_style.fontSize = 12

        # 測試計划
        story.append(Paragraph("測試計划", self.table_title_style))
        story.append(Spacer(1, 3 * mm))
        task_table = Table(task_data, colWidths=[25 * mm, 141 * mm], rowHeights=12 * mm, style=self.common_style)
        story.append(task_table)

        story.append(Spacer(1, 10 * mm))

        # 基礎參數
        story.append(Paragraph("基礎參數", self.sub_table_style))
        basic_table = Table(basic_data, colWidths=[25*mm, 61*mm, 25*mm, 55*mm], rowHeights=12 * mm, style=self.basic_style)
        story.append(basic_table)

        story.append(Spacer(1, 10 * mm))

        # 測試用例集
        story.append(Paragraph("用例集參數", self.sub_table_style))
        case_set_table = Table(case_set_data, colWidths=[25 * mm, 141 * mm], rowHeights=12 * mm, style=self.common_style)
        story.append(case_set_table)

        # story.append(PageBreak())
        story.append(Spacer(1, 15 * mm))

        # 失敗用例--使用可以自動換行的方式需要data里都是str類型的才OK
        story.append(Paragraph("失敗用例", self.table_title_style))
        story.append(Spacer(1, 3 * mm))
        para_fail_case_data = [[Paragraph(cell, body_style) for cell in row] for row in fail_case_data]
        fail_case_table = Table(para_fail_case_data, colWidths=[20 * mm, 35 * mm, 91 * mm, 20 * mm])
        fail_case_table.setStyle(self.common_style)
        story.append(fail_case_table)

        story.append(Spacer(1, 15 * mm))

        # 基礎用例(P0)
        story.append(Paragraph("基礎用例(P0)", self.table_title_style))
        story.append(Spacer(1, 3 * mm))
        para_p0_case_data = [[Paragraph(cell, body_style) for cell in row] for row in p0_case_data]
        p0_case_table = Table(para_p0_case_data, colWidths=[20 * mm, 35 * mm, 91 * mm, 20 * mm])
        p0_case_table.setStyle(self.common_style)
        story.append(p0_case_table)

        doc = SimpleDocTemplate(self.file_path + self.filename + ".pdf",
                                leftMargin=20 * mm, rightMargin=20 * mm, topMargin=20 * mm, bottomMargin=20 * mm)


        doc.build(story)

 

  生成樣式:

    

 

  需要說明的:

  1.項目后台使用的是python2.7.5;

  2.如果需要使用到特定的字體,需要將字體下載下來放到reportlab模塊安裝位置的font文件夾下,如:/xxx/python2.7/site-packages/reportlab/fonts/;

  3.有官方的使用文檔可以參考,如有不懂,可以下載官方說明文檔查看;

  4.支持表格中的中文依文字長度自動換行

 

代碼中使用到的字體下載鏈接:

鏈接: https://pan.baidu.com/s/10p7YxZ0Z32d5z85O8puabg 提取碼: sk8q

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM