zoukankan      html  css  js  c++  java
  • golang发送html邮件带附件

    wrong_sql_send.go

    package main
    
    import (
        _ "github.com/go-sql-driver/mysql"
        "database/sql"
        "fmt"
        "strconv"
        "gopkg.in/gomail.v2"
        "crypto/tls"
        "time"
        "github.com/tealeg/xlsx"
        "github.com/Unknwon/goconfig"
        "strings"
        "os"
    )
    
    var now_time = time.Now()
    var yes_date = now_time.AddDate(0, 0, -1).Format("2006-01-02")
    //var attach_file_name = "wrong_sql_1_22_"+now_time.Format("20060102")+".xlsx"
    var mysql_info = get_config_data("mysql_info")
    var mail_group = get_config_data("mail_group")
    var send_subject = get_config_data("subject")
    var host_port = get_config_data("host_port")
    var limit_record_cnt = 50
    /*
    const
    (
        dbhostsip = "192.168.1.22"
        dbusername = "dmladmin"
        dbpassowrd = "dmladmin"
        dbname = "db_admin"
    )
    */
    
    func get_config_data(sec_name string)(map[string] string){
        cfg, err := goconfig.LoadConfigFile("./config/config.ini")
        if err != nil{
            panic("错误")
            return nil
        }
        sec, err := cfg.GetSection(sec_name)
        return sec
    }
    
    
    func SendMail(mailTo []string,subject string, body string,total_count int,attach_file_name string ) error {
        //定义邮箱服务器连接信息,如果是阿里邮箱 pass填密码,qq邮箱填授权码
        var smtp_info = get_config_data("smtp")
        port, _ := strconv.Atoi(smtp_info["port"]) //转换端口类型为int
        m := gomail.NewMessage()
        m.SetHeader("From","yw" + "<" + smtp_info["user"] + ">")  //这种方式可以添加别名,即“XD Game”, 也可以直接用<code>m.SetHeader("From",mailConn["user"])</code> 读者可以自行实验下效果
        m.SetHeader("To", mailTo...)  //发送给多个用户
        m.SetHeader("Subject", subject)  //设置邮件主题
        m.SetBody("text/html", body)     //设置邮件正文
        if total_count > limit_record_cnt {
            m.Attach("./attach_file/" + attach_file_name)
        }
    
        d := gomail.NewDialer(smtp_info["host"], port, smtp_info["user"], smtp_info["pass"])
        d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
        err := d.DialAndSend(m)
        fmt.Println(err)
        return err
    }
    
    func get_excel_data(db_ip string,mysql_host_port string,attach_file_name string){
        var file *xlsx.File
        var sheet *xlsx.Sheet
        var row *xlsx.Row
        var cell *xlsx.Cell
        var now_time = time.Now()
        var yes_date = now_time.AddDate(0, 0, -1).Format("2006-01-02")
    
        style := xlsx.NewStyle()
        fill := *xlsx.NewFill("solid", "F79646", "FF000000")
        font := *xlsx.NewFont(12, "Verdana")
    
        border := *xlsx.NewBorder("thin", "thin", "thin", "thin")
    
        var  runsql_all  = "select id, replace(replace(run_sql,'
    ',''),'	','') as run_sql,create_time from tb_wrong_run_sql where create_time>="+"'"+yes_date+"'" +" order by id"
        db, err := sql.Open("mysql", mysql_info["dbusername"]+":"+mysql_info["dbpassowrd"]+"@tcp("+db_ip+":"+mysql_host_port+")/"+mysql_info["dbname"])
        if err != nil {
            fmt.Println("连接数据库失败:", err)
        }
        //使用DB的query方法遍历数据库数据
        data_rows, err := db.Query(runsql_all)
        //获取完毕释放rows,阻止更多的列举
        defer data_rows.Close()
        if err != nil {
            fmt.Println("获取错误:", err)
        }
    
        file = xlsx.NewFile()
        sheet, err = file.AddSheet("不符合规范查询")
    
        style.Fill = fill
        style.Font = font
        style.Border = border
    
        style.ApplyFill = true
        style.ApplyFont = true
        style.ApplyBorder = true
    
    
        row = sheet.AddRow()
        cell = row.AddCell()
        cell.Value = "ID"
        cell.SetStyle(style)
        cell = row.AddCell()
        cell.Value = "SQL"
        cell.SetStyle(style)
        cell = row.AddCell()
        cell.Value = "采集时间"
        cell.SetStyle(style)
    
        for data_rows.Next() {
            var id int
            var run_sql string
            var create_time string
            data_rows.Scan(&id, &run_sql, &create_time)
            row = sheet.AddRow()
            cell = row.AddCell()
            cell.Value = strconv.Itoa(id)
            cell = row.AddCell()
            cell.Value = run_sql
            cell = row.AddCell()
            cell.Value = create_time
        }
        err = file.Save("./attach_file/"+attach_file_name)
        if err != nil {
            fmt.Printf(err.Error())
        }
    }
    
    func get_html_data(db_ip string,mysql_host_port string)(string,int) {
        //使用database/sql包中的Open连接数据库
        var  runsql_limit  = "select id, replace(replace(run_sql,'
    ',''),'	','') as run_sql,create_time from tb_wrong_run_sql where create_time>="+"'"+yes_date+"'" +" order by id limit "+strconv.Itoa(limit_record_cnt)
        db, err := sql.Open("mysql", mysql_info["dbusername"]+":"+mysql_info["dbpassowrd"]+"@tcp("+db_ip+":"+mysql_host_port+")/"+mysql_info["dbname"])
        if err != nil {
            fmt.Println("连接数据库失败:", err)
            return "error",-1
        }
        //使用DB的query方法遍历数据库数据
        rows, err := db.Query(runsql_limit)
        //获取完毕释放rows,阻止更多的列举
        defer rows.Close()
        if err != nil {
            fmt.Println("获取错误:", err)
            return "error",-1
        }
        //var title = `xx实例慢查询`
        var header = `<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>`
        var i =0
        //如果有数据记录Next指针就不为true
        var tr = ""
        for rows.Next() {
            var id int
            var run_sql string
            var create_time string
            rows.Scan(&id, &run_sql, &create_time)
            //fmt.Println(id, user, create_time, update_time)
            i++
            var td = ""
            td = td + "<td>" + strconv.Itoa(id) + "</td>"
            td = td + "<td style=word-wrap:break-word;word-break:break-all;>" + run_sql + "</td>"
            td = td + "<td>" + create_time + "</td>"
            tr = tr + "<tr>" + td + "</tr>"
        }
        var body = tr
        //Err返回可能的、在迭代时出现的错误。Err需在显式或隐式调用Close方法后调用。
        //err = rows.Err()
        var th = `<body text='#000000'><center><font size=5 color='#dd0000'><b> `+ `不符合规范查询数:` + strconv.Itoa(i) + `</b></font></center>
            <br/><table style=' font-size: 14px;' border='1' cellspacing='0' cellpadding='1' bordercolor='#000000' width='20%' align='center' ></table>
            <br/><table bgcolor='#B0E0E6' style=' font-size: 14px;'border='1' cellspacing='0' cellpadding='0' bordercolor='#000000' width='95%' align='center' >
            <tr  bgcolor='#F79646' align='left' >
            <th>id</th>
            <th style=60px>SQL</th>
            <th style='50px'>采集时间</th>
            </tr>`
    
        var tail=""
        if (i >= limit_record_cnt) {
            tail= `</table><b><p>更多请查看附件!</p></b></body></html>`
        } else {
            tail= `</table></body></html>`
        }
        var mail = header + th + body + tail
        return mail,i
    }
    
    func get_total_count(db_ip string,mysql_host_port string)(string,int) {
        //使用database/sql包中的Open连接数据库
        var  runsql_total  = "select count(1) from tb_wrong_run_sql where create_time>="+"'"+yes_date+"'"
        fmt.Println(runsql_total)
        db, err := sql.Open("mysql", mysql_info["dbusername"]+":"+mysql_info["dbpassowrd"]+"@tcp("+db_ip+":"+mysql_host_port+")/"+mysql_info["dbname"])
        if err != nil {
            fmt.Println("连接数据库失败:", err)
            return "error",-1
        }
        //使用DB的query方法遍历数据库数据
        rows, err := db.Query(runsql_total)
        //获取完毕释放rows,阻止更多的列举
        defer rows.Close()
        if err != nil {
            fmt.Println("获取错误:", err)
            return "error",-1
        }
    
        var total_cnt int
        for rows.Next() {
            rows.Scan(&total_cnt)
        }
        return "success",total_cnt
    }
    
    
    func pathexists(path string) (int, error) {
        _, err := os.Stat(path)
        if err == nil {
            return 1, nil
        }
        if os.IsNotExist(err) {
            return 0, nil
        }
        return 0, err
    }
    
    func main(){
    
        var record_cnt = 0
        var mailTo = []string{}
        db_ip := os.Args[1]  /*外部输入参数IP地址,如192.168.1.22*/
        var attach_file_name = "wrong_sql_"+db_ip+"_"+now_time.Format("20060102")+".xlsx"
        var subject = "【数据库监控测试环境】不符合规范查询:" + db_ip + "(" + send_subject[db_ip]+ ")-"+now_time.Format("20060102")
        var mysql_host_port = host_port[db_ip]
    
        //附件目录
        _dir := "./attach_file"
        exist_flag, err := pathexists(_dir)
        if err != nil {
            fmt.Printf("get dir error![%v]
    ", err)
            return
        }
    
        if exist_flag == 0 {
            err := os.Mkdir(_dir, os.ModePerm)
            if err != nil {
                fmt.Printf("mkdir failed![%v]
    ", err)
            } else {
                fmt.Printf("mkdir success!
    ")
            }
        }
    
    
        mailTo=strings.Split(mail_group[db_ip], ",")
        _,total_count:=get_total_count(db_ip,mysql_host_port)
        body,record_cnt := get_html_data(db_ip,mysql_host_port)
        //fmt.Print(body)
        if record_cnt> 0 {
            //生成excel数据
            if total_count > limit_record_cnt {
                get_excel_data(db_ip,mysql_host_port,attach_file_name)
            }
            SendMail(mailTo, subject, body,total_count,attach_file_name)
        }
    }

    配置文件内容:

    config.ini

    [smtp]
    user=yw@test.com
    pass=test
    host=mail.test.com
    port=25
    
    [mysql_info]
    dbusername=dmladmin
    dbpassowrd=dmladmin
    dbname=db_admin
    
    [host_port]
    192.168.1.22=3306
    192.168.1.113=3306
    192.168.1.130=3306
    192.168.1.131=3306
    192.168.1.8=4769
    192.168.1.92=3306
    192.168.1.63=3306
    192.168.1.99=3306
    192.168.1.90=3306
    192.168.1.127=3306
    
    [mail_group]
    192.168.1.22=hxl@163.com,hxl@163.com
    192.168.1.113=hxl@163.com,hxl@163.com
    192.168.1.130=hxl@163.com,hxl@163.com
    192.168.1.131=hxl@163.com,hxl@163.com
    192.168.1.8=hxl@163.com,hxl@163.com
    192.168.1.92=hxl@163.com,hxl@163.com
    192.168.1.63=hxl@163.com,hxl@163.com
    192.168.1.99=hxl@163.com,hxl@163.com
    192.168.1.90=hxl@163.com,hxl@163.com
    192.168.1.127=hxl@163.com,hxl@163.com
    
    [subject]
    192.168.1.22=test1
    192.168.1.113=test2
    192.168.1.130=test3
    192.168.1.131=test4
    192.168.1.8=test5
    192.168.1.92=test6
    192.168.1.63=test7
    192.168.1.99=test8
    192.168.1.90=test9
    192.168.1.127=test10
  • 相关阅读:
    OCP-1Z0-053-V12.02-15题
    Boost.Asio性能测试
    使用asio搭建服务器
    boost::asio::ip::tcp::socket is connected?(如何知道socket的链接是链接或断开?)
    boost::async_read_some连续接收数据
    基于boost asio实现的支持ssl的通用socket框架
    Boost.Asio的使用技巧
    Matlab基本函数-expm函数
    Matlab基本函数-exp函数
    OCP-1Z0-053-V12.02-337题
  • 原文地址:https://www.cnblogs.com/hxlasky/p/11347292.html
Copyright © 2011-2022 走看看