package excel import ( "fmt" "net/url" "reflect" "strconv" "github.com/gin-gonic/gin" "github.com/xuri/excelize/v2" ) type ExcelServer struct { File *excelize.File SheetName string // 可定义默认sheet名称 Height float64 // 默认行高度 } // ExportToPath 导出基本的表格 func (l *ExcelServer) 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 *ExcelServer) ExportToWeb(params []map[string]string, data []map[string]interface{}, c *gin.Context) { l.Export(params, data) buffer, _ := l.File.WriteToBuffer() //设置文件类型 c.Header("Content-Type", "application/vnd.ms-excel;charset=utf8") //设置文件名称 c.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(createFileName())) _, _ = c.Writer.Write(buffer.Bytes()) } //设置首行 func (l *ExcelServer) writeTop(params []map[string]string) { topStyle, _ := l.File.NewStyle(&excelize.Style{ Font: &excelize.Font{Bold: true}, Alignment: &excelize.Alignment{ Horizontal: "center", Vertical: "center", }, Protection: nil, NumFmt: 0, DecimalPlaces: 0, CustomNumFmt: nil, Lang: "", NegRed: false, }) 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 *ExcelServer) writeData(params []map[string]string, data []map[string]interface{}) { lineStyle, _ := l.File.NewStyle(&excelize.Style{Alignment: &excelize.Alignment{ Horizontal: "center", Vertical: "center", }}) //数据写入 var j = 2 //数据开始行数 for i, val := range data { //设置行高 _ = l.File.SetRowHeight(l.SheetName, i+1, l.Height) //逐列写入 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, l.Height) } func (l *ExcelServer) Export(params []map[string]string, data []map[string]interface{}) { l.writeTop(params) l.writeData(params, data) } // ExportExcelByStruct excel导出(数据源为Struct) []interface{} func (l *ExcelServer) ExportExcelByStruct(titleList []string, data []interface{}, fileName string, sheetName string, c *gin.Context) error { l.File.SetSheetName("Sheet1", sheetName) header := make([]string, 0) for _, v := range titleList { header = append(header, v) } rowStyleID, _ := l.File.NewStyle(&excelize.Style{ Font: &excelize.Font{ Family: "arial", Size: 13, Color: "#666666", }, Alignment: &excelize.Alignment{ Horizontal: "center", Vertical: "center", }, }) _ = l.File.SetSheetRow(sheetName, "A1", &header) _ = l.File.SetRowHeight("Sheet1", 1, 30) length := len(titleList) headStyle := Letter(length) var lastRow string var widthRow string for k, v := range headStyle { if k == length-1 { lastRow = fmt.Sprintf("%s1", v) widthRow = v } } if err := l.File.SetColWidth(sheetName, "A", widthRow, 30); err != nil { fmt.Print("错误--", err.Error()) } rowNum := 1 for _, v := range data { t := reflect.TypeOf(v) fmt.Print("--ttt--", t.NumField()) value := reflect.ValueOf(v) row := make([]interface { }, 0) for l := 0; l < t.NumField(); l++ { val := value.Field(l).Interface() row = append(row, val) } rowNum++ err := l.File.SetSheetRow(sheetName, "A"+strconv.Itoa(rowNum), &row) _ = l.File.SetCellStyle(sheetName, fmt.Sprintf("A%d", rowNum), fmt.Sprintf("%s", lastRow), rowStyleID) if err != nil { return err } } disposition := fmt.Sprintf("attachment; filename=%s.xlsx", url.QueryEscape(fileName)) c.Writer.Header().Set("Content-Type", "application/octet-stream") c.Writer.Header().Set("Content-Disposition", disposition) c.Writer.Header().Set("Content-Transfer-Encoding", "binary") c.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Disposition") return l.File.Write(c.Writer) } // Letter 遍历a-z func Letter(length int) []string { var str []string for i := 0; i < length; i++ { str = append(str, string(rune('A'+i))) } return str }