Python執行sql語句並將結果導出爲Excel打包發送到指定郵箱

import os
import smtplib
import zipfile
from datetime import datetime, timedelta
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import mysql.connector
import xlwt

mysql_host = ''  # TODO 請設置數據庫地址
mysql_port = 3306  # TODO 請設置數據庫端口
mysql_user = ''  # TODO 請設置數據庫用戶名
mysql_password = ''  # TODO 請設置數據庫密碼


class SQL(object):
    def __init__(self, name, params=None, formula=None):
        self._name = name
        self._params = params
        self.formula = formula
        with open(os.path.join('sql', name + '.sql'), 'r', encoding='utf-8') as f:
            self._sql = f.read()

    @property
    def filename(self):
        return self._name

    @property
    def sql(self):
        return self._sql

    @property
    def params(self):
        return self._params


class SQL1(SQL):
    @property
    def filename(self):
        today = datetime.now().strftime('%Y-%m-%d')
        return today + self._name + '.xls'


class SQL2(SQL):
    @property
    def filename(self):
        today = datetime.now().strftime('%Y-%m-%d')
        return today + self._name + '.xls'

    @property
    def sql(self):
        today = datetime.now()
        return self._sql % tuple([(today - timedelta(days=i)).strftime('%Y%m%d') for i in range(0, 7)])


def export(SQL, d='.'):
    conn = mysql.connector.connect(host=mysql_host, port=mysql_port, database='wifi', user=mysql_user,
                                   password=mysql_password)
    cursor = conn.cursor()
    cursor.execute(SQL.sql, SQL.params)

    book = xlwt.Workbook()
    sheet = book.add_sheet('sheet1')

    for i, val in enumerate(cursor.column_names):
        sheet.write(0, i, val)

    rows = cursor.fetchall()
    for i, row in enumerate(rows):
        r = sheet.row(i + 1)
        for j, v in enumerate(row):
            r.write(j, v)
    if SQL.formula:
        sheet.write(len(rows) + 1, len(cursor.column_names), xlwt.Formula(SQL.formula))
    book.save(os.path.join(d, SQL.filename))


def export_all(sqls, dir='.'):
    if not sqls or len(sqls) < 1:
        return
    for item in sqls:
        try:
            export(item, dir)
        except Exception as e:
            print(e)


def do_export(d='.'):
    export_all([
        SQL1('SQL文件1'),
        SQL2('SQL文件2', formula='SUM($C$2:$C$100)'),
    ], d)


def zip_dir(d):
    f = zipfile.ZipFile(d + '.zip', 'w', zipfile.ZIP_DEFLATED)
    for *_, filenames in os.walk(d):
        for filename in filenames:
            f.write(os.path.join(d, filename))
    f.close()


def send_email(sender, sender_pass, receiver, filename):
    msg = MIMEMultipart()
    msg['From'] = sender
    msg['To'] = receiver
    msg['Subject'] = Header(filename, 'utf-8').encode()

    # 郵件正文是MIMEText:
    msg.attach(MIMEText('統計數據 %s,請查看附件' % filename, 'plain', 'utf-8'))

    # 添加附件就是加上一個MIMEBase,從本地讀取一個圖片:
    with open(filename, 'rb') as f:
        # 設置附件的MIME和文件名,這裏是png類型:
        mime = MIMEBase('application', 'octet-stream', filename=filename)
        # 加上必要的頭信息:
        mime.add_header('Content-Disposition', 'attachment', filename=filename)
        mime.add_header('Content-ID', '<0>')
        mime.add_header('X-Attachment-Id', '0')
        # 把附件的內容讀進來:
        mime.set_payload(f.read())
        # 用Base64編碼:
        encoders.encode_base64(mime)
        # 添加到MIMEMultipart:
        msg.attach(mime)
    smtp_server = 'smtp.qiye.163.com'

    server = smtplib.SMTP(smtp_server, 25)  # SMTP協議默認端口是25
    server.login(sender, sender_pass)
    server.sendmail(sender, [receiver], msg.as_string())
    server.quit()


def export_and_send():
    sender = ''  # TODO 請輸入發送者郵箱,例如 [email protected]
    sender_password = ''  # TODO 請輸入發送者郵箱密碼
    receiver = ''  # TODO 請輸入接收者郵箱,例如 [email protected]
    d = datetime.now().strftime('%Y-%m-%d') + ' 統計數據'
    if not os.path.exists(d):
        os.mkdir(d)
    do_export(d)
    zip_dir(d)
    send_email(sender, sender_password, receiver, d + '.zip')


if __name__ == '__main__':
    export_and_send()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章