-
Notifications
You must be signed in to change notification settings - Fork 0
/
json2excel.go
136 lines (123 loc) · 3.04 KB
/
json2excel.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package json2excel
import (
"bytes"
"errors"
"fmt"
"io"
"os"
"regexp"
"github.com/xuri/excelize/v2"
)
var ErrNoDataForExcel = errors.New("no data available to generate the Excel")
var ErrNilRequestProvided = errors.New("no valid request has been provided")
type JSON2ExcelConverter interface {
Excel(req *request) (io.Reader, error)
SaveExcel(req *request, filePath string) error
}
func NewJSON2ExcelConverter() JSON2ExcelConverter {
return &j2x{}
}
type j2x struct{}
func (*j2x) removeNumbers(input string) string {
re := regexp.MustCompile("[0-9]")
result := re.ReplaceAllString(input, "")
return result
}
func (x *j2x) WriteHeader(file *excelize.File, sheetName string, headers []string) (
startcell string, endcell string, err error) {
for i, header := range headers {
col := fmt.Sprintf("%c", 'A'+i)
cell := fmt.Sprintf("%s1", col)
if err = file.SetCellValue(sheetName, cell, header); err != nil {
return
}
if i == 0 {
startcell = cell
}
endcell = cell
}
var startCol = x.removeNumbers(startcell)
var endCol = x.removeNumbers(endcell)
if err := file.SetColWidth(sheetName, startCol, endCol, 30); err != nil {
return startcell, endcell, err
}
style, err := file.NewStyle(&excelize.Style{
Font: &excelize.Font{Bold: true},
})
if err != nil {
return startcell, endcell, err
}
if err = file.SetCellStyle(sheetName, startcell, endcell, style); err != nil {
return startcell, endcell, err
}
return
}
func (*j2x) WriteData(file *excelize.File, sheetName string, data [][]any) (startcell string, endcell string, err error) {
for i, rowData := range data {
rowIndex := i + 2
for j, cellData := range rowData {
cell := fmt.Sprintf("%c%d", 'A'+j, rowIndex)
if i == 0 && j == 0 {
startcell = cell
}
if err = file.SetCellStr(sheetName, cell, fmt.Sprint(cellData)); err != nil {
return
}
endcell = cell
}
}
return
}
func (jx *j2x) Excel(req *request) (io.Reader, error) {
if req == nil {
return nil, ErrNilRequestProvided
}
if len(req.Data.Columns) == 0 {
return nil, ErrNoDataForExcel
}
file := excelize.NewFile()
defer file.Close()
var sheetName = "Sheet1"
_, err := file.NewSheet(sheetName)
if err != nil {
return nil, err
}
startCell, _, err := jx.WriteHeader(file, sheetName, req.Data.Columns)
if err != nil {
return nil, err
}
_, endCell, err := jx.WriteData(file, sheetName, req.Data.RowsValues)
if err != nil {
return nil, err
}
if err := file.AddTable(sheetName, &excelize.Table{
Range: fmt.Sprintf("%s:%s", startCell, endCell),
Name: "table",
StyleName: "TableStyleMedium2",
}); err != nil {
return nil, err
}
var buff bytes.Buffer
if err := file.Write(&buff); err != nil {
return nil, err
}
return &buff, nil
}
func (jx *j2x) SaveExcel(req *request, nameFile string) error {
if req == nil {
return ErrNilRequestProvided
}
excel, err := jx.Excel(req)
if err != nil {
return err
}
file, err := os.Create(nameFile)
if err != nil {
return err
}
defer file.Close()
if _, err := io.Copy(file, excel); err != nil {
return err
}
return nil
}