Golang 使用excelize 导出表格到浏览器下载或者保存到本地。

4666人浏览 2021-10-20

Golang 使用excelize 导出表格到浏览器下载或者保存到本地。

1.安装Excelize.

go get github.com/xuri/excelize/v2

 官方文档:https://xuri.me/excelize/zh-hans/base/installation.html#install

2.封装好的包

package excelizeLib

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
	"math/rand"
	"net/url"
	"strconv"
	"time"
)

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

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

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

// ExportToPath 导出基本的表格
func (l *lkExcelExport) 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
}

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

//设置首行
func (l *lkExcelExport) 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 *lkExcelExport) 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 *lkExcelExport) 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()))
}

3.调用实例。

注意:本示例使用的是gin框架。

role.GET("test", func(ctx *gin.Context) {
				//数据索引 避免map无序导致数据导出顺序颠倒
				dataKey := make([]map[string]string,0)
				dataKey = append(dataKey, map[string]string{"key":"title","title":"商品","width":"20","is_num":"0"})
				dataKey = append(dataKey, map[string]string{"key":"price","title":"价格","width":"30","is_num":"0"})
				dataKey = append(dataKey, map[string]string{"key":"num","title":"库存","width":"20","is_num":"1"})

				data := make([]map[string]interface{},0)
				data = append(data, map[string]interface{}{
					"title":"苹果",
					"price":99.99,
					"num":121241231231212,
				})
				data = append(data, map[string]interface{}{
					"title":"橘子",
					"price":69.99,
					"num":80,
				})
				data = append(data, map[string]interface{}{
					"title":"香蕉",
					"price":89.99,
					"num":90,
				})
				excel := excelizeLib.NewMyExcel()
				excel.ExportToWeb(dataKey, data, ctx)

})

4.效果图:

推荐文章

GORM 自定义结构体关联的数据库表名称和自定义结构体字段对应的数据表字段名
2021-02-23
KChatRoom在线多人聊天室,项目是使用Websocket和Gin框架基于Golang开发的在线聊天室
2021-05-17
Gin框架下获取所有路由信息
2021-07-14
搜索文章