Go怎么结合Gin导出Mysql数据到Excel表格

    1、实现目标

    Golang 使用excelize 导出表格到浏览器下载或者保存到本地。后续导入的话也会写到这里

    2、使用的库

    go get github.com/xuri/excelize/v2

    3、项目目录go-excel
    ├─ app
    │ ├─ excelize
    │ │ └─ excelize.go
    │ ├─ model
    │ │ └─ sysUser.go
    │ └─ service
    │ └─ userService.go
    ├─ common
    │ └─ mysql.go
    ├─ go.mod
    ├─ go.sum
    ├─ main.go
    └─ setting.json 4、主要代码编写

    读取配置文件是用的viper

    4.1、excelize.go(主要工具类)

    Gin+Go轻松导出Mysql数据到Excel表格

    ExportExcelByStruct 函数 是从网络上直接copy的,研究他这个写法花了好一会儿,所以也写上去了,提供大家学习

    import (
    "
    fmt"

    "
    math/rand"

    "
    net/url"

    "
    reflect"

    "
    strconv"

    "
    time"


    "
    github.com/gin-gonic/gin"

    "
    github.com/xuri/excelize/v2"

    )

    var (
    defaultSheetName = "
    Sheet1"
    //默认Sheet名称
    defaultHeight = 25.0 //默认行高度
    )

    type lzExcelExport struct {
    file *excelize.File
    sheetName string //可定义默认sheet名称
    }

    func NewMyExcel() *lzExcelExport {
    return &
    lzExcelExport{file: createFile(), sheetName: defaultSheetName}
    }

    //导出基本的表格
    func (l *lzExcelExport) ExportToPath(params []map[string]string, data []map[string]interface{}, path string) (string, error) {
    l.export(params, data)
    name := createFileName()
    filePath := path + "
    /"
    + name
    err := l.file.SaveAs(filePath)
    return filePath, err
    }

    //导出到浏览器。此处使用的gin框架 其他框架可自行修改ctx
    func (l *lzExcelExport) ExportToWeb(params []map[string]string, data []map[string]interface{}, c *gin.Context) {
    l.export(params, data)
    buffer, _ := l.file.WriteToBuffer()
    //设置文件类型
    c.Header("
    Content-Type"
    , "
    application/vnd.ms-excel;
    charset=utf8"
    )
    //设置文件名称
    c.Header("
    Content-Disposition"
    , "
    attachment;
    filename="
    +url.QueryEscape(createFileName()))
    _, _ = c.Writer.Write(buffer.Bytes())
    }

    //设置首行
    func (l *lzExcelExport) writeTop(params []map[string]string) {
    topStyle, _ := l.file.NewStyle(`{"
    font"
    :{"
    bold"
    :true},"
    alignment"
    :{"
    horizontal"
    :"
    center"
    ,"
    vertical"
    :"
    center"
    }}`)
    var word = '
    A'

    //首行写入
    for _, conf := range params {
    title := conf["
    title"
    ]
    width, _ := strconv.ParseFloat(conf["
    width"
    ], 64)
    line := fmt.Sprintf("
    %c1"
    , word)
    //设置标题
    _ = l.file.SetCellValue(l.sheetName, line, title)
    //列宽
    _ = l.file.SetColWidth(l.sheetName, fmt.Sprintf("
    %c"
    , word), fmt.Sprintf("
    %c"
    , word), width)
    //设置样式
    _ = l.file.SetCellStyle(l.sheetName, line, line, topStyle)
    word++
    }
    }

    //写入数据
    func (l *lzExcelExport) writeData(params []map[string]string, data []map[string]interface{}) {
    lineStyle, _ := l.file.NewStyle(`{"
    alignment"
    :{"
    horizontal"
    :"
    center"
    ,"
    vertical"
    :"
    center"
    }}`)
    //数据写入
    var j = 2 //数据开始行数
    for i, val := range data {
    //设置行高
    _ = l.file.SetRowHeight(l.sheetName, i+1, defaultHeight)
    //逐列写入
    var word = '
    A'

    for _, conf := range params {
    valKey := conf["
    key"
    ]
    line := fmt.Sprintf("
    %c%v"
    , word, j)
    isNum := conf["
    is_num"
    ]

    //设置值
    if isNum != "
    0"
    {
    valNum := fmt.Sprintf("
    '
    %v"
    , val[valKey])
    _ = l.file.SetCellValue(l.sheetName, line, valNum)
    } else {
    _ = l.file.SetCellValue(l.sheetName, line, val[valKey])
    }

    //设置样式
    _ = l.file.SetCellStyle(l.sheetName, line, line, lineStyle)
    word++
    }
    j++
    }
    //设置行高 尾行
    _ = l.file.SetRowHeight(l.sheetName, len(data)+1, defaultHeight)
    }

    func (l *lzExcelExport) export(params []map[string]string, data []map[string]interface{}) {
    l.writeTop(params)
    l.writeData(params, data)
    }

    func createFile() *excelize.File {
    f := excelize.NewFile()
    // 创建一个默认工作表
    sheetName := defaultSheetName
    index := f.NewSheet(sheetName)
    // 设置工作簿的默认工作表
    f.SetActiveSheet(index)
    return f
    }

    func createFileName() string {
    name := time.Now().Format("
    2006-01-02-15-04-05"
    )
    rand.Seed(time.Now().UnixNano())
    return fmt.Sprintf("
    excle-%v-%v.xlsx"
    , name, rand.Int63n(time.Now().Unix()))
    }

    //excel导出(数据源为Struct) []interface{}
    func (l *lzExcelExport) ExportExcelByStruct(titleList []string, data []interface{}, fileName string, sheetName string, c *gin.Context) error {
    l.file.SetSheetName("
    Sheet1"
    , sheetName)
    header := make([]string, 0)
    for _, v := range titleList {
    header = append(header, v)
    }
    rowStyleID, _ := l.file.NewStyle(`{"
    font"
    :{"
    color"
    :"
    #666666"
    ,"
    size"
    :13,"
    family"
    :"
    arial"
    },"
    alignment"
    :{"
    vertical"
    :"
    center"
    ,"
    horizontal"
    :"
    center"
    }}`)
    _ = l.file.SetSheetRow(sheetName, "
    A1"
    , &
    header)
    _ = l.file.SetRowHeight("
    Sheet1"
    , 1, 30)
    length := len(titleList)
    headStyle := Letter(length)
    var lastRow string
    var widthRow string
    for k, v := range headStyle {

    if k == length-1 {

    lastRow = fmt.Sprintf("
    %s1"
    , v)
    widthRow = v
    }
    }
    if err := l.file.SetColWidth(sheetName, "
    A"
    , widthRow, 30);
    err != nil {
    fmt.Print("
    错误--"
    , err.Error())
    }
    rowNum := 1
    for _, v := range data {

    t := reflect.TypeOf(v)
    fmt.Print("
    --ttt--"
    , t.NumField())
    value := reflect.ValueOf(v)
    row := make([]interface {
    }, 0)
    for l := 0;
    l <
    t.NumField();
    l++ {

    val := value.Field(l).Interface()
    row = append(row, val)
    }
    rowNum++
    err := l.file.SetSheetRow(sheetName, "
    A"
    +strconv.Itoa(rowNum), &
    row)
    _ = l.file.SetCellStyle(sheetName, fmt.Sprintf("
    A%d"
    , rowNum), fmt.Sprintf("
    %s"
    , lastRow), rowStyleID)
    if err != nil {
    return err
    }
    }
    disposition := fmt.Sprintf("
    attachment;
    filename=%s.xlsx"
    , url.QueryEscape(fileName))
    c.Writer.Header().Set("
    Content-Type"
    , "
    application/octet-stream"
    )
    c.Writer.Header().Set("
    Content-Disposition"
    , disposition)
    c.Writer.Header().Set("
    Content-Transfer-Encoding"
    , "
    binary"
    )
    c.Writer.Header().Set("
    Access-Control-Expose-Headers"
    , "
    Content-Disposition"
    )
    return l.file.Write(c.Writer)
    }

    // Letter 遍历a-z
    func Letter(length int) []string {
    var str []string
    for i := 0;
    i <
    length;
    i++ {
    str = append(str, string(rune('
    A'
    +i)))
    }
    return str
    } 4.2、userService.go(接受请求)

    其中导出的函数都已经测试是ok的,可以直接用,数据改成自己的就好,注意的事项里面我也写了,避雷!!

    import (
    "
    go-excel/app/excelize"

    "
    go-excel/app/model"

    config "
    go-excel/common"

    "
    github.com/gin-gonic/gin"

    )



    //获取所有用户数据-excel
    func GetAllUserExportToWeb(ctx *gin.Context) {
    var users []model.TUser
    db := config.GetDB()
    db.Find(&
    users)

    //定义首行标题
    dataKey := make([]map[string]string, 0)
    dataKey = append(dataKey, map[string]string{
    "
    key"
    : "
    id"
    ,
    "
    title"
    : "
    索引"
    ,
    "
    width"
    : "
    20"
    ,
    "
    is_num"
    : "
    0"
    ,
    })
    dataKey = append(dataKey, map[string]string{
    "
    key"
    : "
    username"
    ,
    "
    title"
    : "
    用户名"
    ,
    "
    width"
    : "
    20"
    ,
    "
    is_num"
    : "
    0"
    ,
    })
    dataKey = append(dataKey, map[string]string{
    "
    key"
    : "
    remark"
    ,
    "
    title"
    : "
    备注"
    ,
    "
    width"
    : "
    20"
    ,
    "
    is_num"
    : "
    0"
    ,
    })

    //填充数据
    data := make([]map[string]interface{}, 0)
    if len(users) >
    0 {
    for _, v := range users {
    data = append(data, map[string]interface{}{
    "
    id"
    : v.ID,
    "
    username"
    : v.Username,
    "
    remark"
    : v.Remark,
    })
    }
    }
    ex := excelize.NewMyExcel()

    // ex.ExportToWeb(dataKey, data, ctx)

    //保存到D盘
    ex.ExportToPath(dataKey, data, "
    D:/"
    )
    }

    //excel 导出
    func GetUserExcelByMap(ctx *gin.Context) {
    var users []model.TUser
    db := config.GetDB()
    db.Find(&
    users)

    titles := []string{"
    ID"
    , "
    用户名"
    , "
    备注"
    }

    ex := excelize.NewMyExcel()

    var datas []interface{}
    for _, v := range users {
    //这里最好新建一个struct 和titles一致,不然users里面的多余的字段也会写进去
    datas = append(datas, model.TUser{
    ID: v.ID,
    Username: v.Username,
    Remark: v.Remark,
    })
    }
    ex.ExportExcelByStruct(titles, datas, "
    用户数据"
    , "
    用户"
    , ctx)
    } 4.2、测试结果

    GetAllUserExportToWeb

    GetUserExcelByMap



    随着数据分析的需求逐渐增加,导出Excel表格的功能变得越来越常见。本文将介绍如何使用Gin框架和Go语言来实现将Mysql数据库中的数据导出到Excel表格中。
    第一步:连接Mysql数据库
    要导出数据库中的数据,首先需要建立与Mysql数据库的连接。可以使用Go语言提供的database/sql包来连接数据库。在代码中,需要指定数据库的连接信息,例如数据库名、用户名和密码等。
    第二步:查询数据并存储到Excel文件中
    有了与数据库的连接之后,就可以直接进行数据的查询了。在Go语言中,可以使用sql包提供的Query方法来执行数据库查询。查询出需要的数据之后,可以通过excelize包将数据保存到Excel表格中。需要注意的是,在保存数据的过程中,可以通过设置Excel单元格的格式来实现对数据的样式进行设置。
    第三步:进行Excel文件的导出
    最后一步是导出生成的Excel文件。可以使用Go语言提供的net/http包来完成文件下载。将生成的Excel文件写入到HTTP Response中,用户就可以通过下载链接来下载导出的Excel文件了。
    结论
    本文通过搭建基于Gin和Go语言的数据导出平台,让开发者轻松实现从Mysql数据库中导出数据到Excel表格中的功能。通过本文的介绍和实现,读者可以更好地理解Gin和Go语言在数据处理和导出中的应用。