.. | ||
example | ||
excel_test.go | ||
excelInter.go | ||
img_1.png | ||
img.png | ||
options.go | ||
readme.md | ||
utils.go |
excel文件生成器
excel文件生成器简介
此模块提供了通过.xlsx
格式的excel模板文件,创建文件并自动添加数据的方法。
此模块通过设计模式,在"github.com/xuri/excelize/v2"的基础上封装了ExcelCreator
这一泛型的方法。适用于快速开发报表导出功能。
基本使用示例
package main
import (
"fmt"
"github.com/flipped-aurora/gin-vue-admin/server/utils/excel"
"github.com/flipped-aurora/gin-vue-admin/server/utils/simpletime"
"sync"
"time"
)
//读写锁
var exportEpidemicPreventStaticStaticLock sync.RWMutex
//定义sheet1数据结构
type EpidemicPreventStaticReport struct {
Xid int `json:"xid" form:"xid" db:"column:xid;comment:序号"`
Time string `json:"time" form:"time" db:"column:time;comment:日期"`
Name string `json:"name" form:"name" db:"column:name;comment:项目名称"`
Code string `json:"code" form:"code" db:"column:code;comment:监督备案号"`
Street string `json:"street" form:"street" db:"column:street;comment:街道"`
State string `json:"state" form:"state" db:"column:state;comment:状态:未完成、已完成"`
}
//导出数据
func (m EpidemicPreventStaticReport) WriteToExcel(datas []EpidemicPreventStaticReport) (path string, filename string, err error) {
defer exportEpidemicPreventStaticStaticLock.Unlock()
//实例化sheet1,载入数据
st1 := excel.NewSheet("Sheet1", datas)
var suffixName = func() string {
return fmt.Sprintf("%v", simpletime.TimeToString(time.Now(), simpletime.TimeFormat.NoSpacer_YMDhms))
}
//实例化excelCreator
exc, err := excel.NewExcelCreator("防疫日报日完成项目数统计.xlsx", &suffixName, "uploads/template2/file", "uploads/template2/防疫日报日完成项目数统计.xlsx", st1)
if err != nil {
fmt.Println(err.error())
}
exportEpidemicPreventStaticStaticLock.Lock()
// 导出数据
return exc.WriteToExcel()
}
func main(){
var (
reportData []EpidemicPreventStaticReport
excel EpidemicPreventStaticReport
)
//do something
//..
//..
path,filename,err:=excel.WriteToExcel(reportData)
if err!=nil{
fmt.Println(err.Error())
}else{
fmt.Printf("path:%v\nfilename:%v\n",path,filename)
}
}
使用说明
此模块的使用流程如下
1. 创建excel模板,定义好工作簿名称和表头
请注意,程序默认数据都是一行行连续的。如果两条数据之间间隔了一个或多个空行,导出的数据可能会出现错误。
2. 定义工作簿数据结构
注意事项:
- 结构体字段顺序要与工作簿的表头顺序一一对应、命名规则随意;
- json标签用于数据的转换,同时也便于将结构体直接作为接口请求参数来使用;没有json标签时,数据将会被忽略;
type Sheet1 struct {
Xid int `json:"xid"`
Name string `json:"name"`
Age int `json:"age"`
}
3. 准备数据,实例化sheet对象
数据类型至此结构体和切片
NewSheet
方法的第一个参数是工作簿名称,需要与模板文件中的对应,不然导出数据时会报错
//准备数据
var sheet1Data = []Sheet1Define{
{1, "张三", 16},
{2, "黑猫警长", 18},
}
//实例化sheet对象
var sheet1 = excel.NewSheet("Sheet1", &sheet1Data)
4 生成excel文件
4.1 直接生成文件
如果你不需要什么额外操作,只想直接生成excel文件,那么可以直接调用这个方法
//定义后缀名生成器,如果不需要可以传nil
var suffixFunc = func() string { return fmt.Sprintf("%v", time.Now().Unix()) }
//导出文件
path,err:=excel.WriteToExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1)
生成效果:
4.2 ExcelCreator
ExcelCreator可以用来对工作簿和工作簿中的数据进行增删改查,以及生成文件。
4.2.1 实例化ExcelCreator
var suffixFunc = func() string { return fmt.Sprintf("%v", time.Now().Unix()) } //文件后缀名生成方法
exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1)
if err!=nil{
fmt.Println(err.Error())
}
//可连续添加多个工作簿或者不传,当然也支持一张工作簿数据的多次传入
//exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1,sheet_2,sheet_3)
//exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx")
//exCreator,err := excel.NewExcel("demo.xlsx", &suffixFunc, "./", "./demo.xlsx", sheet_1_1,sheet_1_2,sheet_1_3)
//不使用文件后缀名
//exCreator,err := excel.NewExcelCreator("demo.xlsx", nil, "./", "./demo.xlsx", sheet_1)
//exCreator,err := excel.NewExcelCreatorWithoutSuffix("demo.xlsx","./", "./demo.xlsx", sheet_1)
FileName
和 filesSuffix
参数的说明
当设置了filesSuffix
参数后,创建excel文件时会自动生成文件后缀名。
如FileName
设置为"demo.xlsx"、filesSuffix
返回值为"20200723",那么最终文件名为"demo20200723.xlsx"
4.2.2 新增工作簿
如果工作簿已存在,数据会组合而不是覆盖
var err = exCreator.SheetsAdd(sheet_2)
4.2.3 删除工作簿
var err = exCreator.SheetsDelete(sheet_2.SheetName())
4.2.5 取出工作簿map和缓存数据
工作簿存储在ExcelCreator.Sheets
中,存储结构为map[string][]sheet
。string即工作簿名称。取出后可以进行任意的操作
var sheets = exCreator.Sheets
datas:= sheets["Sheet1"].GetDatas
//do somthing...
4.2.6 将数据生成到文件
path,fileName, err := exCreator.WriteToExcel()
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println(path)
fmt.Println(fileName)
}
相关问题
1. 为什么不支持通过代码直接生成表头?
鉴于在部分场景下,表头格式比较复杂,且通过代码生成灵活较度差,单元格格式通过代码设置比较繁琐。相比较下,没有直接创建excel文件模板来调整更为直观方便,所以没做此方面的设计。