forked from go/golangs_learn
VIVIMAN
3 years ago
4 changed files with 348 additions and 0 deletions
@ -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" |
|||
} |
|||
} |
After Width: | Height: | Size: 97 KiB |
@ -0,0 +1,14 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> |
|||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> |
|||
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/> |
|||
<dependency> |
|||
<dependentAssembly> |
|||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/> |
|||
</dependentAssembly> |
|||
</dependency> |
|||
<asmv3:application> |
|||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> |
|||
<dpiAware>true</dpiAware> |
|||
</asmv3:windowsSettings> |
|||
</asmv3:application> |
|||
</assembly> |
Binary file not shown.
Loading…
Reference in new issue