Skip to content

Commit 4dd3447

Browse files
committed
This closes qax-os#1955, refs qax-os#119, support to set cell value with an IEEE 754 "not-a-number" value or infinity
1 parent 68a1704 commit 4dd3447

File tree

4 files changed

+31
-8
lines changed

4 files changed

+31
-8
lines changed

cell.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"bytes"
1616
"encoding/xml"
1717
"fmt"
18+
"math"
1819
"os"
1920
"reflect"
2021
"strconv"
@@ -385,6 +386,9 @@ func setCellBool(value bool) (t string, v string) {
385386
// var x float32 = 1.325
386387
// f.SetCellFloat("Sheet1", "A1", float64(x), 2, 32)
387388
func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSize int) error {
389+
if math.IsNaN(value) || math.IsInf(value, 0) {
390+
return f.SetCellStr(sheet, cell, fmt.Sprint(value))
391+
}
388392
f.mu.Lock()
389393
ws, err := f.workSheetReader(sheet)
390394
if err != nil {
@@ -399,16 +403,19 @@ func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSiz
399403
return err
400404
}
401405
c.S = ws.prepareCellStyle(col, row, c.S)
402-
c.T, c.V = setCellFloat(value, precision, bitSize)
403-
c.IS = nil
406+
c.setCellFloat(value, precision, bitSize)
404407
return f.removeFormula(c, ws, sheet)
405408
}
406409

407410
// setCellFloat prepares cell type and string type cell value by a given float
408411
// value.
409-
func setCellFloat(value float64, precision, bitSize int) (t string, v string) {
410-
v = strconv.FormatFloat(value, 'f', precision, bitSize)
411-
return
412+
func (c *xlsxC) setCellFloat(value float64, precision, bitSize int) {
413+
if math.IsNaN(value) || math.IsInf(value, 0) {
414+
c.setInlineStr(fmt.Sprint(value))
415+
return
416+
}
417+
c.T, c.V = "", strconv.FormatFloat(value, 'f', precision, bitSize)
418+
c.IS = nil
412419
}
413420

414421
// SetCellStr provides a function to set string type value of a cell. Total

cell_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,19 @@ func TestSetCellValue(t *testing.T) {
292292
val, err = f.GetCellValue("Sheet1", "B1")
293293
assert.NoError(t, err)
294294
assert.Equal(t, "b", val)
295+
296+
f = NewFile()
297+
// Test set cell value with an IEEE 754 "not-a-number" value or infinity
298+
for num, expected := range map[float64]string{
299+
math.NaN(): "NaN",
300+
math.Inf(0): "+Inf",
301+
math.Inf(-1): "-Inf",
302+
} {
303+
assert.NoError(t, f.SetCellValue("Sheet1", "A1", num))
304+
val, err := f.GetCellValue("Sheet1", "A1")
305+
assert.NoError(t, err)
306+
assert.Equal(t, expected, val)
307+
}
295308
}
296309

297310
func TestSetCellValues(t *testing.T) {

stream.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,9 +529,9 @@ func (sw *StreamWriter) setCellValFunc(c *xlsxC, val interface{}) error {
529529
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
530530
setCellIntFunc(c, val)
531531
case float32:
532-
c.T, c.V = setCellFloat(float64(val), -1, 32)
532+
c.setCellFloat(float64(val), -1, 32)
533533
case float64:
534-
c.T, c.V = setCellFloat(val, -1, 64)
534+
c.setCellFloat(val, -1, 64)
535535
case string:
536536
c.setCellValue(val)
537537
case []byte:

stream_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/xml"
55
"fmt"
66
"io"
7+
"math"
78
"math/rand"
89
"os"
910
"path/filepath"
@@ -76,6 +77,8 @@ func TestStreamWriter(t *testing.T) {
7677
assert.NoError(t, streamWriter.SetRow("A7", nil, RowOpts{Height: 20, Hidden: true, StyleID: styleID}))
7778
assert.Equal(t, ErrMaxRowHeight, streamWriter.SetRow("A8", nil, RowOpts{Height: MaxRowHeight + 1}))
7879

80+
assert.NoError(t, streamWriter.SetRow("A9", []interface{}{math.NaN(), math.Inf(0), math.Inf(-1)}))
81+
7982
for rowID := 10; rowID <= 51200; rowID++ {
8083
row := make([]interface{}, 50)
8184
for colID := 0; colID < 50; colID++ {
@@ -145,7 +148,7 @@ func TestStreamWriter(t *testing.T) {
145148
cells += len(row)
146149
}
147150
assert.NoError(t, rows.Close())
148-
assert.Equal(t, 2559559, cells)
151+
assert.Equal(t, 2559562, cells)
149152
// Save spreadsheet with password.
150153
assert.NoError(t, file.SaveAs(filepath.Join("test", "EncryptionTestStreamWriter.xlsx"), Options{Password: "password"}))
151154
assert.NoError(t, file.Close())

0 commit comments

Comments
 (0)