1
+ const addressRegex = / ^ [ A - Z ] + \d + $ / ;
1
2
// =========================================================================
2
3
// Column Letter to Number conversion
3
4
const colCache = {
@@ -29,6 +30,7 @@ const colCache = {
29
30
'Y' ,
30
31
'Z' ,
31
32
] ,
33
+ _l2nFill : 0 ,
32
34
_l2n : { } ,
33
35
_n2l : [ ] ,
34
36
_level ( n ) {
@@ -48,18 +50,20 @@ const colCache = {
48
50
let l3 ;
49
51
let n = 1 ;
50
52
if ( level >= 4 ) {
51
- throw new Error ( ` Out of bounds. Excel supports columns from 1 to 16384` ) ;
53
+ throw new Error ( ' Out of bounds. Excel supports columns from 1 to 16384' ) ;
52
54
}
53
- if ( level >= 1 ) {
55
+ if ( this . _l2nFill < 1 && level >= 1 ) {
54
56
while ( n <= 26 ) {
55
57
c = this . _dictionary [ n - 1 ] ;
56
58
this . _n2l [ n ] = c ;
57
59
this . _l2n [ c ] = n ;
58
60
n ++ ;
59
61
}
62
+ this . _l2nFill = 1 ;
60
63
}
61
- if ( level >= 2 ) {
62
- while ( n <= 26 + 26 * 26 ) {
64
+ if ( this . _l2nFill < 2 && level >= 2 ) {
65
+ n = 27 ;
66
+ while ( n <= 26 + ( 26 * 26 ) ) {
63
67
v = n - ( 26 + 1 ) ;
64
68
l1 = v % 26 ;
65
69
l2 = Math . floor ( v / 26 ) ;
@@ -68,10 +72,12 @@ const colCache = {
68
72
this . _l2n [ c ] = n ;
69
73
n ++ ;
70
74
}
75
+ this . _l2nFill = 2 ;
71
76
}
72
- if ( level >= 3 ) {
77
+ if ( this . _l2nFill < 3 && level >= 3 ) {
78
+ n = 26 + ( 26 * 26 ) + 1 ;
73
79
while ( n <= 16384 ) {
74
- v = n - ( 26 * 26 + 26 + 1 ) ;
80
+ v = n - ( ( 26 * 26 ) + 26 + 1 ) ;
75
81
l1 = v % 26 ;
76
82
l2 = Math . floor ( v / 26 ) % 26 ;
77
83
l3 = Math . floor ( v / ( 26 * 26 ) ) ;
@@ -80,6 +86,7 @@ const colCache = {
80
86
this . _l2n [ c ] = n ;
81
87
n ++ ;
82
88
}
89
+ this . _l2nFill = 3 ;
83
90
}
84
91
} ,
85
92
l2n ( l ) {
@@ -107,41 +114,63 @@ const colCache = {
107
114
108
115
// check if value looks like an address
109
116
validateAddress ( value ) {
110
- if ( ! value . match ( / ^ [ A - Z ] + \d + $ / ) ) {
117
+ if ( ! addressRegex . test ( value ) ) {
111
118
throw new Error ( `Invalid Address: ${ value } ` ) ;
112
119
}
113
120
return true ;
114
121
} ,
115
122
116
123
// convert address string into structure
117
124
decodeAddress ( value ) {
118
- const addr = this . _hash [ value ] ;
125
+ const addr = value . length < 5 && this . _hash [ value ] ;
119
126
if ( addr ) {
120
127
return addr ;
121
128
}
122
- const matchCol = value . match ( / [ A - Z ] + / ) ;
123
- let col ;
124
- let colNumber ;
125
- if ( matchCol ) {
126
- col = matchCol [ 0 ] ;
127
- colNumber = this . l2n ( col ) ;
129
+ let hasCol = false ;
130
+ let col = '' ;
131
+ let colNumber = 0 ;
132
+ let hasRow = false ;
133
+ let row = '' ;
134
+ let rowNumber = 0 ;
135
+ for ( let i = 0 , char ; i < value . length ; i ++ ) {
136
+ char = value . charCodeAt ( i ) ;
137
+ // col should before row
138
+ if ( ! hasRow && char >= 65 && char <= 90 ) {
139
+ // 65 = 'A'.charCodeAt(0)
140
+ // 90 = 'Z'.charCodeAt(0)
141
+ hasCol = true ;
142
+ col += value [ i ] ;
143
+ // colNumber starts from 1
144
+ colNumber = ( colNumber * 26 ) + char - 64 ;
145
+ } else if ( char >= 48 && char <= 57 ) {
146
+ // 48 = '0'.charCodeAt(0)
147
+ // 57 = '9'.charCodeAt(0)
148
+ hasRow = true ;
149
+ row += value [ i ] ;
150
+ // rowNumber starts from 0
151
+ rowNumber = ( rowNumber * 10 ) + char - 48 ;
152
+ } else if ( hasRow && hasCol && char !== 36 ) {
153
+ // 36 = '$'.charCodeAt(0)
154
+ break ;
155
+ }
156
+ }
157
+ if ( ! hasCol ) {
158
+ colNumber = undefined ;
159
+ } else if ( colNumber > 16384 ) {
160
+ throw new Error ( `Out of bounds. Invalid column letter: ${ col } ` ) ;
128
161
}
129
- const matchRow = value . match ( / \d + / ) ;
130
- let row ;
131
- let rowNumber ;
132
- if ( matchRow ) {
133
- row = matchRow [ 0 ] ;
134
- rowNumber = parseInt ( row , 10 ) ;
162
+ if ( ! hasRow ) {
163
+ rowNumber = undefined ;
135
164
}
136
165
137
166
// in case $row$col
138
- value = ( col || '' ) + ( row || '' ) ;
167
+ value = col + row ;
139
168
140
169
const address = {
141
170
address : value ,
142
171
col : colNumber ,
143
172
row : rowNumber ,
144
- $col$row : `$${ col || '' } $${ row || '' } ` ,
173
+ $col$row : `$${ col } $${ row } ` ,
145
174
} ;
146
175
147
176
// mem fix - cache only the tl 100x100 square
0 commit comments