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
原文地址:https://www.cnblogs.com/hxlasky/p/11347292.html