134 lines
4.1 KiB
Go
134 lines
4.1 KiB
Go
package excel
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"git.rosy.net.cn/baseapi/utils"
|
||
"git.rosy.net.cn/jx-callback/globals"
|
||
"github.com/360EntSecGroup-Skylar/excelize"
|
||
"io"
|
||
"reflect"
|
||
)
|
||
|
||
type Obj2ExcelSheetConfig struct {
|
||
Title string
|
||
Data interface{}
|
||
CaptionList []string
|
||
}
|
||
|
||
func Obj2Excel(sheetList []*Obj2ExcelSheetConfig) []byte {
|
||
globals.SugarLogger.Debug("Obj2Excel")
|
||
excelFile := excelize.NewFile()
|
||
//for sheetIndex, sheetConfig := range sheetList {
|
||
for _, sheetConfig := range sheetList {
|
||
obj := sheetConfig.Data
|
||
|
||
typeInfo := reflect.TypeOf(obj)
|
||
if typeInfo.Kind() == reflect.Ptr {
|
||
typeInfo = typeInfo.Elem()
|
||
}
|
||
if typeInfo.Kind() != reflect.Slice {
|
||
panic("obj must be slice type")
|
||
}
|
||
typeInfo = typeInfo.Elem()
|
||
if typeInfo.Kind() == reflect.Ptr {
|
||
typeInfo = typeInfo.Elem()
|
||
}
|
||
if typeInfo.Kind() != reflect.Struct && typeInfo.Kind() != reflect.Map {
|
||
panic("obj must be slice of map or struct")
|
||
}
|
||
|
||
valueInfo := reflect.Indirect(reflect.ValueOf(obj))
|
||
/*因爲默認是Sheet1,所以直接賦值就叫sheet1,然後再改名字就行了,不然會默認多一頁空白頁為sheet1*/
|
||
//if sheetIndex == 0 {
|
||
index := excelFile.NewSheet("Sheet1")
|
||
// sheetName := excelFile.GetSheetName(1)
|
||
excelFile.SetSheetName("Sheet1", sheetConfig.Title)
|
||
//} else {
|
||
// excelFile.NewSheet(sheetConfig.Title)
|
||
//}
|
||
isMemberStruct := typeInfo.Kind() == reflect.Struct
|
||
colWithList := make([]float64, len(sheetConfig.CaptionList))
|
||
if isMemberStruct {
|
||
var indexSlice [][]int
|
||
name2IndexMap := utils.GetStructNameIndex(typeInfo, "json")
|
||
for col, name := range sheetConfig.CaptionList {
|
||
if colWith := float64(len(name)); colWith > colWithList[col] {
|
||
colWithList[col] = colWith
|
||
}
|
||
if _, ok := name2IndexMap[name]; !ok {
|
||
panic(fmt.Sprintf("col:%s不能找到相应的数据", name))
|
||
}
|
||
indexSlice = append(indexSlice, name2IndexMap[name])
|
||
excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name)
|
||
}
|
||
for i := 0; i < valueInfo.Len(); i++ {
|
||
for col, index := range indexSlice {
|
||
str := fmt.Sprint(reflect.Indirect(valueInfo.Index(i)).FieldByIndex(index).Interface())
|
||
//// if colWith := float64(len(str)); colWith > colWithList[col] {
|
||
//// colWithList[col] = colWith
|
||
//// }
|
||
excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), str)
|
||
}
|
||
}
|
||
} else {
|
||
var name2IndexMap map[string]int
|
||
if valueInfo.Len() > 0 {
|
||
oneData := valueInfo.Index(0).Interface().(map[string]interface{})
|
||
name2IndexMap = make(map[string]int)
|
||
for k := range oneData {
|
||
name2IndexMap[k] = 1
|
||
}
|
||
}
|
||
for col, name := range sheetConfig.CaptionList {
|
||
if colWith := float64(len(name)); colWith > colWithList[col] {
|
||
colWithList[col] = colWith
|
||
}
|
||
if name2IndexMap != nil {
|
||
if _, ok := name2IndexMap[name]; !ok {
|
||
panic(fmt.Sprintf("col:%s不能找到相应的数据", name))
|
||
}
|
||
}
|
||
excelFile.SetCellStr(sheetConfig.Title, genAxis(0, col), name)
|
||
}
|
||
for i := 0; i < valueInfo.Len(); i++ {
|
||
mapData := valueInfo.Index(i).Interface().(map[string]interface{})
|
||
for col, name := range sheetConfig.CaptionList {
|
||
str := fmt.Sprint(mapData[name])
|
||
// if colWith := float64(len(str)); colWith > colWithList[col] {
|
||
// colWithList[col] = colWith
|
||
// }
|
||
excelFile.SetCellStr(sheetConfig.Title, genAxis(i+1, col), str)
|
||
}
|
||
}
|
||
}
|
||
// for col := range sheetConfig.CaptionList {
|
||
// colName, _ := excelize.ColumnNumberToName(col + 1)
|
||
// excelFile.SetColWidth(sheetConfig.Title, colName, colName, colWithList[col])
|
||
// }
|
||
excelFile.SetActiveSheet(index)
|
||
}
|
||
buf := &bytes.Buffer{}
|
||
excelFile.Write(buf)
|
||
return buf.Bytes()
|
||
}
|
||
|
||
func Excel2Slice(reader io.Reader) (contents map[string][][]string) {
|
||
globals.SugarLogger.Debug("Excel2Slice")
|
||
if excelFile, err := excelize.OpenReader(reader); err == nil {
|
||
contents = make(map[string][][]string)
|
||
for _, v := range excelFile.GetSheetMap() {
|
||
contents[v], _ = excelFile.GetRows(v)
|
||
}
|
||
}
|
||
return contents
|
||
}
|
||
|
||
func genAxis(row, col int) (pos string) {
|
||
pos, err := excelize.CoordinatesToCellName(col+1, row+1)
|
||
if err != nil {
|
||
globals.SugarLogger.Debugf("err:%v", err)
|
||
}
|
||
return pos
|
||
}
|