開發要求:
由於管理后台導出數據非常緩慢,找程序員解決無果后,自己動手寫了一個腳本,每天定時將報表發送給業務部門。
1. 通過條件查詢MySQL獲取數據
2. 將獲取的數據寫入到Excel中,對應字段名
3. 將Excel作為附件內容,將郵件發送至相關人員
程序:
1. README

# 作者:hkey # 博客地址:hukey.cnblogs.com # http://www.cnblogs.com/hukey/p/8983831.html # 目錄結構: PS: 功能比較單一,為了方便管理寫入了一個文件中,有如下兩個類: CreateExcel: 查詢數據庫並生成Excel SendMail: 將Excel作為附件內容,將郵件發送至相關人員 # 使用說明: 數據庫信息和郵件信息內容都需要手動填寫,確保無誤; 可實現發送至多人;
2. 數據庫腳本:

-- MySQL dump 10.14 Distrib 5.5.56-MariaDB, for Linux (x86_64) -- -- Host: localhost Database: user_info -- ------------------------------------------------------ -- Server version 5.5.56-MariaDB /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `user` -- DROP TABLE IF EXISTS `user`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `user` ( `id` int(16) DEFAULT NULL, `name` varchar(255) DEFAULT NULL, `city` varchar(255) DEFAULT NULL, `class` varchar(255) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- -- Dumping data for table `user` -- LOCK TABLES `user` WRITE; /*!40000 ALTER TABLE `user` DISABLE KEYS */; INSERT INTO `user` VALUES (1,'小飛','北京','三年二班'),(2,'小四','上海','三年一班'),(3,'小K','西安','三年三班'); /*!40000 ALTER TABLE `user` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2018-05-03 9:45:06
3. 程序代碼

# -*- coding: utf-8 -*- # Author: hkey from email.header import Header from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart # from email.utils import parseaddr, formataddr from email import encoders from email.mime.base import MIMEBase import smtplib, os import pymysql, xlwt class CreateExcel(object): '''查詢數據庫並生成Excel文檔''' def __init__(self, mysql_info): self.mysql_info = mysql_info self.conn = pymysql.connect(host = self.mysql_info['host'], port = self.mysql_info['port'], user = self.mysql_info['user'], passwd = self.mysql_info['passwd'], db = self.mysql_info['db'], charset='utf8') self.cursor = self.conn.cursor() def getUserData(self, sql): # 查詢數據庫 self.cursor.execute(sql) table_desc = self.cursor.description result = self.cursor.fetchall() if not result: print('沒數據。') # 返回查詢數據、表字段 print('數據庫查詢完畢'.center(30, '#')) return result, table_desc def writeToExcel(self, data, filename): # 生成Excel文檔 # 注意:生成Excel是一列一列寫入的。 result, fileds = data wbk = xlwt.Workbook(encoding='utf-8') # 創建一個表格 sheet1 = wbk.add_sheet('sheet1', cell_overwrite_ok=True) for filed in range(len(fileds)): # Excel插入第一行字段信息 sheet1.write(0, filed, fileds[filed][0]) # (行,列,數據) for row in range(1, len(result)+1): # 將數據從第二行開始寫入 for col in range(0, len(fileds)): sheet1.write(row, col, result[row-1][col]) #(行, 列, 數據第一行的第一列) wbk.save(filename) def close(self): # 關閉游標和數據庫連接 self.cursor.close() self.conn.close() print('關閉數據庫連接'.center(30, '#')) class SendMail(object): '''將Excel作為附件發送郵件''' def __init__(self, email_info): self.email_info = email_info # 使用SMTP_SSL連接端口為465 self.smtp = smtplib.SMTP_SSL(self.email_info['server'], self.email_info['port']) # 創建兩個變量 self._attachements = [] self._from = '' def login(self): # 通過郵箱名和smtp授權碼登錄到郵箱 self._from = self.email_info['user'] self.smtp.login(self.email_info['user'], self.email_info['password']) # def _format_addr(self, s): # name, addr = parseaddr(s) # return formataddr((Header(name, 'utf-8').encode(), addr)) def add_attachment(self): # 添加附件內容 # 注意:添加附件內容是通過讀取文件的方式加入 file_path = self.email_info['file_path'] with open(file_path, 'rb') as file: filename = os.path.split(file_path)[1] mime = MIMEBase('application', 'octet-stream', filename=filename) mime.add_header('Content-Disposition', 'attachment', filename=('gbk', '', filename)) mime.add_header('Content-ID', '<0>') mime.add_header('X-Attachment-Id', '0') mime.set_payload(file.read()) encoders.encode_base64(mime) # 添加到列表,可以有多個附件內容 self._attachements.append(mime) def sendMail(self): # 發送郵件,可以實現群發 msg = MIMEMultipart() contents = MIMEText(self.email_info['content'], 'plain', 'utf-8') msg['From'] = self.email_info['user'] msg['To'] = self.email_info['to'] msg['Subject'] = self.email_info['subject'] for att in self._attachements: # 從列表中提交附件,附件可以有多個 msg.attach(att) msg.attach(contents) try: self.smtp.sendmail(self._from, self.email_info['to'].split(','), msg.as_string()) print('郵件發送成功,請注意查收'.center(30, '#')) except Exception as e: print('Error:', e) def close(self): # 退出smtp服務 self.smtp.quit() print('logout'.center(30, '#')) if __name__ == '__main__': # 數據庫連接信息 mysql_dict = { 'host': '192.168.118.13', 'port': 3306, 'user': 'root', 'passwd': '123456', 'db': 'user_info' } # 郵件登錄及內容信息 email_dict = { # 手動填寫,確保信息無誤 "user": "xxx@126.com", "to": "xxx@qq.com, xxx@qq.com", # 多個郵箱以','隔開; "server": "smtp.126.com", 'port': 465, # values值必須int類型 "username": "xxx@126.com", "password": "xxxx", "subject": "user測試表", "content": '用戶測試數據', 'file_path': 'example.xls' } sql = 'select * from user' # filename = 'example.xls' create_excel = CreateExcel(mysql_dict) sql_res = create_excel.getUserData(sql) create_excel.writeToExcel(sql_res,email_dict['file_path']) create_excel.close() sendmail = SendMail(email_dict) sendmail.login() sendmail.add_attachment() sendmail.sendMail() sendmail.close()
運行結果: