0

0

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

WBOY

WBOY

发布时间:2023-05-26 21:15:20

|

2181人浏览过

|

来源于亿速云

转载

    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(主要工具类)

    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

    Imagine By Magic Studio
    Imagine By Magic Studio

    AI图片生成器,用文字制作图片

    下载

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

    GetUserExcelByMap

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

    相关文章

    WPS零基础入门到精通全套教程!
    WPS零基础入门到精通全套教程!

    全网最新最细最实用WPS零基础入门到精通全套教程!带你真正掌握WPS办公! 内含Excel基础操作、函数设计、数据透视表等

    下载

    相关标签:

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    WorkBuddy
    WorkBuddy

    腾讯云推出的AI原生桌面智能体工作台

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    C# ASP.NET Core微服务架构与API网关实践
    C# ASP.NET Core微服务架构与API网关实践

    本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

    76

    2026.03.11

    Go高并发任务调度与Goroutine池化实践
    Go高并发任务调度与Goroutine池化实践

    本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

    38

    2026.03.10

    Kotlin Android模块化架构与组件化开发实践
    Kotlin Android模块化架构与组件化开发实践

    本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

    83

    2026.03.09

    JavaScript浏览器渲染机制与前端性能优化实践
    JavaScript浏览器渲染机制与前端性能优化实践

    本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

    97

    2026.03.06

    Rust内存安全机制与所有权模型深度实践
    Rust内存安全机制与所有权模型深度实践

    本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

    223

    2026.03.05

    PHP高性能API设计与Laravel服务架构实践
    PHP高性能API设计与Laravel服务架构实践

    本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

    458

    2026.03.04

    AI安装教程大全
    AI安装教程大全

    2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

    169

    2026.03.04

    Swift iOS架构设计与MVVM模式实战
    Swift iOS架构设计与MVVM模式实战

    本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

    246

    2026.03.03

    C++高性能网络编程与Reactor模型实践
    C++高性能网络编程与Reactor模型实践

    本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

    34

    2026.03.03

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    MySQL 教程
    MySQL 教程

    共48课时 | 2.5万人学习

    MySQL 初学入门(mosh老师)
    MySQL 初学入门(mosh老师)

    共3课时 | 0.3万人学习

    简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信

    共1课时 | 848人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号