excelutils.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package excelutils
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/pkg/errors"
  6. "github.com/xuri/excelize/v2"
  7. "log"
  8. "reflect"
  9. "strconv"
  10. )
  11. func ExportExcel(titleList []string, data []interface{}, sheetName string) ([]byte, error) {
  12. f := excelize.NewFile()
  13. defer func() {
  14. err := f.Close()
  15. if err != nil {
  16. log.Println("ExportExcel Close File:", err.Error())
  17. }
  18. }()
  19. err := f.SetSheetName("Sheet1", sheetName)
  20. if err != nil {
  21. return nil, err
  22. }
  23. header := make([]string, 0)
  24. for _, v := range titleList {
  25. header = append(header, v)
  26. }
  27. rowStyleID, _ := f.NewStyle(&excelize.Style{
  28. Font: &excelize.Font{
  29. Family: "arial",
  30. Size: 13,
  31. Color: "#666666",
  32. },
  33. Alignment: &excelize.Alignment{
  34. Horizontal: "center",
  35. Vertical: "center",
  36. },
  37. })
  38. err = f.SetSheetRow(sheetName, "A1", &header)
  39. if err != nil {
  40. return nil, err
  41. }
  42. err = f.SetRowHeight(sheetName, 1, 30)
  43. if err != nil {
  44. return nil, err
  45. }
  46. length := len(titleList)
  47. headStyle, err := generateExcelColumnIndexes(length)
  48. if err != nil {
  49. return nil, err
  50. }
  51. var lastRow string
  52. var widthRow string
  53. for k, v := range headStyle {
  54. if k == length-1 {
  55. lastRow = fmt.Sprintf("%s1", v)
  56. widthRow = v
  57. }
  58. }
  59. if err := f.SetColWidth(sheetName, "A", widthRow, 20); err != nil {
  60. return nil, err
  61. }
  62. rowNum := 1
  63. _ = f.SetCellStyle(sheetName, fmt.Sprintf("A%d", 1), fmt.Sprintf("%s", lastRow), rowStyleID)
  64. for _, v := range data {
  65. t := reflect.TypeOf(v)
  66. value := reflect.ValueOf(v)
  67. row := make([]interface{}, 0)
  68. for l := 0; l < t.NumField(); l++ {
  69. val := value.Field(l).Interface()
  70. row = append(row, val)
  71. }
  72. rowNum++
  73. err := f.SetSheetRow(sheetName, "A"+strconv.Itoa(rowNum), &row)
  74. if err != nil {
  75. return nil, err
  76. }
  77. }
  78. buffer := &bytes.Buffer{}
  79. err = f.Write(buffer)
  80. if err != nil {
  81. return nil, err
  82. }
  83. return buffer.Bytes(), nil
  84. }
  85. func generateExcelColumnIndexes(columnNum int) ([]string, error) {
  86. if columnNum > 26*27 {
  87. return nil, errors.New("columnNum is too large")
  88. }
  89. indexes := make([]string, 0)
  90. for currentColumn := 1; currentColumn <= columnNum; currentColumn++ {
  91. var index string
  92. if currentColumn%26 == 0 {
  93. index = "Z"
  94. } else {
  95. index = string(rune('A' + currentColumn%26 - 1))
  96. }
  97. if currentColumn <= 26 {
  98. indexes = append(indexes, index)
  99. continue
  100. }
  101. upperLetterIndex := currentColumn / 26
  102. if upperLetterIndex%26 == 0 && currentColumn != 26*26 {
  103. index = "Z" + index
  104. } else {
  105. if currentColumn%26 == 0 {
  106. index = string(rune('A'+upperLetterIndex-2)) + "Z"
  107. } else {
  108. index = string(rune('A'+upperLetterIndex%26-1)) + index
  109. }
  110. }
  111. indexes = append(indexes, index)
  112. }
  113. return indexes, nil
  114. }