-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathreadxlsx.go
98 lines (87 loc) · 1.8 KB
/
readxlsx.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
package streamxlsx
import (
"archive/zip"
"bytes"
"encoding/xml"
"errors"
"fmt"
)
// TestFile is used to test the package.
// It doesn't implement a full reader.
type TestFile struct {
Sheets []TestSheet
}
type TestSheet struct {
Name string
Cells []TestCell
}
type TestCell struct {
Ref string
Type string
Value string
Style int
}
func TestParse(b []byte) (*TestFile, error) {
z, err := zip.NewReader(bytes.NewReader(b), int64(len(b)))
if err != nil {
return nil, err
}
file := TestFile{}
var rels relationshipsXML
if err := readXML(z, "xl/_rels/workbook.xml.rels", &rels); err != nil {
return nil, err
}
var workbook workbookXML
if err := readXML(z, "xl/workbook.xml", &workbook); err != nil {
return nil, err
}
for i, sheet := range workbook.Sheets {
s, err := readSheet(z, i+1, sheet.Name)
if err != nil {
return nil, err
}
file.Sheets = append(file.Sheets, *s)
}
return &file, nil
}
func readSheet(z *zip.Reader, id int, name string) (*TestSheet, error) {
var s worksheetXML
if err := readXML(z, fmt.Sprintf("xl/worksheets/sheet%d.xml", id), &s); err != nil {
return nil, err
}
var cells []TestCell
for _, row := range s.Rows {
for _, cell := range row.Cells {
v := cell.Value
if cell.InlineString != nil {
v = *cell.InlineString
}
style := 0
if cell.Style != nil {
style = *cell.Style
}
cells = append(cells, TestCell{
Ref: cell.Ref,
Type: cell.Type,
Value: v,
Style: style,
})
}
}
return &TestSheet{
Name: name,
Cells: cells,
}, nil
}
func readXML(z *zip.Reader, filename string, dest interface{}) error {
for _, f := range z.File {
if f.Name == filename {
fh, err := f.Open()
if err != nil {
return err
}
return xml.NewDecoder(fh).Decode(dest)
}
}
return errors.New("file not found")
}