html-table学习

178 阅读3分钟

参考链接:fasionchan.com/python/libs…

反思

谨慎使用set_styleset_cell_styleset_header_cell_style全局样式

多使用table[row].set_cell_style单行样式

实践

# -*-coding:utf-8-*-
import datetime
import json
import time

import pythoncom
import requests
import win32com.client as win32
from HTMLTable import HTMLTable


class Email:
    def __init__(self):
        self.send_flag = True
        self.mail = None

    @staticmethod
    def get(url, params=None, data=None):
        return requests.get(url=url, params=params, data=data)

    @staticmethod
    def post(url, params=None, data=None):
        return requests.post(url=url, params=params, data=data)

    def send(self):
        pythoncom.CoInitialize()
        outlook = win32.Dispatch('outlook.application')
        self.mail = outlook.CreateItem(0)
        self.mail.To = ''  # 收件人

        self.mail.Subject = f'【请阅】 文件对比结果({str(datetime.date.today())})'  # 邮件主题
        self.get_table()
        with open('test.html', 'r', encoding='utf8')as f:
            self.mail.HTMLBody = f.read()  # 邮件正文
        self.mail.Send()
        pythoncom.CoUninitialize()

    def get_c_diff(self):
        res = self.get('http://127.0.0.1:8080/get/config/info',
                       params={'name': 'c_cur_branch'}).json()
        branch = res.get('result')[0].get('value')

        res = self.get('http://127.0.0.1:8080/get/todaydata/').json()
        c_diff = []
        for file in res.get('change'):
            c_diff.append(file.get('name'))
        return c_diff

    def get_excel_check_result(self):
        date = int(time.mktime(datetime.date.today().timetuple()))
        res = self.get('http://127.0.0.1:8080/get/excel/checkResult',
                       params={'time': date}).json().get('result')
        excel_diff = {}
        for data in res:
            module = excel_module.get(data.get('excel'))
            if not excel_diff.get(module):
                excel_diff[module] = []
            excel_diff[module].append(
                {'excel': data.get('excel'), 'sheet': data.get('sheet'), 'reason': data.get('reason')})
        return excel_diff

    def get_java_excel_diff(self):
        res = self.get('http://127.0.0.1:8080/get/config/info',
                       params={'name': 'excel_cur_branch'}).json()
        branch = res.get('result')[0].get('value')

        res = self.get('http://127.0.0.1:8080/get/java/cp/func').json()
        res = res.get('result')
        func_diff = {}
        for data in res:
            module = excel_module.get(data.get('dboxname'))
            if not func_diff.get(module):
                func_diff[module] = []
            func_diff[module].append()

        struct_diff = {}
        res = self.get('http://127.0.0.1:8080/get/java/cp/param').json()
        res = res.get('result')
        for data in res:
            module = excel_module.get(data.get(''))
            if not struct_diff.get(module):
                struct_diff[module] = []
            struct_diff[module].append()
        return func_diff, struct_diff

    def get_java_diff(self):
        res = self.get('http://127.0.0.1:8080/get/config/info',
                       params={'name': 'java_cur_branch'}).json()
        branch = res.get('result')[0].get('value')

        res = self.get('http://127.0.0.1:8080/get/java/file/change/info').json()
        files = res.get('result')
        java_diff = {}
        for data in files:
            if data.get('mark') == 'diff':
                module = data.get('path').split('/')[1]
                if not java_diff.get(module):
                    java_diff[module] = []
                java_diff[module].append()
        return java_diff

    def get_aidl_diff(self):
        module_path = {}
        hub = self.get('http://127.0.0.1:8080/get/aidl/json').json().get('result')
        aidl_diff = {}
        for module in []:
            local = self.get('http://127.0.0.1:8080/get/aidl/text', params={'name': module}).json().get(
                'result')
            if hub.get(module) != local:
                aidl_diff[module] = module_path.get(module)

        return aidl_diff

    def get_table(self):
        table = HTMLTable()

        #  文件对比结果
        table.append_header_rows((
            (f'文件对比结果({str(datetime.date.today())})', '', '', '', '', '', '', '', '', ''),
        ))
        table[0][0].attr.colspan = 10
        table[0].set_cell_style({
            'color': '#ffffff', 'background-color': '#5686bf', 'font-size': '36px', 'text-align': 'center',
            'font-weight': 'bold'
        })

        # 分支
        self.set_sec_header_data_and_style(f'【分支】{self.branch}', table)

        # -------------------------- C文件对比 --------------------------
        self.set_header_data_and_style(
            'C文件对比',
            table)
        c_diff = self.get_c_diff()
        row = self.get_last_row_num(table)
        if not c_diff:
            table.append_data_rows((('不一致文件', '', '', '无', '', '', '', '', '', ''),))
            table[row][0].attr.colspan = 3
            table[row][3].attr.colspan = 7
            self.set_data_style(table, row)
        else:
            start_row = self.get_last_row_num(table)
            for file in c_diff:
                table.append_data_rows((('不一致文件', '', '', file, '', '', '', '', '', ''),))
                table[row][0].attr.colspan = 3
                table[row][3].attr.colspan = 7
                self.set_data_style(table, row)
                row += 1
            end_row = self.get_last_row_num(table)
            table[start_row][0].attr.rowspan = end_row - start_row

        # -------------------------- Excel格式校验 --------------------------
        self.set_header_data_and_style('Excel文件对比', table)
        self.set_sec_header_data_and_style('Excel格式校验结果', table)
        row = self.get_last_row_num(table)
        table.append_data_rows((
            ('组件', 'Excel文件名', '', '', 'sheet表名', '校验结果', '', '', '', ''),
        ))
        self.set_first_line_style(table, row)
        table[row][1].attr.colspan = 3
        table[row][5].attr.colspan = 5

        excel_diff = self.get_excel_check_result()
        row = self.get_last_row_num(table)
        if not excel_diff:
            table.append_data_rows(
                (('无', '', '', '无', '无', '', '', '', '', ''),))
            table[row][1].attr.colspan = 3
            table[row][5].attr.colspan = 5
            self.set_data_style(table, row)
        else:
            for module, infos in excel_diff.items():
                module_start_row = self.get_last_row_num(table)
                for info in infos:
                    table.append_data_rows(
                        ((module, info.get('excel'), '', '', info.get('sheet'), info.get('reason'), '', '', '', ''),))
                    table[row][1].attr.colspan = 3
                    table[row][5].attr.colspan = 5
                    self.set_data_style(table, row)
                    row += 1
                module_end_row = self.get_last_row_num(table)
                table[module_start_row][1].attr.rowspan = module_end_row - module_start_row

        # -------------------------- Excel与Java对比 --------------------------
        # 类方法
        func_diff, struct_diff = self.get_java_excel_diff()
        self.set_sec_header_data_and_style('Excel与Java对比结果', table)
        row = self.get_last_row_num(table)
        table.append_data_rows((
            ('类型', '组件', 'Excel文件名', '类名', '方法名', '参数名', '类型(值)', '类型(仓库值)', '返回类型(值)', '返回类型(仓库值)'),
        ))
        self.set_first_line_style(table, row)
        row = self.get_last_row_num(table)
        if not func_diff:
            table.append_data_rows((('没有异常', '', '', '', '', '', '', '', '', ''),))
            table[row][0].attr.colspan = 10
            self.set_data_style(table, row)
        else:
            class_start_row = self.get_last_row_num(table)
            for module, infos in func_diff.items():
                module_start_row = self.get_last_row_num(table)
                for info in infos:
                    table.append_data_rows()
                    self.set_data_style(table, row)
                    row += 1
                module_end_row = self.get_last_row_num(table)
                table[module_start_row][1].attr.rowspan = module_end_row - module_start_row

            class_end_row = self.get_last_row_num(table)
            table[class_start_row][0].attr.rowspan = class_end_row - class_start_row

        # 结构体/枚举
        row = self.get_last_row_num(table)
        table.append_data_rows((('类型', '组件', 'Excel文件名', '类名', '', '参数名', '类型(值)', '', '类型(仓库值)', ''),))
        self.set_first_line_style(table, row)
        table[row][3].attr.colspan = 2
        table[row][6].attr.colspan = 2
        table[row][8].attr.colspan = 2
        row = self.get_last_row_num(table)
        if not struct_diff:
            table.append_data_rows((('没有异常', '', '', '', '', '', '', '', '', ''),))
            table[row][0].attr.colspan = 10
            self.set_data_style(table, row)
        else:
            class_start_row = self.get_last_row_num(table)
            for module, infos in struct_diff.items():
                module_start_row = self.get_last_row_num(table)
                for info in infos:
                    table.append_data_rows()
                    table[row][3].attr.colspan = 2
                    table[row][6].attr.colspan = 2
                    table[row][8].attr.colspan = 2
                    self.set_data_style(table, row)
                    row += 1
                module_end_row = self.get_last_row_num(table)
                table[module_start_row][1].attr.rowspan = module_end_row - module_start_row

            class_end_row = self.get_last_row_num(table)
            table[class_start_row][0].attr.rowspan = class_end_row - class_start_row

        # -------------------------- Java文件对比 --------------------------
        self.set_header_data_and_style(
            'Java文件对比(表格只显示不一致文件名,详情查看)', table)
        row = self.get_last_row_num(table)
        table.append_data_rows((('组件', '文件名', '文件路径', '', '', '', '代码文件路径', '', '', ''),))
        self.set_first_line_style(table, row)
        table[row][2].attr.colspan = 4
        table[row][6].attr.colspan = 4
        java_diff = self.get_java_diff()
        row = self.get_last_row_num(table)
        if not java_diff:
            table.append_data_rows((('无', '无', '无', '', '', '', '无', '', '', ''),))
            table[row][2].attr.colspan = 4
            table[row][6].attr.colspan = 4
            self.set_data_style(table, row)
        else:
            for module, infos in java_diff.items():
                start_row = self.get_last_row_num(table)
                for info in infos:
                    table.append_data_rows(
                        ((module, info.get('file'), info.get(''), '', '', '', info.get('hub'), '', '', ''),))
                    table[row][2].attr.colspan = 4
                    table[row][6].attr.colspan = 4
                    table[row].set_cell_style({'text-align': 'left', 'font-size': '14px'})
                    row += 1
                end_row = self.get_last_row_num(table)
                table[start_row][0].attr.rowspan = end_row - start_row

        # -------------------------- Aidl文件对比 --------------------------
        self.set_header_data_and_style(
            'Aidl文件对比',
            table)
        row = self.get_last_row_num(table)
        table.append_data_rows((('组件', '', '文件代码仓路径', '', '', '', '', '', '', ''),))
        self.set_first_line_style(table, row)
        table[row][0].attr.colspan = 2
        table[row][2].attr.colspan = 8

        row = self.get_last_row_num(table)
        aidl_data = self.get_aidl_diff()
        if not aidl_data:
            table.append_data_rows((('无', '', '无', '', '', '', '', '', '', ''),))
            table[row][0].attr.colspan = 2
            table[row][2].attr.colspan = 8
            self.set_data_style(table, row)
        else:
            for module, path in aidl_data.items():
                table.append_data_rows(((module, '', path, '', '', '', '', '', '', ''),))
                table[row][0].attr.colspan = 2
                table[row][2].attr.colspan = 8
                self.set_data_style(table, row)
                row += 1

        self.set_global_style(table)
        html = table.to_html()
        with open('test.html', 'w', encoding='utf8') as f:
            f.write('<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>')
            f.write(html)
        return html

    @staticmethod
    def set_global_style(table):
        # 表格样式,即<table>标签样式
        table.set_style({
            'border-collapse': 'collapse',
            'word-break': 'keep-all',
            'white-space': 'nowrap',
            'font-family': 'SimSun'
        })

        # 统一设置所有单元格样式,<td>或<th>
        table.set_cell_style({
            'border-color': '#000',
            'border-width': '2px',
            'border-style': 'solid',
            'padding': '2px',
            'width': '140px',
            'word-break': 'break-all'
        })

        # 设置所有表头单元格
        table.set_header_cell_style({
            'padding-top': '10px',
            'padding-bottom': '10px',
            'padding-right': '10px',
        })

    def set_header_data_and_style(self, str_, table):
        row = self.get_last_row_num(table)
        table.append_header_rows((
            (str_, '', '', '', '', '', '', '', '', ''),
        ))
        table[row][0].attr.colspan = 10
        table[row].set_cell_style({
            'color': '#000000',
            'background-color': '#5686bf',
            'font-size': '16px',
            'text-align': 'left',
            'font-weight': 'bold',
        })

    def set_sec_header_data_and_style(self, str_, table):
        row = self.get_last_row_num(table)
        table.append_data_rows((
            (str_, '', '', '', '', '', '', '', '', ''),
        ))
        table[row][0].attr.colspan = 10
        table[row].set_cell_style({
            'color': '#000000',
            'background-color': '#48a6f8',
            'font-size': '14px',
            'text-align': 'left',
            'font-weight': 'bold'
        })

    @staticmethod
    def set_first_line_style(table, row):
        table[row].set_cell_style({
            'color': '#000000',
            'background-color': '#deeaf6',
            'font-size': '14px',
            'text-align': 'center',
            'font-weight': 'bold'
        })

    @staticmethod
    def set_data_style(table, row):
        table[row].set_cell_style({'text-align': 'center', 'font-size': '14px'})

    @staticmethod
    def get_last_row_num(table):
        head_count = 0
        for _ in table.iter_header_rows():
            head_count += 1
        data_count = 0
        for _ in table.iter_data_rows():
            data_count += 1
        return head_count + data_count


if __name__ == '__main__':
    email = Email()
    # email.send()
    # email.get_c_diff()
    # email.get_excel_check_result()
    # email.get_java_excel_diff()
    # email.get_java_diff()
    # email.get_aidl_diff()
    email.get_table()