123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- 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
- }
|