| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 | package excelsimport (	"github.com/druidcaesa/gotool"	"github.com/xuri/excelize/v2"	"reflect"	"strconv")// 获取title头listfunc getTitle(list []map[string]string) []string {	titleList := make([]string, 0)	for _, item := range list {		for _, s := range item {			titleList = append(titleList, s)		}	}	return titleList}// ExportExcel 导出excelfunc ExportExcel(list []interface{}, title string) (error, *excelize.File) {	//获取标题	headerList, expList := ExcelCreate(list[0])	headers := getTitle(headerList)	// 默认存在第一个工作簿是 Sheet1 首字母要大写,否则会报错。	// 如果想额外的创建工作簿,可以使用,sheet2 := file.NewSheet("Sheet2"),工作簿的名称不区分大小写。	// 如果有多个工作簿,可以使用 file.SetActiveSheet(index) 来指定打开文件时focus到哪个工作簿	sheet1 := "Sheet1"	files := excelize.NewFile()	character := string(65 + len(headers) - 1)	/* -------------------- 第一行大标题 -------------------- */	// 设置行高	err := files.SetRowHeight(sheet1, 1, 25)	if err != nil {		return err, nil	}	// 合并单元格	err = files.MergeCell(sheet1, "A1", character+"1")	if err != nil {		return err, nil	}	// 设置单元格样式:对齐;字体,大小;单元格边框	styleTitle, _ := files.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},"font":{"bold":true,"italic":false,"family":"Calibri","size":16,"color":"#000000"},"border":[{"type":"left","color":"#3FAD08","style":0},{"type":"top","color":"#3FAD08","style":0},{"type":"bottom","color":"#3FAD08","style":2},{"type":"right","color":"#3FAD08","style":0}]}`)	err = files.SetCellStyle(sheet1, "A1", character+"1", styleTitle)	if err != nil {		return err, nil	}	err = files.SetCellValue(sheet1, "A1", title)	if err != nil {		return err, nil	}	/* -------------------- 字段标题 -------------------- */	styleHeader, _ := files.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},"font":{"bold":false,"italic":false,"family":"Calibri","size":10,"color":"#000000"}}`)	err = files.SetCellStyle(sheet1, "A2", character+"2", styleHeader)	if err != nil {		return err, nil	}	for k, v := range headers {		if k < 26 {			err = files.SetCellValue(sheet1, string(65+k)+"2", v)		} else {			err = files.SetCellValue(sheet1, "A"+string(65+k-26)+"2", v)		}		if err != nil {			return err, nil		}	}	// 设置最后一列宽度	err = files.SetColWidth(sheet1, "C", character, 20)	if err != nil {		return err, nil	}	// 冻结窗口:冻结第一行和第二行	err = files.SetPanes(sheet1, `{"freeze":true,"split":false,"x_split":0,"y_split":2}`)	if err != nil {		return err, nil	}	///* -------------------- 填充行数据 -------------------- */	line := 3	for _, v := range list {		var num = 0		lineChr := strconv.Itoa(line)		// 设置样式		err = files.SetCellStyle(sheet1, "A"+lineChr, character+lineChr, styleHeader)		if err != nil {			return err, nil		}		// 反射获取数据和类型		getValue := reflect.ValueOf(v)		getType := reflect.TypeOf(v)		n := getValue.NumField()		for i := 0; i < n; i++ {			val := getValue.Field(i)			name := getType.Field(i).Name			if !getIsTitle(name, headerList) {				continue			}			if num < 26 {				err = files.SetCellValue(sheet1, string(65+num)+lineChr, getExp(name, expList, val.Interface()))			} else {				err = files.SetCellValue(sheet1, "A"+string(65-26+num)+lineChr, getExp(name, expList, val.Interface()))			}			/*	err = files.SetCellValue(sheet1, string(65+num)+lineChr, getExp(name, expList, val.Interface()))*/			if err != nil {				return err, nil			}			num++		}		line++	}	return nil, files}func getIsTitle(name string, headerList []map[string]string) bool {	flag := false	for _, m := range headerList {		if gotool.StrUtils.HasNotEmpty(m[name]) {			flag = true		}	}	return flag}func getExp(name string, expList []map[string][]map[string]string, value interface{}) interface{} {	for _, m := range expList {		if len(m[name]) > 0 {			maps := m[name]			for _, m2 := range maps {				if gotool.StrUtils.HasNotEmpty(m2[interfaceToString(value)]) {					value = m2[interfaceToString(value)]				}			}		}	}	return value}func interfaceToString(inter interface{}) string {	switch inter.(type) {	case string:		return inter.(string)	case int:		return strconv.Itoa(inter.(int))	case int64:		return strconv.FormatInt(inter.(int64), 10)	default:		return inter.(string)	}}
 |