forked from go/golangs_learn
				
			
				 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