-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit af64e66
Showing
5 changed files
with
308 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
go.sum | ||
sqlexcel | ||
main | ||
go.sum | ||
config.ini |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#!/usr/bin/env bash | ||
|
||
|
||
CURR_PATH=$(cd `dirname $0`;pwd) | ||
BNARY_NAME=`cat $CURR_PATH/go.mod | grep ^module |awk '{print $2}'` | ||
|
||
function _info(){ | ||
local msg=$1 | ||
local now=`date '+%Y-%m-%d %H:%M:%S'` | ||
echo "\033[1;46;30m[INFO]\033[0m $now $msg" | ||
} | ||
|
||
function _version(){ | ||
local msg=$1 | ||
local now=`date '+%Y-%m-%d %H:%M:%S'` | ||
echo "\033[1;46;30m[INFO]\033[0m $now $msg" | ||
} | ||
|
||
function get_tag () { | ||
local tag=$(git describe --tags 2>>/dev/null) | ||
if [ -n "$tag" ];then | ||
tag=$(echo $tag | cut -d '-' -f 1) | ||
else | ||
tag='unknown' | ||
fi | ||
echo $tag | ||
} | ||
|
||
function get_branch () { | ||
local branch=$(git rev-parse --abbrev-ref HEAD) | ||
if [ -z "$branch" ]; then | ||
branch='unknown' | ||
fi | ||
echo $branch | ||
} | ||
|
||
function get_commit () { | ||
local commit=$(git rev-parse HEAD) | ||
if [ -z "$commit" ]; then | ||
commit='unknown' | ||
fi | ||
echo $commit | ||
} | ||
|
||
|
||
function main() { | ||
local platform=$1 | ||
local bin_name=$2 | ||
local main_file=$3 | ||
local is_docker=$4 | ||
|
||
_info "开始构建 [$BNARY_NAME] ..." | ||
|
||
TAG=$(get_tag) | ||
BRANCH=$(get_branch) | ||
COMMIT=$(get_commit) | ||
DATE=$(date '+%Y-%m-%d %H:%M:%S') | ||
version=$(go version | grep -o 'go[0-9].[0-9].*') | ||
|
||
Path="$BNARY_NAME/version" | ||
_version "构建版本的时间(Build Time): $DATE" | ||
_version "当前构建的版本(Git Tag ): $TAG" | ||
_version "当前构建的分支(Git Branch): $BRANCH" | ||
_version "当前构建的提交(Git Commit): $COMMIT" | ||
|
||
case $platform in | ||
"linux") | ||
_info "开始构建Linux平台版本 ..." | ||
GOOS=linux GOARCH=amd64 \ | ||
CGO_ENABLED=0 go build -a -o $bin_name -ldflags "-X '$Path.GIT_TAG=$TAG' -X '$Path.GIT_BRANCH=$BRANCH' -X '$Path.GIT_COMMIT=$COMMIT' -X '$Path.BUILD_TIME=$DATE' -X '$Path.GO_VERSION=$version'" $main_file | ||
;; | ||
*) | ||
_info "开始本地构建 ..." | ||
CGO_ENABLED=0 go build -a -o $bin_name -ldflags "-X '$Path.GIT_TAG=$TAG' -X '$Path.GIT_BRANCH=$BRANCH' -X '$Path.GIT_COMMIT=$COMMIT' -X '$Path.BUILD_TIME=$DATE' -X '$Path.GO_VERSION=$version'" $main_file | ||
;; | ||
esac | ||
if [ $? -ne 0 ];then | ||
_info "构建失败" | ||
exit 1 | ||
fi | ||
_info "程序构建完成: $bin_name" | ||
} | ||
|
||
main ${1:-local} $BNARY_NAME $CURR_PATH/main.go | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[email] | ||
smtp = "smtp.exmail.qq.com" | ||
user = "[email protected]" | ||
passwd = "xx" | ||
port = 587 | ||
|
||
[data] | ||
datasource = "root:root@tcp(127.0.0.1:3306)/xx?parseTime=true&loc=Local" | ||
sql = "select a.id ,a.phone_number,a.username ,a.register_type,a.register_channel,a.register_time,hour(a.register_time) as hour ,case when b.receiver_id is null then 0 else 1 end as spread from uc.user_account a left join marketing.spread_record b on a.id=b.receiver_id where date(register_time)=curdate() order by register_time;" | ||
sql = "select * from user" | ||
name = "用户数据" | ||
mailto = "[email protected];[email protected]" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module sqlexcel | ||
|
||
go 1.13 | ||
|
||
require ( | ||
github.com/BurntSushi/toml v0.3.1 | ||
github.com/ftlynx/tsx v0.0.0-20200407075516-7380aaf715d7 | ||
github.com/go-sql-driver/mysql v1.5.0 | ||
github.com/tealeg/xlsx v1.0.5 | ||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect | ||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/tls" | ||
"database/sql" | ||
"fmt" | ||
"github.com/BurntSushi/toml" | ||
"github.com/ftlynx/tsx/mysqlx" | ||
_ "github.com/go-sql-driver/mysql" | ||
"github.com/tealeg/xlsx" | ||
"gopkg.in/gomail.v2" | ||
"io/ioutil" | ||
"mime" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type Config struct { | ||
Data *DataConfig `toml:"data"` | ||
EMail *EmailConf `toml:"email"` | ||
} | ||
|
||
type DataConfig struct { | ||
Datasource string `toml:"datasource"` | ||
Sql string `toml:"sql"` | ||
Name string `toml:"name"` | ||
Mailto string `toml:"mailto"` | ||
} | ||
|
||
type EmailConf struct { | ||
Smtp string `toml:"smtp"` | ||
Port int `toml:"port"` | ||
User string `toml:"user"` | ||
Passwd string `toml:"passwd"` | ||
} | ||
|
||
func parseConfig(configpath string) (*Config, error) { | ||
cfg := new(Config) | ||
|
||
configPath, err := filepath.Abs(configpath) | ||
if err != nil { | ||
return cfg, fmt.Errorf("get config file absolute path failed, %s", err.Error()) | ||
} | ||
|
||
file, err := os.Open(configPath) | ||
defer file.Close() | ||
if err != nil { | ||
return cfg, fmt.Errorf("open config file error, %s", err.Error()) | ||
} | ||
|
||
fd, err := ioutil.ReadAll(file) | ||
if err != nil { | ||
return cfg, fmt.Errorf("read config file error, %s", err.Error()) | ||
} | ||
|
||
cfg.Data = new(DataConfig) | ||
cfg.EMail = new(EmailConf) | ||
|
||
if err := toml.Unmarshal(fd, cfg); err != nil { | ||
return cfg, fmt.Errorf("load config file error, %s", err.Error()) | ||
} | ||
|
||
return cfg, nil | ||
} | ||
|
||
type myDB struct { | ||
DB *sql.DB | ||
} | ||
|
||
func (d *myDB) QueryData(sql string) ([]string, []map[string]interface{}, error) { | ||
result := make([]map[string]interface{}, 0) | ||
rows, err := d.DB.Query(sql) | ||
if err != nil { | ||
return make([]string, 0), result, err | ||
} | ||
columns, err := rows.Columns() | ||
if err != nil { | ||
return columns, result, err | ||
} | ||
|
||
cache := make([]interface{}, len(columns)) | ||
for index, _ := range cache { | ||
var a interface{} | ||
cache[index] = &a | ||
} | ||
|
||
for rows.Next() { | ||
if err := rows.Scan(cache...); err != nil { | ||
return columns, result, err | ||
} | ||
item := make(map[string]interface{}) | ||
for i, data := range cache { | ||
item[columns[i]] = *data.(*interface{}) | ||
} | ||
result = append(result, item) | ||
} | ||
return columns, result, err | ||
} | ||
|
||
func CreateExcel(columns []string, data []map[string]interface{}, filename string) error { | ||
file := xlsx.NewFile() | ||
sheet, err := file.AddSheet("sheet1") | ||
if err != nil { | ||
return err | ||
} | ||
row := sheet.AddRow() | ||
row.SetHeightCM(1) | ||
for _, v := range columns { | ||
cell := row.AddCell() | ||
cell.Value = v | ||
} | ||
for _, v1 := range data { | ||
row := sheet.AddRow() | ||
row.SetHeightCM(1) | ||
for _, column := range columns { | ||
cell := row.AddCell() | ||
cell.Value = fmt.Sprintf("%s", v1[column]) | ||
} | ||
} | ||
return file.Save(filename) | ||
} | ||
|
||
type connMail struct { | ||
User string `json:"user"` | ||
Passwd string `json:"passwd"` | ||
Smtp string `json:"smtp"` | ||
Port int `json:"port"` | ||
} | ||
|
||
func (m *connMail) Send(to string, cc string, subject string, attaFile string) error { | ||
d := gomail.NewDialer(m.Smtp, m.Port, m.User, m.Passwd) | ||
d.TLSConfig = &tls.Config{InsecureSkipVerify: true} | ||
|
||
//设置消息 | ||
msg := gomail.NewMessage() | ||
msg.SetHeader("From", msg.FormatAddress(m.User, "系统邮件")) | ||
msg.SetHeader("To", strings.Split(to, ";")...) | ||
msg.SetHeader("CC", cc) | ||
msg.SetHeader("Subject", subject) | ||
msg.SetBody("text/plain", "hi, all:\r\n\r\n 相关数据见附件") | ||
|
||
if attaFile != "" { | ||
names := strings.Split(attaFile, "/") | ||
name := names[len(names)-1] | ||
msg.Attach(attaFile, | ||
gomail.Rename(name), | ||
gomail.SetHeader(map[string][]string{ | ||
"Content-Disposition": []string{ | ||
fmt.Sprintf(`attachment; filename="%s"`, mime.QEncoding.Encode("UTF-8", name)), | ||
}, | ||
}, | ||
)) | ||
} | ||
|
||
return d.DialAndSend(msg) | ||
} | ||
|
||
func main() { | ||
if len(os.Args) < 2 { | ||
panic(fmt.Sprintf("usage %s config.ini", os.Args[0])) | ||
} | ||
cfg, err := parseConfig(os.Args[1]) | ||
if err != nil { | ||
panic(err) | ||
} | ||
maxConnNum := 10 | ||
maxIdleConn := 5 | ||
maxLifeTime := time.Duration(int64(86400)) | ||
db, err := mysqlx.SqlDB(cfg.Data.Datasource, maxConnNum, maxIdleConn, maxLifeTime) | ||
if err != nil { | ||
panic(err) | ||
} | ||
email := connMail{ | ||
User: cfg.EMail.User, | ||
Passwd: cfg.EMail.Passwd, | ||
Smtp: cfg.EMail.Smtp, | ||
Port: cfg.EMail.Port, | ||
} | ||
sqldata := myDB{DB: db} | ||
columns, result, err := sqldata.QueryData(cfg.Data.Sql) | ||
if err != nil { | ||
panic(err) | ||
} | ||
filename := fmt.Sprintf("/tmp/%s.xlsx", cfg.Data.Name) | ||
if err := CreateExcel(columns, result, filename); err != nil { | ||
panic(err) | ||
} | ||
if err := email.Send(cfg.Data.Mailto, "", cfg.Data.Name, filename); err != nil { | ||
panic(err) | ||
} | ||
return | ||
} |