162 lines
6.0 KiB
Markdown
162 lines
6.0 KiB
Markdown
# excel文件生成器
|
||
## excel文件生成器简介
|
||
此模块提供了通过`.xlsx`格式的excel模板文件,创建文件并自动添加数据的方法。
|
||
此模块通过设计模式,在"github.com/xuri/excelize/v2"的基础上封装了`ExcelCreator`这一泛型的方法。适用于快速开发报表导出功能。
|
||
|
||
### 基本使用示例
|
||
```go
|
||
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. 定义工作簿数据结构
|
||
注意事项:
|
||
1. 结构体字段顺序要与工作簿的表头顺序一一对应、命名规则随意;
|
||
2. json标签用于数据的转换,同时也便于将结构体直接作为接口请求参数来使用;没有json标签时,数据将会被忽略;
|
||
```go
|
||
type Sheet1 struct {
|
||
Xid int `json:"xid"`
|
||
Name string `json:"name"`
|
||
Age int `json:"age"`
|
||
}
|
||
```
|
||
### 3. 准备数据,实例化sheet对象
|
||
数据类型至此结构体和切片<br/>
|
||
`NewSheet`方法的第一个参数是工作簿名称,需要与模板文件中的对应,不然导出数据时会报错
|
||
```go
|
||
//准备数据
|
||
var sheet1Data = []Sheet1Define{
|
||
{1, "张三", 16},
|
||
{2, "黑猫警长", 18},
|
||
}
|
||
//实例化sheet对象
|
||
var sheet1 = excel.NewSheet("Sheet1", &sheet1Data)
|
||
```
|
||
### 4 生成excel文件
|
||
### 4.1 直接生成文件
|
||
如果你不需要什么额外操作,只想直接生成excel文件,那么可以直接调用这个方法
|
||
```go
|
||
//定义后缀名生成器,如果不需要可以传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`
|
||
```go
|
||
|
||
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 新增工作簿
|
||
如果工作簿已存在,数据会组合而不是覆盖
|
||
```go
|
||
var err = exCreator.SheetsAdd(sheet_2)
|
||
```
|
||
### 4.2.3 删除工作簿
|
||
```go
|
||
var err = exCreator.SheetsDelete(sheet_2.SheetName())
|
||
```
|
||
|
||
### 4.2.5 取出工作簿map和缓存数据
|
||
工作簿存储在`ExcelCreator.Sheets`中,存储结构为`map[string][]sheet`。string即工作簿名称。取出后可以进行任意的操作
|
||
```go
|
||
var sheets = exCreator.Sheets
|
||
datas:= sheets["Sheet1"].GetDatas
|
||
//do somthing...
|
||
```
|
||
|
||
### 4.2.6 将数据生成到文件
|
||
```go
|
||
path,fileName, err := exCreator.WriteToExcel()
|
||
if err != nil {
|
||
fmt.Println(err.Error())
|
||
} else {
|
||
fmt.Println(path)
|
||
fmt.Println(fileName)
|
||
}
|
||
```
|
||
|
||
## 相关问题
|
||
### 1. 为什么不支持通过代码直接生成表头?
|
||
鉴于在部分场景下,表头格式比较复杂,且通过代码生成灵活较度差,单元格格式通过代码设置比较繁琐。相比较下,没有直接创建excel文件模板来调整更为直观方便,所以没做此方面的设计。
|