forked from shakinm/xlsReader
/
format.go
127 lines (100 loc) · 3.29 KB
/
format.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
package record
import (
"bytes"
"fmt"
"strconv"
"strings"
"github.com/ezhdanovskiy/fmtdate"
"github.com/ezhdanovskiy/xlsReader/helpers"
"github.com/ezhdanovskiy/xlsReader/xls/structure"
)
//FORMAT: Number Format
var FormatRecord = []byte{0x1E, 0x04} //(41Eh)
/*
The FORMAT record describes a number format in the workbook.
All the FORMAT records should appear together in a BIFF file. The order of FORMAT
records in an existing BIFF file should not be changed. It is possible to write custom
number formats in a file, but they should be added at the end of the existing FORMAT
records.
Record Data
Offset Field Name Size Contents
------------------------------------------------
4 ifmt 2 Format index code (for internal use only)
6 cch 2 Length of the string
7 grbit 1 Option Flags (described in Unicode Strings in BIFF8 section)
8 rgb var Array of string characters
Excel uses the ifmt structure to identify built-in formats when it reads a file that was
created by a different localized version. For more information about built-in formats,
see "XF".
*/
type Format struct {
ifmt [2]byte
cch [2]byte
grbit [1]byte
rgb []byte
vers []byte
stFormat structure.XLUnicodeRichExtendedString
}
func (r *Format) Read(stream []byte, vers []byte) {
r.vers = vers
if bytes.Compare(vers, FlagBIFF8) == 0 {
copy(r.ifmt[:], stream[0:2])
_ = r.stFormat.Read(stream[2:])
} else {
copy(r.ifmt[:], stream[:2])
copy(r.cch[:], stream[2:4])
r.rgb = make([]byte, helpers.BytesToUint16(r.cch[:]))
copy(r.rgb[:], stream[4:])
}
}
func (r *Format) String() string {
if bytes.Compare(r.vers, FlagBIFF8) == 0 {
return r.stFormat.String()
}
strLen := helpers.BytesToUint16(r.cch[:])
return strings.TrimSpace(string(decodeWindows1251(bytes.Trim(r.rgb[:int(strLen)], "\x00"))))
}
func (r *Format) GetIndex() int {
return int(helpers.BytesToUint16(r.ifmt[:]))
}
func (r *Format) GetFormatString(data structure.CellData) string {
if r.GetIndex() >= 164 {
if data.GetType() == "*record.LabelSSt" {
return data.GetString()
}
if data.GetType() == "*record.Label" {
return data.GetString()
}
if data.GetType() == "*record.FakeBlank" {
return data.GetString()
}
if data.GetType() == "*record.Blank" {
return data.GetString()
}
if data.GetType() == "*record.BoolErr" {
return data.GetString()
}
if data.GetType() == "*record.Number" || data.GetType() == "*record.Rk" {
if r.String() == "General" || r.String() == "@" {
return strconv.FormatFloat(data.GetFloat64(), 'f', -1, 64)
} else if strings.Contains(r.String(), "%") {
return fmt.Sprintf("%.2f", data.GetFloat64()*100) + "%"
} else if strings.Contains(r.String(), "#") || strings.Contains(r.String(), ".00") {
return fmt.Sprintf("%.2f", data.GetFloat64())
} else if strings.Contains(r.String(), "0") {
return fmt.Sprintf("%.f", data.GetFloat64())
} else {
t := helpers.TimeFromExcelTime(data.GetFloat64(), false)
dateFormat := strings.ReplaceAll(r.String(), "HH:MM:SS", "hh:mm:ss")
dateFormat = strings.ReplaceAll(dateFormat, "\\", "")
return fmtdate.Format(dateFormat, t)
}
}
return data.GetString()
} else {
if data.GetType() == "*record.Number" {
return strconv.FormatFloat(data.GetFloat64(), 'f', -1, 64)
}
}
return data.GetString()
}