forked from go/golangs_learn
VIVIMAN
3 years ago
10 changed files with 918 additions and 8 deletions
@ -0,0 +1,394 @@ |
|||
package main |
|||
|
|||
/*import ( |
|||
"fmt" |
|||
"github.com/360EntSecGroup-Skylar/excelize" |
|||
"strings" |
|||
"time" |
|||
) |
|||
|
|||
func main() { |
|||
|
|||
} |
|||
func ImportAccountByExcel(c echo.Context) error { |
|||
//文件地址
|
|||
path := c.FormValue("path") |
|||
if path == "" { |
|||
return utils.ErrorNull(c, "请上传excel文件") |
|||
} |
|||
path = strings.TrimLeft(path, "/") |
|||
if flag, _ := utils.PathExists(path); !flag { |
|||
return utils.ErrorNull(c, "未找到excel文件") |
|||
} |
|||
//path := "files/excel/account_template_test.xlsx"
|
|||
//excel表
|
|||
sheetName := "Sheet1" |
|||
xlsx, err := excelize.OpenFile(path) |
|||
if err != nil { |
|||
return utils.ErrorNull(c, fmt.Sprintf("打开excel失败,error:%s", err.Error())) |
|||
} |
|||
|
|||
//excel错误样式,黄色背景
|
|||
style, _ := xlsx.NewStyle(`{"border":[{"type":"left","color":"000000","style":1},{"type":"top","color":"000000","style":1},{"type":"bottom","color":"000000","style":1},{"type":"right","color":"000000","style":1}],"fill":{"type":"pattern","color":["#ffeb00"],"pattern":1},"alignment":{"horizontal":"left","ident":1,"vertical":"center","wrap_text":true}}`) |
|||
//sheet名称
|
|||
rows := xlsx.GetRows(sheetName) |
|||
|
|||
var ip = c.RealIP() |
|||
var now = time.Now() |
|||
var partyId int64 = 1 |
|||
var account *model.Account |
|||
var accountInfo *model.AccountInfo |
|||
var dateStr, tempStr string |
|||
var errorMap = map[int]interface{}{} |
|||
var errorMsg []string |
|||
var org model.PartyOrg |
|||
var partyPost model.PartyPost |
|||
//模板错误
|
|||
if len(rows) <= 2 { |
|||
return utils.ErrorNull(c, "excel格式错误或无有效数据") |
|||
} |
|||
//无有效数据
|
|||
if len(rows[2]) < 25 { |
|||
return utils.ErrorNull(c, "excel格式错误或无有效数据") |
|||
} |
|||
for rIndex, row := range rows { |
|||
//跳过提示行、标题行
|
|||
if rIndex != 0 && rIndex != 1 { |
|||
errorMsg = []string{} |
|||
accountInfo = new(model.AccountInfo) |
|||
account = new(model.Account) |
|||
//姓名
|
|||
account.FullName = utils.Trim(row[0]) |
|||
if account.FullName == "" { |
|||
errorMsg = append(errorMsg, "姓名不能为空") |
|||
} else if len(account.FullName) >= 50 { |
|||
errorMsg = append(errorMsg, "姓名字符过长") |
|||
} |
|||
|
|||
//性别
|
|||
account.Gender = utils.Trim(row[1]) |
|||
if account.Gender == "" { |
|||
errorMsg = append(errorMsg, "性别为必填项") |
|||
} else if account.Gender != enum.GENDER_MALE && account.Gender != enum.GENDER_FEMALE { |
|||
errorMsg = append(errorMsg, "性别错误,值范围:男、女") |
|||
} |
|||
|
|||
//手机号
|
|||
account.Mobile = utils.Trim(row[2]) |
|||
if account.Mobile == "" { |
|||
errorMsg = append(errorMsg, "手机号码为必填项") |
|||
} else if !utils.IsMobile(account.Mobile) { |
|||
errorMsg = append(errorMsg, "手机号码格式错误") |
|||
} |
|||
account.Name = account.Mobile |
|||
|
|||
//出生日期
|
|||
dateStr = utils.Trim(row[3]) |
|||
account.DateOfBirth, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "出生日期格式错误") |
|||
} |
|||
|
|||
//在岗状态
|
|||
accountInfo.WorkStatus = utils.Trim(row[4]) |
|||
switch accountInfo.WorkStatus { |
|||
case "在岗", "待聘人员", "农民工", "停薪留职", "排休人员", "离退休", "其他", "": |
|||
break |
|||
default: |
|||
errorMsg = append(errorMsg, "在岗状态错误,值范围:在岗, 待聘人员, 农民工, 停薪留职, 排休人员, 离退休, 其他") |
|||
break |
|||
} |
|||
|
|||
//民族
|
|||
accountInfo.Nation = utils.Trim(row[5]) |
|||
if len(accountInfo.Nation) > 50 { |
|||
errorMsg = append(errorMsg, "民族字符串过长") |
|||
} |
|||
|
|||
//籍贯
|
|||
accountInfo.NativePlace = utils.Trim(row[6]) |
|||
if len(accountInfo.Nation) > 100 { |
|||
errorMsg = append(errorMsg, "籍贯字符串过长") |
|||
} |
|||
|
|||
//身份证
|
|||
accountInfo.Idcard = utils.Trim(row[7]) |
|||
|
|||
if accountInfo.Idcard != "" { |
|||
if len(accountInfo.Idcard) != 15 && len(accountInfo.Idcard) != 18 { |
|||
errorMsg = append(errorMsg, "身份证格式错误仅,支持15、18位") |
|||
} |
|||
} |
|||
//学历
|
|||
accountInfo.Education = utils.Trim(row[8]) |
|||
switch accountInfo.Education { |
|||
case "博士", "硕士", "本科", "专科", "高中及以下", "": |
|||
break |
|||
default: |
|||
errorMsg = append(errorMsg, "学历错误,值范围:博士,硕士,本科,专科,高中及以下") |
|||
break |
|||
} |
|||
|
|||
//人员类型
|
|||
accountInfo.PersonnelType = utils.Trim(row[9]) |
|||
if accountInfo.PersonnelType != "" { |
|||
switch accountInfo.PersonnelType { |
|||
case "正式党员", "预备党员", "": |
|||
break |
|||
default: |
|||
errorMsg = append(errorMsg, "学历错误,值范围:正式党员,预备党员") |
|||
break |
|||
} |
|||
} |
|||
|
|||
//党支部
|
|||
tempStr = utils.Trim(row[10]) |
|||
if tempStr != "" { |
|||
org, err = GetPartyOrgByName(partyId, tempStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "党支部不存在") |
|||
} else { |
|||
account.OrgId = org.ID |
|||
} |
|||
} else { |
|||
errorMsg = append(errorMsg, "党支部为必填项") |
|||
} |
|||
|
|||
//党内职务
|
|||
tempStr = utils.Trim(row[11]) |
|||
if tempStr != "" { |
|||
partyPost, err = GetPartyPostByName(partyId, tempStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "党内职务不存在") |
|||
} else { |
|||
accountInfo.PartyPostId = partyPost.ID |
|||
} |
|||
} |
|||
|
|||
//转为预备党员日期
|
|||
dateStr = utils.Trim(row[12]) |
|||
accountInfo.TurnPreparePartyDate, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "转为预备党员日期格式错误") |
|||
} |
|||
|
|||
//转为正式党员日期
|
|||
dateStr = utils.Trim(row[13]) |
|||
accountInfo.TurnPartyDate, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "转为正式党员日期格式错误") |
|||
} |
|||
|
|||
//工作岗位
|
|||
accountInfo.Post = utils.Trim(row[14]) |
|||
if len(accountInfo.Post) >= 50 { |
|||
errorMsg = append(errorMsg, "工作岗位字符过长") |
|||
} |
|||
|
|||
//税后工资
|
|||
tempStr = utils.Trim(row[15]) |
|||
if tempStr != "" { |
|||
accountInfo.AfterTaxWages, err = convert.ToFloat64(utils.Trim(row[15])) |
|||
if err != nil || accountInfo.AfterTaxWages < 0 { |
|||
errorMsg = append(errorMsg, "税后工资格式错误") |
|||
} |
|||
} |
|||
//固定电话
|
|||
accountInfo.Phone = utils.Trim(row[16]) |
|||
if len(accountInfo.Phone) >= 30 { |
|||
errorMsg = append(errorMsg, "固定电话字符过长") |
|||
} |
|||
|
|||
//家庭地址
|
|||
accountInfo.HomeAddress = utils.Trim(row[17]) |
|||
if len(accountInfo.HomeAddress) >= 255 { |
|||
errorMsg = append(errorMsg, "家庭地址字符过长") |
|||
} |
|||
|
|||
//党籍状态
|
|||
accountInfo.PartyStatus = utils.Trim(row[18]) |
|||
switch accountInfo.PartyStatus { |
|||
case "正常", "异常", "": |
|||
break |
|||
default: |
|||
errorMsg = append(errorMsg, "党籍状态错误,值范围:正常、异常") |
|||
break |
|||
} |
|||
|
|||
//是否为失联党员
|
|||
accountInfo.PartyLostStatus = utils.Trim(row[19]) |
|||
switch accountInfo.PartyLostStatus { |
|||
case "是", "否", "": |
|||
break |
|||
default: |
|||
errorMsg = append(errorMsg, "是否为失联党员错误,值范围:是、否") |
|||
break |
|||
} |
|||
|
|||
//失去联系的日期
|
|||
dateStr = utils.Trim(row[20]) |
|||
accountInfo.PartyLostDate, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "失去联系的日期格式错误") |
|||
} |
|||
|
|||
//是否为流动党员
|
|||
accountInfo.PartyFlowStatus = utils.Trim(row[21]) |
|||
switch accountInfo.PartyFlowStatus { |
|||
case "是", "否", "": |
|||
break |
|||
default: |
|||
errorMsg = append(errorMsg, "是否为流动党员错误,值范围:是、否") |
|||
break |
|||
} |
|||
|
|||
//外出流向
|
|||
accountInfo.OutgoingFlow = utils.Trim(row[22]) |
|||
if len(accountInfo.OutgoingFlow) >= 500 { |
|||
errorMsg = append(errorMsg, "外出流向字符过长") |
|||
} |
|||
|
|||
//申请入党日期
|
|||
dateStr = utils.Trim(row[23]) |
|||
accountInfo.PartyApplyDate, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "申请入党日期格式错误") |
|||
} |
|||
|
|||
//列为积极分子日期
|
|||
dateStr = utils.Trim(row[24]) |
|||
accountInfo.PartyActivistDate, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "列为积极分子日期格式错误") |
|||
} |
|||
|
|||
//列为发展对象日期
|
|||
dateStr = utils.Trim(row[25]) |
|||
accountInfo.PartyDevelopDate, err = utils.ParseExcelDate(dateStr) |
|||
if err != nil { |
|||
errorMsg = append(errorMsg, "列为发展对象日期格式错误") |
|||
} |
|||
|
|||
//判断手机号码是否存在
|
|||
acc, _ := GetAccountByMobile(account.Mobile) |
|||
if acc.ID > 0 { |
|||
errorMsg = append(errorMsg, "手机号码已存在") |
|||
} |
|||
|
|||
if len(errorMsg) > 0 { |
|||
//错误记录
|
|||
xlsx.SetCellDefault(sheetName, fmt.Sprintf("AA%v", rIndex+1), strings.Join(errorMsg, ";\r\n")) |
|||
errorMap[rIndex] = errorMsg |
|||
} else { |
|||
//添加的默认数据
|
|||
account.ID = utils.ID() |
|||
account.Status = enum.NORMAL |
|||
account.CTime = &now |
|||
account.UTime = account.CTime |
|||
account.PartyId = partyId |
|||
account.Ip = ip |
|||
|
|||
accountInfo.ID = utils.ID() |
|||
accountInfo.AccountId = account.ID |
|||
|
|||
//数据保存
|
|||
if err := saveImportAccount(account, accountInfo); err != nil { |
|||
//保存失败错误处理
|
|||
errorMsg = append(errorMsg, err.Error()) |
|||
xlsx.SetCellDefault(sheetName, fmt.Sprintf("AA%v", rIndex+1), strings.Join(errorMsg, ";\r\n")) |
|||
errorMap[rIndex] = errorMsg |
|||
} |
|||
} |
|||
//如果有错误,将背景设为警示颜色
|
|||
if len(errorMsg) > 0 { |
|||
xlsx.SetCellStyle(sheetName, fmt.Sprintf("A%v", rIndex+1), fmt.Sprintf("AA%v", rIndex+1), style) |
|||
} |
|||
fmt.Println("-------------------------------------------------------------------------------------------") |
|||
} |
|||
} |
|||
|
|||
if len(errorMap) > 0 { |
|||
//固定的标题栏位置
|
|||
xlsx.SetCellDefault(sheetName, "AA2", "错误说明") |
|||
xlsx.Save() |
|||
return utils.Confirm(c, "导入数据异常,请下载excel根据最后一列的错误说明进行修改调整", fmt.Sprintf("%s", path)) |
|||
} |
|||
//需要自己处理返回
|
|||
return utils.SuccessNull(c, "导入成功") |
|||
} |
|||
|
|||
func saveImportAccount(account *model.Account, accountInfo *model.AccountInfo) error { |
|||
//保存事务
|
|||
tx := global.DB.Begin() |
|||
defer func() { |
|||
if r := recover(); r != nil { |
|||
tx.Rollback() |
|||
} |
|||
}() |
|||
if tx.Error != nil { |
|||
global.Log.Error("tx error:%v", tx.Error.Error()) |
|||
return errors.New(fmt.Sprintf("初始化事务失败:%s", tx.Error.Error())) |
|||
} |
|||
if err := tx.Create(&account).Error; err != nil { |
|||
tx.Rollback() |
|||
global.Log.Error("tx create account error:%v", err) |
|||
return errors.New(fmt.Sprintf("导入党员失败:%s", err.Error())) |
|||
} |
|||
if err := tx.Create(&accountInfo).Error; err != nil { |
|||
tx.Rollback() |
|||
global.Log.Error("tx create accountInfo error:%v", err) |
|||
return errors.New(fmt.Sprintf("导入党员详细信息失败:%s", err.Error())) |
|||
} |
|||
|
|||
if err := tx.Commit().Error; err != nil { |
|||
global.Log.Error("commit error:%v", err) |
|||
return errors.New(fmt.Sprintf("保存党员失败:%s", err.Error())) |
|||
} |
|||
return nil |
|||
} |
|||
|
|||
//去除前后所有空格、空字符串、制表符
|
|||
func Trim(str string) string { |
|||
if str == "" { |
|||
return "" |
|||
} |
|||
return strings.TrimSpace(strings.TrimPrefix(str, string('\uFEFF'))) |
|||
} |
|||
|
|||
//已处理数字型日期
|
|||
func ParseExcelDate(date string) (d *time.Time, err error) { |
|||
if date != "" { |
|||
var date2 time.Time |
|||
if !IsValidNumber(date) { |
|||
date2, err = ParseDate(date) |
|||
if err != nil { |
|||
return |
|||
} |
|||
d = &date2 |
|||
return |
|||
} else { |
|||
date2, err = ParseDate("1900-1-1") |
|||
if err != nil { |
|||
return |
|||
} |
|||
days := convert.MustInt(date) |
|||
date2 = date2.AddDate(0, 0, days-2) |
|||
d = &date2 |
|||
return |
|||
} |
|||
} |
|||
return |
|||
} |
|||
|
|||
func IsValidNumber(date string) bool { |
|||
|
|||
} |
|||
|
|||
//字符串日期转换
|
|||
func ParseDate(date string) (time.Time, error) { |
|||
date = strings.Replace(date, "/", "-", -1) |
|||
date = strings.Replace(date, ".", "-", -1) |
|||
date = strings.Replace(date, "-0", "-", -1) |
|||
local, _ := time.LoadLocation("Local") |
|||
return time.ParseInLocation("2006-1-2", date, local) |
|||
}*/ |
@ -0,0 +1,172 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"fmt" |
|||
|
|||
"github.com/xuri/excelize/v2" |
|||
) |
|||
|
|||
func main() { |
|||
// wb := excelize.NewFile()
|
|||
wb, err := excelize.OpenFile("../excel_files/TMP_05.xlsx") |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
return |
|||
} |
|||
sheetName := wb.GetSheetName(wb.GetActiveSheetIndex()) |
|||
|
|||
sty_idx, err := wb.NewStyle(&excelize.Style{ |
|||
Border: []excelize.Border{ |
|||
{ |
|||
Type: "right", // top bottom left right diagonalDown diagonalUp 中的一个
|
|||
Color: "#000000", // 十六进制的颜色编码
|
|||
Style: 2, // 0-13 有对应的样式
|
|||
}, |
|||
{ |
|||
Type: "left", |
|||
Color: "#000000", |
|||
Style: 2, |
|||
}, |
|||
{ |
|||
Type: "top", |
|||
Color: "#000000", |
|||
Style: 2, |
|||
}, |
|||
{ |
|||
Type: "bottom", |
|||
Color: "#000000", |
|||
Style: 2, |
|||
}, |
|||
}, Fill: excelize.Fill{ |
|||
Type: "gradient", // gradient 渐变色 pattern 填充图案
|
|||
// Pattern: 1, // 填充样式 当类型是 pattern 0-18 填充图案 1 实体填充
|
|||
// Color: []string{"#FF0000"}, // 当Type = pattern 时,只有一个
|
|||
Color: []string{"#00F700", "#00F700"}, |
|||
Shading: 1, // 类型是 gradient 使用 0-5 横向(每种颜色横向分布) 纵向 对角向上 对角向下 有外向内 由内向外
|
|||
}, Font: &excelize.Font{ |
|||
Bold: true, |
|||
// Italic: false,
|
|||
// Underline: "single",
|
|||
Size: 14, |
|||
Family: "宋体", |
|||
// Strike: true, // 删除线
|
|||
Color: "#0000FF", |
|||
}, Alignment: &excelize.Alignment{ |
|||
Horizontal: "center", // 水平对齐方式 center left right fill(填充) justify(两端对齐) centerContinuous(跨列居中) distributed(分散对齐)
|
|||
Vertical: "center", // 垂直对齐方式 center top justify distributed
|
|||
// Indent: 1, // 缩进 只要有值就变成了左对齐 + 缩进
|
|||
// TextRotation: 30, // 旋转
|
|||
// RelativeIndent: 10, // 好像没啥用
|
|||
// ReadingOrder: 0, // 不知道怎么设置
|
|||
// JustifyLastLine: true, // 两端分散对齐,只有 水平对齐 为 distributed 时 设置true 才有效
|
|||
// WrapText: true, // 自动换行
|
|||
// ShrinkToFit: true, // 缩小字体以填充单元格
|
|||
}, Protection: &excelize.Protection{ |
|||
Hidden: true, // 貌似没啥用
|
|||
Locked: true, // 貌似没啥用
|
|||
}, NumFmt: 0, // 内置的数字格式样式 0-638 常用的 0-58 配合lang使用,因为语言不同样式不同 具体的样式参照文档
|
|||
Lang: "zh-cn", // zh-cn 中文
|
|||
DecimalPlaces: 2, // 小数位数 只有NumFmt是 2-11 有效
|
|||
// CustomNumFmt: "",// 自定义样式 是指针,只能通过变量的方式
|
|||
NegRed: true, // 不知道具体的含义
|
|||
}) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
if err := wb.SetCellStyle(sheetName, "A1", "B3", sty_idx); err != nil { |
|||
fmt.Println(err) |
|||
return |
|||
} |
|||
|
|||
// 除了以Go语言的方式传参外,还支持JSON格式的传参
|
|||
// 边框样式
|
|||
border_sty, err := wb.NewStyle(`{"border":[ |
|||
{"type":"top","color":"#000000","style":1}, |
|||
{"type":"left","color":"#000000","style":1}, |
|||
{"type":"right","color":"#000000","style":1}, |
|||
{"type":"bottom","color":"#000000","style":1} |
|||
]}`) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
if err := wb.SetCellStyle(sheetName, "D2", "G10", border_sty); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
// 字体样式
|
|||
// 链接的字体样式 下划线 + 蓝色
|
|||
font_link_sty, err := wb.NewStyle(`{"font":{"underline":"single","size":12,"color":"#0000FF","family":"仿宋"}}`) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
fmt.Println(font_link_sty) |
|||
if err := wb.SetCellValue(sheetName, "F6", "这是链接"); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
if err := wb.SetCellHyperLink(sheetName, "F6", "Sheet1!A1", "Location"); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
if err := wb.SetCellStyle(sheetName, "F6", "F6", font_link_sty); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
styleIdx, err := wb.GetCellStyle(sheetName, "F6") |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
fmt.Println(styleIdx) |
|||
|
|||
// 对齐方式
|
|||
Al_style, err := wb.NewStyle(`{"alignment":{ |
|||
"horizontal":"center", |
|||
"vertical":"center" |
|||
}}`) |
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
if err := wb.SetCellStyle(sheetName, "F6", "F6", Al_style); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
// 多个样式设置在同一个单元格,后面的会覆盖前面的
|
|||
|
|||
link_sty, err := wb.NewStyle(`{ |
|||
"border":[ |
|||
{"type":"top","color":"#000000","style":1}, |
|||
{"type":"left","color":"#000000","style":1}, |
|||
{"type":"right","color":"#000000","style":1}, |
|||
{"type":"bottom","color":"#000000","style":1} |
|||
], |
|||
"font":{ |
|||
"underline":"single", |
|||
"size":12, |
|||
"color":"#0000FF", |
|||
"family":"仿宋" |
|||
}, |
|||
"alignment":{ |
|||
"horizontal":"center", |
|||
"vertical":"center" |
|||
} |
|||
}`) |
|||
|
|||
if err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
if err := wb.SetCellStyle(sheetName, "D11", "D11", link_sty); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
if err := wb.SetCellValue(sheetName, "D11", "这是链接"); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
|
|||
if err := wb.SetCellHyperLink(sheetName, "D11", "http://www.baidu.com", "External"); err != nil { |
|||
fmt.Println(err) |
|||
} |
|||
wb.Save() |
|||
// wb.SaveAs("../excel_files/TMP_05.xlsx")
|
|||
} |
@ -0,0 +1,243 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"database/sql" |
|||
"encoding/json" |
|||
"fmt" |
|||
"github.com/360EntSecGroup-Skylar/excelize" |
|||
_ "github.com/go-sql-driver/mysql" |
|||
"log" |
|||
"strconv" |
|||
"strings" |
|||
"time" |
|||
) |
|||
|
|||
const sheetName = `全部数据` |
|||
const fileName = `公务员系统数据-` |
|||
const fileType = `.xlsx` |
|||
const linkStr = `root:admin@tcp(127.0.0.1:35017)/hy_qggwy?charset=utf8` |
|||
const sqlStr = `SELECT concat(code_type,code_value),code_name FROM CODE_VALUE where code_type in('%s') union SELECT concat(code_type,code_value),code_name3 FROM CODE_VALUE where code_type='ZB01'` |
|||
|
|||
var CodeValueMap = make(map[string]string) |
|||
var allObj = make([][]interface{}, 200) |
|||
|
|||
func main() { |
|||
db, _ := sql.Open("mysql", linkStr) |
|||
codes, headers, types, headWidth, yrYhsLen, err := getInit() |
|||
if err { |
|||
return |
|||
} |
|||
QueryMap(db, fmt.Sprintf(sqlStr, strings.Join(types, "','")), CodeValueMap) |
|||
log.Print("输出内容:", headers) |
|||
log.Print("输出内容:", codes) |
|||
log.Print("输出内容:", CodeValueMap) |
|||
|
|||
allObj = [][]interface{}{} |
|||
ii := make([]interface{}, yrYhsLen, yrYhsLen) |
|||
for i := 0; i < yrYhsLen; i++ { |
|||
ii[i] = "测试" |
|||
} |
|||
allObj = append(allObj, ii) |
|||
ii = make([]interface{}, yrYhsLen, yrYhsLen) |
|||
for i := 0; i < yrYhsLen; i++ { |
|||
ii[i] = "输出内容输出内容输出内容" |
|||
} |
|||
allObj = append(allObj, ii) |
|||
log.Print("输出内容:", allObj) |
|||
getExcelFile(headers, headWidth, allObj) |
|||
} |
|||
|
|||
// getInit 初始化 JSON 对象,获取猎头
|
|||
func getInit() ([]string, []string, []string, []float64, int, bool) { |
|||
var yrYhs []YrYh |
|||
//读取的数据为json格式,需要进行解码
|
|||
err := json.Unmarshal([]byte(yryh), &yrYhs) |
|||
if err != nil { |
|||
log.Fatal("发生异常:", err) |
|||
return nil, nil, nil, nil, 0, true |
|||
} |
|||
yrYhsLen := len(yrYhs) |
|||
types := make([]string, yrYhsLen, yrYhsLen) // 输出类型
|
|||
codes := make([]string, yrYhsLen, yrYhsLen) // 输出信息项
|
|||
headers := make([]string, yrYhsLen, yrYhsLen) // 输出列名
|
|||
headWidth := make([]float64, yrYhsLen, yrYhsLen) // 输出列名
|
|||
for i1, i2 := range yrYhs { |
|||
codes[i1] = i2.Code |
|||
headers[i1] = i2.Name |
|||
headWidth[i1] = i2.Width |
|||
if i2.Type != "" && i2.Type != "DATE" && i2.Type != "ZB01" { |
|||
types[i1] = i2.Type |
|||
} |
|||
} |
|||
return codes, headers, types, headWidth, yrYhsLen, false |
|||
} |
|||
|
|||
func getExcelFile(headers []string, headWidth []float64, values [][]interface{}) { |
|||
f, _ := ExportExcel(sheetName, headers, headWidth, values) |
|||
_ = f.SaveAs(fileName + time.Now().Format("2006102150405") + fileType) |
|||
} |
|||
|
|||
// maxCharCount 最多26个字符A-Z
|
|||
const maxCharCount = 26 |
|||
|
|||
// ExportExcel 导出Excel文件
|
|||
// sheetName 工作表名称, 注意这里不要取sheet1这种名字,否则导致文件打开时发生部分错误。
|
|||
// headers 列名切片, 表头
|
|||
// rows 数据切片,是一个二维数组
|
|||
func ExportExcel(sheetName string, headers []string, headWidth []float64, rows [][]interface{}) (*excelize.File, error) { |
|||
f := excelize.NewFile() |
|||
style, _ := f.NewStyle(`{ |
|||
"border":[ |
|||
{"type":"top","color":"#000000","style":1}, |
|||
{"type":"left","color":"#000000","style":1}, |
|||
{"type":"right","color":"#000000","style":1}, |
|||
{"type":"bottom","color":"#000000","style":1} |
|||
], |
|||
"font":{"size":12,"color":"#000000","family":"仿宋"}, |
|||
"alignment":{"horizontal":"center","vertical":"center","wrap_text":true}, |
|||
"fill":{"type":"gradient","shading":0,"color":["#FFFF00","#FFFF00"]} |
|||
}`) |
|||
sheetIndex := f.NewSheet(sheetName) |
|||
maxColumnRowNameLen := 1 + len(strconv.Itoa(len(rows))) |
|||
columnCount := len(headers) |
|||
if columnCount > maxCharCount { |
|||
maxColumnRowNameLen++ |
|||
} else if columnCount > maxCharCount*maxCharCount { |
|||
maxColumnRowNameLen += 2 |
|||
} |
|||
columnNames := make([][]byte, 0, columnCount) |
|||
f.SetRowHeight(sheetName, 1, 80) // 设置行高
|
|||
for i, header := range headers { |
|||
columnName := getColumnName(i, maxColumnRowNameLen) |
|||
columnNames = append(columnNames, columnName) |
|||
// 初始化excel表头,这里的index从1开始要注意
|
|||
curColumnName := getColumnRowName(columnName, 1) |
|||
f.SetColWidth(sheetName, toCharStr(i+1), toCharStr(i+1), headWidth[i]) |
|||
f.SetCellValue(sheetName, curColumnName, header) |
|||
f.SetCellStyle(sheetName, curColumnName, curColumnName, style) // 设置单元格样式
|
|||
} |
|||
for rowIndex, row := range rows { |
|||
for columnIndex, columnName := range columnNames { |
|||
// 从第二行开始
|
|||
f.SetCellValue(sheetName, getColumnRowName(columnName, rowIndex+2), row[columnIndex]) |
|||
} |
|||
} |
|||
f.SetActiveSheet(sheetIndex) |
|||
return f, nil |
|||
} |
|||
|
|||
// getColumnName 生成列名
|
|||
// Excel的列名规则是从A-Z往后排;超过Z以后用两个字母表示,比如AA,AB,AC;两个字母不够以后用三个字母表示,比如AAA,AAB,AAC
|
|||
// 这里做数字到列名的映射:0 -> A, 1 -> B, 2 -> C
|
|||
// maxColumnRowNameLen 表示名称框的最大长度,假设数据是10行,1000列,则最后一个名称框是J1000(如果有表头,则是J1001),是4位
|
|||
// 这里根据 maxColumnRowNameLen 生成切片,后面生成名称框的时候可以复用这个切片,而无需扩容
|
|||
func getColumnName(column, maxColumnRowNameLen int) []byte { |
|||
const A = 'A' |
|||
if column < maxCharCount { |
|||
// 第一次就分配好切片的容量
|
|||
slice := make([]byte, 0, maxColumnRowNameLen) |
|||
return append(slice, byte(A+column)) |
|||
} else { |
|||
// 递归生成类似AA,AB,AAA,AAB这种形式的列名
|
|||
return append(getColumnName(column/maxCharCount-1, maxColumnRowNameLen), byte(A+column%maxCharCount)) |
|||
} |
|||
} |
|||
|
|||
// getColumnRowName 生成名称框
|
|||
// Excel的名称框是用A1,A2,B1,B2来表示的,这里需要传入前一步生成的列名切片,然后直接加上行索引来生成名称框,就无需每次分配内存
|
|||
func getColumnRowName(columnName []byte, rowIndex int) (columnRowName string) { |
|||
l := len(columnName) |
|||
columnName = strconv.AppendInt(columnName, int64(rowIndex), 10) |
|||
columnRowName = string(columnName) |
|||
// 将列名恢复回去
|
|||
columnName = columnName[:l] |
|||
return |
|||
} |
|||
|
|||
// 获取表数据
|
|||
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 has(v1 dept, vs []*dept) bool { |
|||
var has bool |
|||
has = false |
|||
for _, v2 := range vs { |
|||
v3 := *v2 |
|||
if v1.Pid+v1.Id == v3.Pid { |
|||
has = true |
|||
break |
|||
} |
|||
} |
|||
return has |
|||
|
|||
} |
|||
|
|||
func makeTree(vs []*dept, node *dept) { |
|||
fmt.Println("the node value in maketree is:", *node) |
|||
childs := findChild(node, vs) |
|||
fmt.Println(" the child we got is :", childs) |
|||
for _, child := range childs { |
|||
fmt.Println("in the childs's for loop, the child's address here is:", &child) |
|||
node.Child = append(node.Child, child) |
|||
fmt.Println("in the child's for loop, after append the child is:", child) |
|||
if has(*child, vs) { |
|||
fmt.Println("i am in if has") |
|||
fmt.Println("the child in if has is:", *child) |
|||
fmt.Println("the child in if has 's address is:", child) |
|||
makeTree(vs, child) |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
func findChild(v *dept, vs []*dept) (ret []*dept) { |
|||
for _, v2 := range vs { |
|||
if v.Pid+v.Id == v2.Pid { |
|||
ret = append(ret, v2) |
|||
} |
|||
} |
|||
return |
|||
} |
|||
|
|||
// 数字转字母
|
|||
func toCharStr(i int) string { |
|||
return string('A' - 1 + i) |
|||
} |
|||
|
|||
type YrYh struct { |
|||
Name string `json:"name"` |
|||
Code string `json:"code"` |
|||
Type string `json:"type"` |
|||
Width float64 `json:"width"` |
|||
} |
|||
|
|||
var yryh = `[ |
|||
{"name":"姓名","code":"a01.a0101","type":"","width":11}, |
|||
{"name":"性别","code":"a01.a0104","type":"GB2261","width":8}, |
|||
{"name":"民族","code":"a01.a0117","type":"GB3304","width":8}, |
|||
{"name":"出生日期","code":"a01.a0107","type":"DATE","width":12}, |
|||
{"name":"参加工作时间","code":"a01.a0134","type":"DATE","width":13}, |
|||
{"name":"入党时间","code":"a01.a0140","type":"","width":12}, |
|||
{"name":"工作单位及职务全称","code":"a01.a0192a","type":"","width":20}, |
|||
{"name":"职务层次","code":"a01.a0221","type":"ZB09","width":12}, |
|||
{"name":"任职务层次时间","code":"a01.a0288","type":"DATE","width":15}, |
|||
{"name":"职级","code":"a01.a0192e","type":"ZB148","width":12}, |
|||
{"name":"任职级时间","code":"a01.a0192c","type":"DATE","width":12}, |
|||
{"name":"任相当层次职务职级时间","code":"a01.a0192x","type":"DATE","width":15}, |
|||
{"name":"最高学历","code":"a01.zgxl","type":"","width":15}, |
|||
{"name":"籍贯","code":"a01.a0111","type":"ZB01","width":12} |
|||
]` |
|||
|
|||
// 树结构
|
|||
type dept struct { |
|||
Id string `json:"id"` |
|||
Pid string `json:"pid"` |
|||
Child []*dept `json:"child"` |
|||
} |
@ -0,0 +1,42 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"log" |
|||
) |
|||
|
|||
func main() { |
|||
var yrYhs []YrYh |
|||
//读取的数据为json格式,需要进行解码
|
|||
err := json.Unmarshal([]byte(yryh), &yrYhs) |
|||
if err != nil { |
|||
log.Fatal("发生异常:", err) |
|||
return |
|||
} |
|||
for _, i2 := range yrYhs { |
|||
log.Print("输出内容:", i2) |
|||
} |
|||
} |
|||
|
|||
type YrYh struct { |
|||
Name string `json:"name"` |
|||
Code string `json:"code"` |
|||
Type string `json:"type"` |
|||
} |
|||
|
|||
var yryh = `[ |
|||
{"name":"姓名","code":"a0101","type":""}, |
|||
{"name":"性别","code":"a0104","type":"GB2261"}, |
|||
{"name":"民族","code":"a0117","type":"GB3304"}, |
|||
{"name":"出生日期","code":"a0107","type":"DATE"}, |
|||
{"name":"参加工作时间","code":"a0134","type":"DATE"}, |
|||
{"name":"入党时间","code":"a0140","type":""}, |
|||
{"name":"工作单位及职务全称","code":"a0192a","type":""}, |
|||
{"name":"职务层次","code":"a0221","type":"ZB09"}, |
|||
{"name":"任职务层次时间","code":"a0288","type":"DATE"}, |
|||
{"name":"职级","code":"a0192e","type":"ZB148"}, |
|||
{"name":"任职级时间","code":"a0192c","type":"DATE"}, |
|||
{"name":"任相当层次职务职级时间","code":"a0192x","type":"DATE"}, |
|||
{"name":"最高学历","code":"zgxl","type":""}, |
|||
{"name":"籍贯","code":"a0111","type":"ZB01"} |
|||
]` |
@ -0,0 +1,35 @@ |
|||
package main |
|||
|
|||
//func main() {
|
|||
// var funcs []func(db *gorm.DB) error
|
|||
// for _, user := range prugs {
|
|||
// funcs = append(funcs, func(db *gorm.DB) error {
|
|||
// execSQL := ""
|
|||
// return db.Exec(execSQL, value...).Error
|
|||
// })
|
|||
// }
|
|||
//
|
|||
// if err := global.Tx(funcs...); err != nil {
|
|||
// global.Log.Error("err:%s", err.Error())
|
|||
// return err
|
|||
// }
|
|||
//}
|
|||
|
|||
//func Tx(funcs ...func(db *gorm.DB) error) (err error) {
|
|||
// tx := DB.Begin()
|
|||
// defer func() {
|
|||
// if r := recover(); r != nil {
|
|||
// tx.Rollback()
|
|||
// err = fmt.Errorf("%v", err)
|
|||
// }
|
|||
// }()
|
|||
// for _, f := range funcs {
|
|||
// err = f(tx)
|
|||
// if err != nil {
|
|||
// tx.Rollback()
|
|||
// return
|
|||
// }
|
|||
// }
|
|||
// err = tx.Commit().Error
|
|||
// return
|
|||
//}
|
Loading…
Reference in new issue