forked from pcarleton/sheets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcell.go
80 lines (61 loc) · 1.57 KB
/
cell.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
package sheets
import (
"fmt"
"strings"
)
const (
Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
type CellPos struct {
Row int
Col int
}
func (c CellPos) A1Notation() string {
return fmt.Sprintf("%s%d", aRangeLetter(c.Col), c.Row+1)
}
func (c CellPos) RangeForData(data [][]interface{}) CellRange {
bottomLeft := CellPos{c.Row + len(data) - 1, c.Col + len(data[0]) - 1}
return CellRange{Start: c, End: bottomLeft}
}
type CellRange struct {
Start CellPos
End CellPos
}
func (a CellRange) String() string {
return fmt.Sprintf("%s:%s", a.Start.A1Notation(), a.End.A1Notation())
}
type SheetRange struct {
SheetName string
Range CellRange
}
func (s SheetRange) String() string {
return fmt.Sprintf("%s!%s", s.SheetName, s.Range.String())
}
func DefaultRange(data [][]string) CellRange {
bottomLeft := CellPos{len(data), len(data[0])}
return CellRange{CellPos{}, bottomLeft}
}
func aRangeLetter(num int) string {
base := len(Alphabet)
start := num
numDigits := 1
for start >= base {
// A1 is like base 26 with letters instead of digits,
// except that "A", "AA", and "AAA" would all be 0 in base 26
// and in A1 they are different numbers.
// Subtract the base here so it behaves more like base 26.
start -= base
numDigits += 1
base *= len(Alphabet)
}
base /= len(Alphabet)
digits := make([]string, numDigits)
for i := 0; i < numDigits-1; i += 1 {
idx := start / base
digits[i] = Alphabet[idx : idx+1]
start = start - (idx * base)
base = base / len(Alphabet)
}
digits[numDigits-1] = Alphabet[start : start+1]
return strings.Join(digits, "")
}