Browse Source

完成 Golang 导出excel

master
VIVIMAN 3 years ago
parent
commit
c0299db2f5
  1. 394
      golang_learn/data_func/go_to_excel/go_to_checkExcel/main.go
  2. 16
      golang_learn/data_func/go_to_excel/go_to_main/main.go
  3. 172
      golang_learn/data_func/go_to_excel/go_to_main_style/main.go
  4. 243
      golang_learn/data_func/go_to_excel/go_to_mc/query_all/main.go
  5. 0
      golang_learn/data_func/go_to_json/demo01/demo.go
  6. 0
      golang_learn/data_func/go_to_json/demo02/demo.go
  7. 42
      golang_learn/data_func/go_to_json/demo03/main.go
  8. 35
      golang_learn/data_func/go_to_orm/go_to_gom/main.go
  9. 4
      golang_learn/go.mod
  10. 20
      golang_learn/go.sum

394
golang_learn/data_func/go_to_excel/go_to_checkExcel/main.go

@ -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)
}*/

16
golang_learn/data_func/go_to_excel/go_to_main/main.go

@ -4,12 +4,26 @@ package main
* 推荐使用方式写的输出excel文件
**/
import (
// "github.com/360EntSecGroup-Skylar/excelize/v2"
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
"strconv"
)
func main() {
headers := []string{"用户名", "性别", "年龄"}
values := [][]interface{}{
{"测试", 1, "男"},
{"ggr1", 2, "男"},
}
f, _ := ExportExcel("Sheet1", headers, values)
err := f.SaveAs("test.xlsx")
fmt.Sprintln(err)
// 文件名使用英文,否则会中文乱码
//fileName = "test.xlxs"
//w.Header().Add("Content-Type", "application/octet-stream")
//w.Header().Add("Content-Disposition", "attachment; filename="+fileName)
//w.Header().Add("Content-Transfer-Encoding", "binary")
}

172
golang_learn/data_func/go_to_excel/go_to_main_style/main.go

@ -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")
}

243
golang_learn/data_func/go_to_excel/go_to_mc/query_all/main.go

@ -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
golang_learn/data_func/go_to_json/demo/demo.go → golang_learn/data_func/go_to_json/demo01/demo.go

0
golang_learn/data_func/go_to_json/demo1/demo.go → golang_learn/data_func/go_to_json/demo02/demo.go

42
golang_learn/data_func/go_to_json/demo03/main.go

@ -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"}
]`

35
golang_learn/data_func/go_to_orm/go_to_gom/main.go

@ -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
//}

4
golang_learn/go.mod

@ -30,10 +30,10 @@ require (
github.com/spf13/viper v1.8.1
github.com/tidwall/gjson v1.13.0
github.com/tidwall/sjson v1.2.4
github.com/xuri/excelize/v2 v2.5.0
github.com/yeka/zip v0.0.0-20180914125537-d046722c6feb
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
golang.org/x/exp/errors v0.0.0-20210715201039-d37aa40e8013
golang.org/x/image v0.0.0-20201208152932-35266b937fa6
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
golang.org/x/text v0.3.6
gopkg.in/Knetic/govaluate.v3 v3.0.0 // indirect

20
golang_learn/go.sum

@ -267,6 +267,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI=
github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o=
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
@ -317,6 +321,10 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc=
github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM=
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o=
github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.5.0 h1:nDDVfX0qaDuGjAvb+5zTd0Bxxoqa1Ffv9B4kiE23PTM=
github.com/xuri/excelize/v2 v2.5.0/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A=
github.com/yeka/zip v0.0.0-20180914125537-d046722c6feb h1:OJYP70YMddlmGq//EPLj8Vw2uJXmrA+cGSPhXTDpn2E=
github.com/yeka/zip v0.0.0-20180914125537-d046722c6feb/go.mod h1:9BnoKCcgJ/+SLhfAXj15352hTOuVmG5Gzo8xNRINfqI=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -344,8 +352,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -362,8 +370,8 @@ golang.org/x/exp/errors v0.0.0-20210715201039-d37aa40e8013/go.mod h1:YgqsNsAu4fT
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20201208152932-35266b937fa6 h1:nfeHNc1nAqecKCy2FCy4HY+soOOe5sDLJ/gZLbx6GYI=
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk=
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -424,8 +432,9 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985 h1:4CSI6oo7cOjJKajidEljs9h+uP0rRZBPPPhcCbj5mw8=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -495,6 +504,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

Loading…
Cancel
Save