Browse Source

1. make WriteSlice and WriteStruct write value with builtin format to general format
2. WriteSlice and WriteStruct now support time.Time
3. add more types to SetValue and add test for cell.SetValue

GaoXiang 9 years ago
parent
commit
afb0e7ea86
4 changed files with 78 additions and 39 deletions
  1. 1 13
      cell.go
  2. 40 0
      cell_test.go
  3. 16 22
      write.go
  4. 21 4
      write_test.go

+ 1 - 13
cell.go

@@ -174,19 +174,7 @@ func (c *Cell) SetValue(n interface{}) {
 	case time.Time:
 		c.SetDateTime(n.(time.Time))
 		return
-	case int:
-		c.setGeneral(fmt.Sprintf("%v", n))
-		return
-	case int32:
-		c.setGeneral(fmt.Sprintf("%v", n))
-		return
-	case int64:
-		c.setGeneral(fmt.Sprintf("%v", n))
-		return
-	case float32:
-		c.setGeneral(fmt.Sprintf("%v", n))
-		return
-	case float64:
+	case int, int8, int16, int32, int64, float32, float64:
 		c.setGeneral(fmt.Sprintf("%v", n))
 		return
 	case string:

+ 40 - 0
cell_test.go

@@ -1,6 +1,9 @@
 package xlsx
 
 import (
+	"math"
+	"time"
+
 	. "gopkg.in/check.v1"
 )
 
@@ -442,3 +445,40 @@ func (s *CellSuite) TestStringBool(c *C) {
 	cell.SetString("0")
 	c.Assert(cell.Bool(), Equals, true)
 }
+
+// TestSetValue tests whether SetValue handle properly for different type values.
+func (s *CellSuite) TestSetValue(c *C) {
+	cell := Cell{}
+
+	// int
+	for _, i := range []interface{}{1, int8(1), int16(1), int32(1), int64(1)} {
+		cell.SetValue(i)
+		val, err := cell.Int64()
+		c.Assert(err, IsNil)
+		c.Assert(val, Equals, int64(1))
+	}
+
+	// float
+	for _, i := range []interface{}{1.11, float32(1.11), float64(1.11)} {
+		cell.SetValue(i)
+		val, err := cell.Float()
+		c.Assert(err, IsNil)
+		c.Assert(val, Equals, 1.11)
+	}
+
+	// time
+	cell.SetValue(time.Unix(0, 0))
+	val, err := cell.Float()
+	c.Assert(err, IsNil)
+	c.Assert(math.Floor(val), Equals, 25569.0)
+
+	// string and nil
+	for _, i := range []interface{}{nil, "", []byte("")} {
+		cell.SetValue(i)
+		c.Assert(cell.Value, Equals, "")
+	}
+
+	// others
+	cell.SetValue([]string{"test"})
+	c.Assert(cell.Value, Equals, "[test]")
+}

+ 16 - 22
write.go

@@ -3,6 +3,7 @@ package xlsx
 import (
 	"fmt"
 	"reflect"
+	"time"
 )
 
 // Writes an array to row r. Accepts a pointer to array type 'e',
@@ -34,27 +35,21 @@ func (r *Row) WriteSlice(e interface{}, cols int) int {
 	var setCell func(reflect.Value)
 	setCell = func(val reflect.Value) {
 		switch t := val.Interface().(type) {
+		case time.Time:
+			cell := r.AddCell()
+			cell.SetValue(t)
 		case fmt.Stringer: // check Stringer first
 			cell := r.AddCell()
 			cell.SetString(t.String())
 		default:
 			switch val.Kind() { // underlying type of slice
-			case reflect.String:
-				cell := r.AddCell()
-				cell.SetString(t.(string))
-			case reflect.Int, reflect.Int8,
-				reflect.Int16, reflect.Int32:
+			case reflect.String, reflect.Int, reflect.Int8,
+				reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64, reflect.Float32:
 				cell := r.AddCell()
-				cell.SetInt(t.(int))
-			case reflect.Int64:
-				cell := r.AddCell()
-				cell.SetInt64(t.(int64))
+				cell.SetValue(val.Interface())
 			case reflect.Bool:
 				cell := r.AddCell()
 				cell.SetBool(t.(bool))
-			case reflect.Float64, reflect.Float32:
-				cell := r.AddCell()
-				cell.SetFloat(t.(float64))
 			case reflect.Interface:
 				setCell(reflect.ValueOf(t))
 			}
@@ -90,23 +85,22 @@ func (r *Row) WriteStruct(e interface{}, cols int) int {
 	var k int
 	for i := 0; i < n; i, k = i+1, k+1 {
 		f := v.Field(i)
-		cell := r.AddCell()
 
 		switch t := f.Interface().(type) {
+		case time.Time:
+			cell := r.AddCell()
+			cell.SetValue(t)
 		case fmt.Stringer: // check Stringer first
+			cell := r.AddCell()
 			cell.SetString(t.String())
 		default:
 			switch f.Kind() {
-			case reflect.Int, reflect.Int8,
-				reflect.Int16, reflect.Int32:
-				cell.SetInt(t.(int))
-			case reflect.Int64:
-				cell.SetInt64(t.(int64))
-			case reflect.String:
-				cell.SetString(t.(string))
-			case reflect.Float64, reflect.Float32:
-				cell.SetFloat(t.(float64))
+			case reflect.String, reflect.Int, reflect.Int8,
+				reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64, reflect.Float32:
+				cell := r.AddCell()
+				cell.SetValue(f.Interface())
 			case reflect.Bool:
+				cell := r.AddCell()
 				cell.SetBool(t.(bool))
 			default:
 				k-- // nothing set so reset to previous

+ 21 - 4
write_test.go

@@ -1,6 +1,9 @@
 package xlsx
 
 import (
+	"math"
+	"time"
+
 	. "gopkg.in/check.v1"
 )
 
@@ -29,6 +32,7 @@ func (r *RowSuite) TestWriteStruct(c *C) {
 		LikesPHP    bool
 		Stringer    testStringerImpl
 		StringerPtr *testStringerImpl
+		Time        time.Time
 	}
 	testStruct := e{
 		"Eric",
@@ -37,12 +41,17 @@ func (r *RowSuite) TestWriteStruct(c *C) {
 		false,
 		testStringerImpl{"Stringer"},
 		&testStringerImpl{"Pointer to Stringer"},
+		time.Unix(0, 0),
 	}
-	row.WriteStruct(&testStruct, -1)
+	cnt := row.WriteStruct(&testStruct, -1)
+	c.Assert(cnt, Equals, 7)
 	c.Assert(row, NotNil)
 
-	var c0, c4, c5 string
-	var err error
+	var (
+		c0, c4, c5 string
+		err        error
+		c6         float64
+	)
 	if c0, err = row.Cells[0].String(); err != nil {
 		c.Error(err)
 	}
@@ -55,6 +64,9 @@ func (r *RowSuite) TestWriteStruct(c *C) {
 	if c5, err = row.Cells[5].String(); err != nil {
 		c.Error(err)
 	}
+	if c6, err = row.Cells[6].Float(); err != nil {
+		c.Error(err)
+	}
 
 	c.Assert(c0, Equals, "Eric")
 	c.Assert(c1, Equals, 20)
@@ -62,6 +74,7 @@ func (r *RowSuite) TestWriteStruct(c *C) {
 	c.Assert(c3, Equals, false)
 	c.Assert(c4, Equals, "Stringer")
 	c.Assert(c5, Equals, "Pointer to Stringer")
+	c.Assert(math.Floor(c6), Equals, 25569.0)
 
 	c.Assert(e1, Equals, nil)
 	c.Assert(e2, Equals, nil)
@@ -115,7 +128,7 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	c3 := row3.Cells[0].Bool()
 	c.Assert(c3, Equals, true)
 
-	s4 := interfaceA{"Eric", 10, 3.94, true}
+	s4 := interfaceA{"Eric", 10, 3.94, true, time.Unix(0, 0)}
 	row4 := sheet.AddRow()
 	row4.WriteSlice(&s4, -1)
 	c.Assert(row4, NotNil)
@@ -133,6 +146,10 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	c43 := row4.Cells[3].Bool()
 	c.Assert(c43, Equals, true)
 
+	c44, e44 := row4.Cells[4].Float()
+	c.Assert(e44, Equals, nil)
+	c.Assert(math.Floor(c44), Equals, 25569.0)
+
 	s5 := stringerA{testStringerImpl{"Stringer"}}
 	row5 := sheet.AddRow()
 	row5.WriteSlice(&s5, -1)