-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexcel.go
More file actions
134 lines (108 loc) · 2.71 KB
/
excel.go
File metadata and controls
134 lines (108 loc) · 2.71 KB
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
package main
import (
"encoding/json"
"fmt"
"github.com/xuri/excelize/v2"
)
type ExcelService struct{}
func NewExcelService() *ExcelService {
return &ExcelService{}
}
// WriteExcel writes data to an Excel file
func (es *ExcelService) WriteExcel(path string, dataJSON string, sheetName string, includeHeaders bool) error {
// Parse JSON data
var data []map[string]interface{}
if err := json.Unmarshal([]byte(dataJSON), &data); err != nil {
return fmt.Errorf("invalid JSON data: %w", err)
}
if len(data) == 0 {
return fmt.Errorf("no data to write")
}
// Create new Excel file
f := excelize.NewFile()
defer f.Close()
// Create or get sheet
if sheetName == "" {
sheetName = "Sheet1"
}
index, err := f.NewSheet(sheetName)
if err != nil {
return fmt.Errorf("failed to create sheet: %w", err)
}
f.SetActiveSheet(index)
// Get headers from first row
headers := make([]string, 0)
for key := range data[0] {
headers = append(headers, key)
}
row := 1
// Write headers if requested
if includeHeaders {
for col, header := range headers {
cell, _ := excelize.CoordinatesToCellName(col+1, row)
f.SetCellValue(sheetName, cell, header)
}
row++
}
// Write data rows
for _, record := range data {
for col, header := range headers {
cell, _ := excelize.CoordinatesToCellName(col+1, row)
value := record[header]
f.SetCellValue(sheetName, cell, value)
}
row++
}
// Auto-fit columns
for col := range headers {
colName, _ := excelize.ColumnNumberToName(col + 1)
f.SetColWidth(sheetName, colName, colName, 15)
}
// Save file
if err := f.SaveAs(path); err != nil {
return fmt.Errorf("failed to save Excel file: %w", err)
}
return nil
}
// ReadExcel reads data from an Excel file
func (es *ExcelService) ReadExcel(path string, sheetName string) (string, error) {
f, err := excelize.OpenFile(path)
if err != nil {
return "", fmt.Errorf("failed to open Excel file: %w", err)
}
defer f.Close()
// Get sheet name if not provided
if sheetName == "" {
sheetName = f.GetSheetName(0)
}
// Read all rows
rows, err := f.GetRows(sheetName)
if err != nil {
return "", fmt.Errorf("failed to read rows: %w", err)
}
if len(rows) == 0 {
return "[]", nil
}
// First row as headers
headers := rows[0]
// Convert to array of objects
var data []map[string]interface{}
for i := 1; i < len(rows); i++ {
row := rows[i]
record := make(map[string]interface{})
for j, header := range headers {
if j < len(row) {
record[header] = row[j]
} else {
record[header] = ""
}
}
data = append(data, record)
}
// Convert to JSON
jsonData, err := json.Marshal(data)
if err != nil {
return "", fmt.Errorf("failed to marshal data: %w", err)
}
return string(jsonData), nil
}