create.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package excelutil
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "github.com/xuri/excelize/v2"
  7. "io"
  8. "time"
  9. "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/errors"
  10. )
  11. func ExportExcel(ctx context.Context, titles []interface{}, values [][]interface{}, cellFunc ExcelCellOptionFunc, opts ...ExcelOptionFunc) (io.Reader, error) {
  12. if len(titles) == 0 {
  13. return nil, errors.New("表头为空")
  14. }
  15. file := excelize.NewFile()
  16. defer func() {
  17. if err := file.Close(); err != nil {
  18. fmt.Println(err)
  19. }
  20. }()
  21. streamWriter, err := file.NewStreamWriter("Sheet1")
  22. if err != nil {
  23. return nil, errors.WithStack(err)
  24. }
  25. for _, opt := range opts {
  26. if err = opt(file, streamWriter); err != nil {
  27. return nil, err
  28. }
  29. }
  30. // 写入标题
  31. titleStyleID, err := getDefaultTitleStyleId(file)
  32. if err != nil {
  33. return nil, errors.WithStackOnce(err)
  34. }
  35. for i, v := range titles {
  36. cell := excelize.Cell{}
  37. if val, ok := v.(excelize.Cell); ok {
  38. cell = val
  39. } else {
  40. cell = excelize.Cell{StyleID: titleStyleID, Value: v}
  41. }
  42. if cellFunc != nil {
  43. if err = cellFunc(0, i, &cell); err != nil {
  44. return nil, errors.WithStack(err)
  45. }
  46. }
  47. titles[i] = cell
  48. }
  49. if err = streamWriter.SetRow("A1", titles, excelize.RowOpts{Height: 20}); err != nil {
  50. return nil, errors.WithStack(err)
  51. }
  52. // 写入内容
  53. valueStyleID, err := GetDefaultValueStyleId(file)
  54. if err != nil {
  55. return nil, errors.WithStackOnce(err)
  56. }
  57. timeStyleID, err := getDefaultTimeStyleId(file)
  58. if err != nil {
  59. return nil, errors.WithStackOnce(err)
  60. }
  61. for rowID := 0; rowID < len(values); rowID++ {
  62. row := values[rowID]
  63. for i, v := range row {
  64. cell := excelize.Cell{}
  65. if val, ok := v.(excelize.Cell); ok {
  66. cell = val
  67. } else if _, ok := v.(time.Time); ok {
  68. cell = excelize.Cell{StyleID: timeStyleID, Value: v}
  69. } else {
  70. cell = excelize.Cell{StyleID: valueStyleID, Value: v}
  71. }
  72. if cellFunc != nil {
  73. if err = cellFunc(rowID+1, i, &cell); err != nil {
  74. return nil, errors.WithStack(err)
  75. }
  76. }
  77. row[i] = cell
  78. }
  79. cell, _ := excelize.CoordinatesToCellName(1, rowID+2)
  80. if err := streamWriter.SetRow(cell, row); err != nil {
  81. return nil, errors.WithStack(err)
  82. }
  83. }
  84. if err := streamWriter.Flush(); err != nil {
  85. return nil, errors.WithStack(err)
  86. }
  87. buf := bytes.NewBuffer([]byte{})
  88. if err = file.Write(buf); err != nil {
  89. return nil, errors.WithStack(err)
  90. }
  91. return buf, nil
  92. }
  93. func getDefaultTitleStyleId(file *excelize.File) (int, error) {
  94. styleID, err := file.NewStyle(&excelize.Style{
  95. // 标题加粗
  96. Font: &excelize.Font{
  97. Bold: true,
  98. Color: "FFFFFF",
  99. },
  100. // 设置边框
  101. Border: []excelize.Border{
  102. {Type: "left", Color: "000000", Style: 1},
  103. {Type: "top", Color: "000000", Style: 1},
  104. {Type: "bottom", Color: "000000", Style: 1},
  105. {Type: "right", Color: "000000", Style: 1},
  106. },
  107. // 图案填充-绿色
  108. Fill: excelize.Fill{
  109. Pattern: 1,
  110. Type: "pattern",
  111. Color: []string{"2EA121"},
  112. },
  113. // 居中
  114. Alignment: &excelize.Alignment{
  115. // 水平对齐:
  116. Horizontal: "center",
  117. // 垂直对齐
  118. Vertical: "center",
  119. },
  120. })
  121. return styleID, err
  122. }
  123. func GetYellowStyleId(file *excelize.File) (int, error) {
  124. styleID, err := file.NewStyle(&excelize.Style{
  125. // 标题加粗
  126. Font: &excelize.Font{
  127. Bold: true,
  128. Color: "FFFFFF",
  129. },
  130. // 设置边框
  131. Border: []excelize.Border{
  132. {Type: "left", Color: "000000", Style: 1},
  133. {Type: "top", Color: "000000", Style: 1},
  134. {Type: "bottom", Color: "000000", Style: 1},
  135. {Type: "right", Color: "000000", Style: 1},
  136. },
  137. // 图案填充-黄色
  138. Fill: excelize.Fill{
  139. Pattern: 1,
  140. Type: "pattern",
  141. Color: []string{"FFC60A"},
  142. },
  143. // 居中
  144. Alignment: &excelize.Alignment{
  145. // 水平对齐:
  146. Horizontal: "center",
  147. // 垂直对齐
  148. Vertical: "center",
  149. },
  150. })
  151. return styleID, err
  152. }
  153. func GetDefaultValueStyleId(file *excelize.File) (int, error) {
  154. styleID, err := file.NewStyle(&excelize.Style{
  155. // 设置边框
  156. //Border: []excelize.Border{
  157. // {Type: "left", Color: "000000", Style: 1},
  158. // {Type: "top", Color: "000000", Style: 1},
  159. // {Type: "bottom", Color: "000000", Style: 1},
  160. // {Type: "right", Color: "000000", Style: 1},
  161. //},
  162. // 居中
  163. Alignment: &excelize.Alignment{
  164. // 水平对齐:
  165. Horizontal: "center",
  166. // 垂直对齐
  167. Vertical: "center",
  168. },
  169. })
  170. return styleID, err
  171. }
  172. func getDefaultTimeStyleId(file *excelize.File) (int, error) {
  173. styleID, err := file.NewStyle(&excelize.Style{
  174. // 设置边框
  175. Border: []excelize.Border{
  176. {Type: "left", Color: "000000", Style: 1},
  177. {Type: "top", Color: "000000", Style: 1},
  178. {Type: "bottom", Color: "000000", Style: 1},
  179. {Type: "right", Color: "000000", Style: 1},
  180. },
  181. // 居中
  182. Alignment: &excelize.Alignment{
  183. // 水平对齐:
  184. Horizontal: "center",
  185. // 垂直对齐
  186. Vertical: "center",
  187. },
  188. NumFmt: 22,
  189. })
  190. return styleID, err
  191. }
  192. type ExcelOptionFunc func(*excelize.File, *excelize.StreamWriter) error
  193. type ExcelCellOptionFunc func(rowIndex, cellIndex int, cell *excelize.Cell) error