Skip to content

Commit efcf599

Browse files
committed
This closes qax-os#1360, closes qax-os#1361
- Fix default number format parse issue with a long string of digits - Fix creating a sheet with an empty name cause a corrupted file - The `GetCellStyle` function no longer return master cell style of the merge cell range - Using the specialized name in variables and functions
1 parent addcc1a commit efcf599

23 files changed

+126
-145
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ func main() {
8383
fmt.Println(err)
8484
}
8585
}()
86-
// Get value from cell by given worksheet name and axis.
86+
// Get value from cell by given worksheet name and cell reference.
8787
cell, err := f.GetCellValue("Sheet1", "B2")
8888
if err != nil {
8989
fmt.Println(err)

adjust.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func (f *File) adjustTable(ws *xlsxWorksheet, sheet string, dir adjustDirection,
185185
Decode(&t); err != nil && err != io.EOF {
186186
return
187187
}
188-
coordinates, err := areaRefToCoordinates(t.Ref)
188+
coordinates, err := rangeRefToCoordinates(t.Ref)
189189
if err != nil {
190190
return
191191
}
@@ -204,7 +204,7 @@ func (f *File) adjustTable(ws *xlsxWorksheet, sheet string, dir adjustDirection,
204204
idx--
205205
continue
206206
}
207-
t.Ref, _ = f.coordinatesToAreaRef([]int{x1, y1, x2, y2})
207+
t.Ref, _ = f.coordinatesToRangeRef([]int{x1, y1, x2, y2})
208208
if t.AutoFilter != nil {
209209
t.AutoFilter.Ref = t.Ref
210210
}
@@ -221,7 +221,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
221221
return nil
222222
}
223223

224-
coordinates, err := areaRefToCoordinates(ws.AutoFilter.Ref)
224+
coordinates, err := rangeRefToCoordinates(ws.AutoFilter.Ref)
225225
if err != nil {
226226
return err
227227
}
@@ -241,7 +241,7 @@ func (f *File) adjustAutoFilter(ws *xlsxWorksheet, dir adjustDirection, num, off
241241
coordinates = f.adjustAutoFilterHelper(dir, coordinates, num, offset)
242242
x1, y1, x2, y2 = coordinates[0], coordinates[1], coordinates[2], coordinates[3]
243243

244-
if ws.AutoFilter.Ref, err = f.coordinatesToAreaRef([]int{x1, y1, x2, y2}); err != nil {
244+
if ws.AutoFilter.Ref, err = f.coordinatesToRangeRef([]int{x1, y1, x2, y2}); err != nil {
245245
return err
246246
}
247247
return nil
@@ -277,8 +277,8 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
277277
}
278278

279279
for i := 0; i < len(ws.MergeCells.Cells); i++ {
280-
areaData := ws.MergeCells.Cells[i]
281-
coordinates, err := areaRefToCoordinates(areaData.Ref)
280+
mergedCells := ws.MergeCells.Cells[i]
281+
coordinates, err := rangeRefToCoordinates(mergedCells.Ref)
282282
if err != nil {
283283
return err
284284
}
@@ -305,8 +305,8 @@ func (f *File) adjustMergeCells(ws *xlsxWorksheet, dir adjustDirection, num, off
305305
i--
306306
continue
307307
}
308-
areaData.rect = []int{x1, y1, x2, y2}
309-
if areaData.Ref, err = f.coordinatesToAreaRef([]int{x1, y1, x2, y2}); err != nil {
308+
mergedCells.rect = []int{x1, y1, x2, y2}
309+
if mergedCells.Ref, err = f.coordinatesToRangeRef([]int{x1, y1, x2, y2}); err != nil {
310310
return err
311311
}
312312
}

calc.go

+12-8
Original file line numberDiff line numberDiff line change
@@ -789,10 +789,14 @@ func (f *File) calcCellValue(ctx *calcContext, sheet, cell string) (result strin
789789
return
790790
}
791791
result = token.Value()
792-
isNum, precision := isNumeric(result)
793-
if isNum && (precision > 15 || precision == 0) {
794-
num := roundPrecision(result, -1)
795-
result = strings.ToUpper(num)
792+
if isNum, precision, decimal := isNumeric(result); isNum {
793+
if precision > 15 {
794+
result = strings.ToUpper(strconv.FormatFloat(decimal, 'G', 15, 64))
795+
return
796+
}
797+
if !strings.HasPrefix(result, "0") {
798+
result = strings.ToUpper(strconv.FormatFloat(decimal, 'f', -1, 64))
799+
}
796800
}
797801
return
798802
}
@@ -2089,13 +2093,13 @@ func (fn *formulaFuncs) COMPLEX(argsList *list.List) formulaArg {
20892093
// cmplx2str replace complex number string characters.
20902094
func cmplx2str(num complex128, suffix string) string {
20912095
realPart, imagPart := fmt.Sprint(real(num)), fmt.Sprint(imag(num))
2092-
isNum, i := isNumeric(realPart)
2096+
isNum, i, decimal := isNumeric(realPart)
20932097
if isNum && i > 15 {
2094-
realPart = roundPrecision(realPart, -1)
2098+
realPart = strconv.FormatFloat(decimal, 'G', 15, 64)
20952099
}
2096-
isNum, i = isNumeric(imagPart)
2100+
isNum, i, decimal = isNumeric(imagPart)
20972101
if isNum && i > 15 {
2098-
imagPart = roundPrecision(imagPart, -1)
2102+
imagPart = strconv.FormatFloat(decimal, 'G', 15, 64)
20992103
}
21002104
c := realPart
21012105
if imag(num) > 0 {

calc_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1736,7 +1736,7 @@ func TestCalcCellValue(t *testing.T) {
17361736
"=UPPER(\"TEST 123\")": "TEST 123",
17371737
// VALUE
17381738
"=VALUE(\"50\")": "50",
1739-
"=VALUE(\"1.0E-07\")": "1E-07",
1739+
"=VALUE(\"1.0E-07\")": "0.0000001",
17401740
"=VALUE(\"5,000\")": "5000",
17411741
"=VALUE(\"20%\")": "0.2",
17421742
"=VALUE(\"12:00:00\")": "0.5",

cell.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ func (f *File) SetCellDefault(sheet, cell, value string) error {
485485
// setCellDefault prepares cell type and string type cell value by a given
486486
// string.
487487
func setCellDefault(value string) (t string, v string) {
488-
if ok, _ := isNumeric(value); !ok {
488+
if ok, _, _ := isNumeric(value); !ok {
489489
t = "str"
490490
}
491491
v = value
@@ -631,7 +631,7 @@ func (f *File) SetCellFormula(sheet, cell, formula string, opts ...FormulaOpts)
631631

632632
// setSharedFormula set shared formula for the cells.
633633
func (ws *xlsxWorksheet) setSharedFormula(ref string) error {
634-
coordinates, err := areaRefToCoordinates(ref)
634+
coordinates, err := rangeRefToCoordinates(ref)
635635
if err != nil {
636636
return err
637637
}
@@ -1098,7 +1098,7 @@ func (f *File) setSheetCells(sheet, cell string, slice interface{}, dir adjustDi
10981098
return err
10991099
}
11001100

1101-
// getCellInfo does common preparation for all SetCell* methods.
1101+
// getCellInfo does common preparation for all set cell value functions.
11021102
func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, error) {
11031103
var err error
11041104
cell, err = f.mergeCellsParser(ws, cell)
@@ -1116,8 +1116,9 @@ func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, er
11161116
return &ws.SheetData.Row[row-1].C[col-1], col, row, err
11171117
}
11181118

1119-
// getCellStringFunc does common value extraction workflow for all GetCell*
1120-
// methods. Passed function implements specific part of required logic.
1119+
// getCellStringFunc does common value extraction workflow for all get cell
1120+
// value function. Passed function implements specific part of required
1121+
// logic.
11211122
func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c *xlsxC) (string, bool, error)) (string, error) {
11221123
ws, err := f.workSheetReader(sheet)
11231124
if err != nil {
@@ -1235,7 +1236,7 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error)
12351236
i--
12361237
continue
12371238
}
1238-
ok, err := f.checkCellInArea(cell, ws.MergeCells.Cells[i].Ref)
1239+
ok, err := f.checkCellInRangeRef(cell, ws.MergeCells.Cells[i].Ref)
12391240
if err != nil {
12401241
return cell, err
12411242
}
@@ -1247,18 +1248,18 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error)
12471248
return cell, nil
12481249
}
12491250

1250-
// checkCellInArea provides a function to determine if a given cell reference
1251+
// checkCellInRangeRef provides a function to determine if a given cell reference
12511252
// in a range.
1252-
func (f *File) checkCellInArea(cell, area string) (bool, error) {
1253+
func (f *File) checkCellInRangeRef(cell, reference string) (bool, error) {
12531254
col, row, err := CellNameToCoordinates(cell)
12541255
if err != nil {
12551256
return false, err
12561257
}
12571258

1258-
if rng := strings.Split(area, ":"); len(rng) != 2 {
1259+
if rng := strings.Split(reference, ":"); len(rng) != 2 {
12591260
return false, err
12601261
}
1261-
coordinates, err := areaRefToCoordinates(area)
1262+
coordinates, err := rangeRefToCoordinates(reference)
12621263
if err != nil {
12631264
return false, err
12641265
}
@@ -1333,7 +1334,7 @@ func parseSharedFormula(dCol, dRow int, orig []byte) (res string, start int) {
13331334
// R1C1-reference notation, are the same.
13341335
//
13351336
// Note that this function not validate ref tag to check the cell whether in
1336-
// allow area, and always return origin shared formula.
1337+
// allow range reference, and always return origin shared formula.
13371338
func getSharedFormula(ws *xlsxWorksheet, si int, cell string) string {
13381339
for _, r := range ws.SheetData.Row {
13391340
for _, c := range r.C {

cell_test.go

+21-17
Original file line numberDiff line numberDiff line change
@@ -95,43 +95,43 @@ func TestConcurrency(t *testing.T) {
9595
assert.NoError(t, f.Close())
9696
}
9797

98-
func TestCheckCellInArea(t *testing.T) {
98+
func TestCheckCellInRangeRef(t *testing.T) {
9999
f := NewFile()
100-
expectedTrueCellInAreaList := [][2]string{
100+
expectedTrueCellInRangeRefList := [][2]string{
101101
{"c2", "A1:AAZ32"},
102102
{"B9", "A1:B9"},
103103
{"C2", "C2:C2"},
104104
}
105105

106-
for _, expectedTrueCellInArea := range expectedTrueCellInAreaList {
107-
cell := expectedTrueCellInArea[0]
108-
area := expectedTrueCellInArea[1]
109-
ok, err := f.checkCellInArea(cell, area)
106+
for _, expectedTrueCellInRangeRef := range expectedTrueCellInRangeRefList {
107+
cell := expectedTrueCellInRangeRef[0]
108+
reference := expectedTrueCellInRangeRef[1]
109+
ok, err := f.checkCellInRangeRef(cell, reference)
110110
assert.NoError(t, err)
111111
assert.Truef(t, ok,
112-
"Expected cell %v to be in area %v, got false\n", cell, area)
112+
"Expected cell %v to be in range reference %v, got false\n", cell, reference)
113113
}
114114

115-
expectedFalseCellInAreaList := [][2]string{
115+
expectedFalseCellInRangeRefList := [][2]string{
116116
{"c2", "A4:AAZ32"},
117117
{"C4", "D6:A1"}, // weird case, but you never know
118118
{"AEF42", "BZ40:AEF41"},
119119
}
120120

121-
for _, expectedFalseCellInArea := range expectedFalseCellInAreaList {
122-
cell := expectedFalseCellInArea[0]
123-
area := expectedFalseCellInArea[1]
124-
ok, err := f.checkCellInArea(cell, area)
121+
for _, expectedFalseCellInRangeRef := range expectedFalseCellInRangeRefList {
122+
cell := expectedFalseCellInRangeRef[0]
123+
reference := expectedFalseCellInRangeRef[1]
124+
ok, err := f.checkCellInRangeRef(cell, reference)
125125
assert.NoError(t, err)
126126
assert.Falsef(t, ok,
127-
"Expected cell %v not to be inside of area %v, but got true\n", cell, area)
127+
"Expected cell %v not to be inside of range reference %v, but got true\n", cell, reference)
128128
}
129129

130-
ok, err := f.checkCellInArea("A1", "A:B")
130+
ok, err := f.checkCellInRangeRef("A1", "A:B")
131131
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
132132
assert.False(t, ok)
133133

134-
ok, err = f.checkCellInArea("AA0", "Z0:AB1")
134+
ok, err = f.checkCellInRangeRef("AA0", "Z0:AB1")
135135
assert.EqualError(t, err, newCellNameToCoordinatesError("AA0", newInvalidCellNameError("AA0")).Error())
136136
assert.False(t, ok)
137137
}
@@ -326,8 +326,10 @@ func TestGetCellValue(t *testing.T) {
326326
<c r="Y1"><v>275.39999999999998</v></c>
327327
<c r="Z1"><v>68.900000000000006</v></c>
328328
<c r="AA1"><v>1.1000000000000001</v></c>
329-
<c r="AA2"><v>1234567890123_4</v></c>
330-
<c r="AA3"><v>123456789_0123_4</v></c>
329+
<c r="AB1" t="str"><v>1234567890123_4</v></c>
330+
<c r="AC1" t="str"><v>123456789_0123_4</v></c>
331+
<c r="AD1"><v>+0.0000000000000000002399999999999992E-4</v></c>
332+
<c r="AE1"><v>7.2399999999999992E-2</v></c>
331333
</row>`)))
332334
f.checked = nil
333335
rows, err = f.GetRows("Sheet1")
@@ -361,6 +363,8 @@ func TestGetCellValue(t *testing.T) {
361363
"1.1",
362364
"1234567890123_4",
363365
"123456789_0123_4",
366+
"2.39999999999999E-23",
367+
"0.0724",
364368
}}, rows)
365369
assert.NoError(t, err)
366370
}

col.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ func flatCols(col xlsxCol, cols []xlsxCol, replacer func(fc, c xlsxCol) xlsxCol)
560560
// | | | (x2,y2)|
561561
// +-----+------------+------------+
562562
//
563-
// Example of an object that covers some area from cell A1 to B2.
563+
// Example of an object that covers some range reference from cell A1 to B2.
564564
//
565565
// Based on the width and height of the object we need to calculate 8 vars:
566566
//

datavalidation.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ func (f *File) squashSqref(cells [][]int) []string {
333333
l, r := 0, 0
334334
for i := 1; i < len(cells); i++ {
335335
if cells[i][0] == cells[r][0] && cells[i][1]-cells[r][1] > 1 {
336-
curr, _ := f.coordinatesToAreaRef(append(cells[l], cells[r]...))
336+
curr, _ := f.coordinatesToRangeRef(append(cells[l], cells[r]...))
337337
if l == r {
338338
curr, _ = CoordinatesToCellName(cells[l][0], cells[l][1])
339339
}
@@ -343,7 +343,7 @@ func (f *File) squashSqref(cells [][]int) []string {
343343
r++
344344
}
345345
}
346-
curr, _ := f.coordinatesToAreaRef(append(cells[l], cells[r]...))
346+
curr, _ := f.coordinatesToRangeRef(append(cells[l], cells[r]...))
347347
if l == r {
348348
curr, _ = CoordinatesToCellName(cells[l][0], cells[l][1])
349349
}

excelize_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ func TestSetCellStyleBorder(t *testing.T) {
615615

616616
var style int
617617

618-
// Test set border on overlapping area with vertical variants shading styles gradient fill.
618+
// Test set border on overlapping range with vertical variants shading styles gradient fill.
619619
style, err = f.NewStyle(&Style{
620620
Border: []Border{
621621
{Type: "left", Color: "0000FF", Style: 3},

0 commit comments

Comments
 (0)