diff --git a/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.go b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.go new file mode 100644 index 0000000..a22ab7b --- /dev/null +++ b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.go @@ -0,0 +1,334 @@ +package main + +/* +思路: + 首先:配置文件,若不存在生成配置文件,生成配置文件 + 其次:通过配置获取数据库链接 ,并链接和查询语句 + 最后:将查询语句生成excel + +*/ +import ( + "github.com/lxn/walk" + . "github.com/lxn/walk/declarative" + + "database/sql" + "fmt" + "github.com/360EntSecGroup-Skylar/excelize" + _ "github.com/go-sql-driver/mysql" + "strconv" + "strings" + "time" +) + +var version = "V1.1" + +//数据源字符串:用户名:密码@协议(地址:端口)/数据库?参数=参数值 //mysql +var linkStr = "root:admin@tcp(127.0.0.1:35017)/hy_qggwy?charset=utf8" + +// 注意配置方式,处理上使用这种配置方式 +var _key_, _len_ = "key", "len" +var Increase = map[string]string{ + _key_ + "": "人员新增(2021年在库2020年不在库)", + _key_ + "0": "姓名", + _key_ + "1": "身份证号", + _key_ + "2": "现工作单位及职务", + _len_ + "0": "15", + _len_ + "1": "20", + _len_ + "2": "60", +} +var Decrease = map[string]string{ + _key_ + "": "人员减少(2021年不在库2020年在库)", + _key_ + "0": "姓名", + _key_ + "1": "身份证号", + _key_ + "2": "原现工作单位及职务", + _len_ + "0": "15", + _len_ + "1": "20", + _len_ + "2": "60", +} + +type Row4 struct { + A0101 string + A0184 string + A0192A string +} + +// 定义 应用的结构体 +type MyMainWindow struct { + //匿名 + *walk.MainWindow + lb *walk.ListBox + te *walk.TextEdit + wv *walk.WebView + all *walk.RadioButton + jianshu *walk.RadioButton + juejin *walk.RadioButton + bokeyuan *walk.RadioButton + csdn *walk.RadioButton + os *walk.RadioButton + keywords *walk.LineEdit + query *walk.PushButton + nextquery *walk.PushButton + prvquery *walk.PushButton + favorites *walk.PushButton + unfavorites *walk.PushButton +} + +func main() { + mw := &MyMainWindow{} + + var outTE *walk.TextEdit + var outPB *walk.ProgressBar + isEnd := true + + if err := (MainWindow{ + Title: "数据库比对" + version, + // 这里插入图标会导致程序运行无法获取文件,推荐开发使用,打包注释 + // Icon: "src/data_office/get_db_excel/only_balance_gui/main.ico", + // 这样实现将页面加载到主界面上 + AssignTo: &mw.MainWindow, + Size: Size{600, 400}, + Layout: VBox{}, + MenuItems: []MenuItem{ + Menu{ + Text: "&编辑", + Items: []MenuItem{ + Separator{}, + Action{ + Text: "退出", + OnTriggered: func() { mw.Close() }, + }, + }, + }, + Menu{ + Text: "&帮助", + Items: []MenuItem{ + Action{ + Text: "关于", + OnTriggered: mw.aboutAction_Triggered, + }, + }, + }, + }, + Children: []Widget{ + ProgressBar{ + AssignTo: &outPB, + MaxValue: 100, + MinValue: 0, + Value: 0, + }, + TextEdit{ + AssignTo: &outTE, + ReadOnly: true, + }, + PushButton{ + Text: "开始", + OnClicked: func() { + wirteExcel(outTE, outPB) + isEnd = false + }, + }, + PushButton{ + Enabled: isEnd, + Text: "关闭", + OnClicked: func() { + mw.Close() + }, + }, + }, + }.Create()); err != nil { + fmt.Print(err) + } + + mw.Run() + +} + +func wirteExcel(outTE *walk.TextEdit, outPB *walk.ProgressBar) { + runVal(outTE, outPB, 10, "本程序加载中...") + fromDB, _ := sql.Open("mysql", linkStr) + runVal(outTE, outPB, 20, "数据库驱动加载完成...") + fromMap := QuerySQL(fromDB, "select ifnull(s0201,'') a0101,ifnull(s0202,'') a0184,ifnull(s0203,'') a0192a from m_s02 a where RPT=2021 and not exists(select 1 from m_s02 b where b.RPT=2020 and a.S0202=b.S0202) "+ + "union all select ifnull(s0401,'') a0101,ifnull(s0402,'') a0184,ifnull(s0403,'') a0192a from m_s04 a where RPT=2021 and not exists(select 1 from m_s04 b where b.RPT=2020 and a.S0402=b.S0402) "+ + "union all select ifnull(s0501,'') a0101,ifnull(s0502,'') a0184,ifnull(s0503,'') a0192a from m_s05 a where RPT=2021 and not exists(select 1 from m_s05 b where b.RPT=2020 and a.S0502=b.S0502)") + runVal(outTE, outPB, 40, "增加的数据查询...") + toMap := QuerySQL(fromDB, "select ifnull(s0201,'') a0101,ifnull(s0202,'') a0184,ifnull(s0203,'') a0192a from m_s02 a where RPT=2020 and not exists(select 1 from m_s02 b where b.RPT=2021 and a.S0202=b.S0202) "+ + "union all select ifnull(s0401,'') a0101,ifnull(s0402,'') a0184,ifnull(s0403,'') a0192a from m_s04 a where RPT=2020 and not exists(select 1 from m_s04 b where b.RPT=2021 and a.S0402=b.S0402) "+ + "union all select ifnull(s0501,'') a0101,ifnull(s0502,'') a0184,ifnull(s0503,'') a0192a from m_s05 a where RPT=2020 and not exists(select 1 from m_s05 b where b.RPT=2021 and a.S0502=b.S0502)") + + runVal(outTE, outPB, 60, "减少的数据查询...") + + xlsx := excelize.NewFile() + + // 对比 + runVal(outTE, outPB, 70, "中间库数据比对开始...") + rowIncrease := doBalance(fromMap) + runVal(outTE, outPB, 80, "增加的数据比对完成...") + rowDecrease := doBalance(toMap) + runVal(outTE, outPB, 90, "减少的数据比对完成...") + + // 写数据 + wirteExcelIncrease(xlsx, rowIncrease, Increase) + runVal(outTE, outPB, 95, "增加的数据写入完成...") + wirteExcelDecrease(xlsx, rowDecrease, Decrease) + runVal(outTE, outPB, 99, "减少的数据写入完成...") + + // 生成文件 + var path = "./对比记录-" + time.Now().Format("2006102150405") + ".xlsx" + xlsx.DeleteSheet("Sheet1") + runVal(outTE, outPB, 100, "文件生成完毕...") + // xlsx.SetActiveSheet(1) + _ = xlsx.SaveAs(path) + outTE.AppendText("文件名称为:【当前目录下】" + strings.Replace(path, "./", "", -1) + "\r\n") + outTE.AppendText("请关闭当前窗口,重新打开\r\n") + + fromDB.Close() +} + +func (mw *MyMainWindow) aboutAction_Triggered() { + walk.MsgBox(mw, "数据库对比工具"+version, + " 该工具为公务员系统2020版与公务员系统2021版部分信息比对,\n产生结果会生成Excel供使用。\n"+ + "作者:Viviman张 完成时间:2021-12-21 日", walk.MsgBoxIconQuestion) +} + +func runVal(outTE *walk.TextEdit, outPB *walk.ProgressBar, a int, b string) { + outPB.SetValue(a) + outTE.AppendText(b + "\r\n") +} + +// 处理对比值 +func doBalance(toMap map[string]map[string]string) map[string]Row4 { + var rows = make(map[string]Row4) + for one := range toMap { + t := toMap[one] + r := Row4{ + A0101: t["A0101"], + A0184: t["A0184"], + A0192A: t["A0192A"], + } + rows[one] = r + } + return rows +} + +// 获取表数据 +func QueryMap(db *sql.DB, sqlStr string, m map[string]string) { + rows, _ := db.Query(sqlStr) + defer rows.Close() + columns, _ := rows.Columns() + for rows.Next() { + _ = rows.Scan(&columns[0], &columns[1]) + m[columns[0]] = columns[1] + } +} + +// 获取表数据 +func QuerySQL(db *sql.DB, sqlStr string) map[string]map[string]string { + mapObj := make(map[string]map[string]string) + rows, _ := db.Query(sqlStr) + defer rows.Close() + columns, _ := rows.Columns() + for rows.Next() { + m := make(map[string]string) + _ = rows.Scan(&columns[0], &columns[1], &columns[2]) + m["A0101"] = columns[0] + m["A0184"] = columns[1] + m["A0192A"] = columns[2] + mapObj[columns[1]] = m + } + + return mapObj +} + +func wirteExcelIncrease(xlsx *excelize.File, rows map[string]Row4, title map[string]string) { + var sheetName = title[_key_] + xlsx.NewSheet(sheetName) + rowAfter := wirtTitle(xlsx, title, sheetName) + colBefore, colAfter := "", "" + for one := range rows { + row := rows[one] + colBefore = strings.Replace(ASCIINext(colBefore), " ", "", -1) + colAfter = colBefore + strconv.Itoa(rowAfter) + xlsx.SetCellValue(sheetName, colAfter, row.A0101) + colBefore = strings.Replace(ASCIINext(colBefore), " ", "", -1) + colAfter = colBefore + strconv.Itoa(rowAfter) + xlsx.SetCellValue(sheetName, colAfter, row.A0184) + colBefore = strings.Replace(ASCIINext(colBefore), " ", "", -1) + colAfter = colBefore + strconv.Itoa(rowAfter) + xlsx.SetCellValue(sheetName, colAfter, row.A0192A) + rowAfter, colBefore = rowAfter+1, "" + } +} +func wirteExcelDecrease(xlsx *excelize.File, rows map[string]Row4, title map[string]string) { + var sheetName = title[_key_] + xlsx.NewSheet(sheetName) + rowAfter := wirtTitle(xlsx, title, sheetName) + colBefore, colAfter := "", "" + for one := range rows { + row := rows[one] + colBefore = strings.Replace(ASCIINext(colBefore), " ", "", -1) + colAfter = colBefore + strconv.Itoa(rowAfter) + xlsx.SetCellValue(sheetName, colAfter, row.A0101) + colBefore = strings.Replace(ASCIINext(colBefore), " ", "", -1) + colAfter = colBefore + strconv.Itoa(rowAfter) + xlsx.SetCellValue(sheetName, colAfter, row.A0184) + colBefore = strings.Replace(ASCIINext(colBefore), " ", "", -1) + colAfter = colBefore + strconv.Itoa(rowAfter) + xlsx.SetCellValue(sheetName, colAfter, row.A0192A) + rowAfter, colBefore = rowAfter+1, "" + } +} + +// 写入 头 和 列宽 信息 +func wirtTitle(xlsx *excelize.File, title map[string]string, sheetName string) int { + var f float64 + col, i_ := "", "" + for i, j := 0, (len(title)-1)/2; i < j; i++ { + col = strings.Replace(ASCIINext(col), " ", "", -1) + i_ = strconv.Itoa(i) + f, _ = strconv.ParseFloat(title[_len_+i_], 64) + xlsx.SetColWidth(sheetName, col, col, f) + xlsx.SetCellValue(sheetName, col+strconv.Itoa(1), title[_key_+i_]) + } + return 2 +} + +// 获取行向单元格的下格子 +func ASCIINext(strFrist string) string { + if strFrist == "" { + return "A" + } + switch len(strFrist) { + case 1: + if strFrist == "Z" { + return "AA" + } else { + return string(strFrist[0] + 1) + } + case 2: + if strFrist == "ZZ" { + return "AAA" + } else { + if strFrist[1:] == "Z" { + return string(strFrist[0]+1) + "A" + } else { + return strFrist[:1] + string(strFrist[1]+1) + } + } + case 3: + if strFrist == "ZZZ" { + return "AAAA" + } else { + if strFrist[2:] == "Z" { + if strFrist[1:2] == "Z" { + return string(strFrist[0]+1) + "AA" + } else { + return strFrist[:1] + string(strFrist[1]+1) + "A" + } + } else { + return strFrist[:2] + string(strFrist[2]+1) + } + } + default: + return "A" + } +} diff --git a/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.ico b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.ico new file mode 100644 index 0000000..5eb5c96 Binary files /dev/null and b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.ico differ diff --git a/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.manifest b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.manifest new file mode 100644 index 0000000..114293d --- /dev/null +++ b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.manifest @@ -0,0 +1,14 @@ + + + + + + + + + + + true + + + \ No newline at end of file diff --git a/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.syso b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.syso new file mode 100644 index 0000000..fa3b3b3 Binary files /dev/null and b/golang_learn/data_office/get_db_excel/only_balance_ms020405/main.syso differ