Browse Source

WriteSlice supports write []interface{}

Hugh Gao 10 years ago
parent
commit
7caacb81ce
2 changed files with 39 additions and 27 deletions
  1. 23 27
      write.go
  2. 16 0
      write_test.go

+ 23 - 27
write.go

@@ -11,49 +11,45 @@ func (r *Row) WriteSlice(e interface{}, cols int) int {
 		return cols
 	}
 
-	t := reflect.TypeOf(e).Elem()
-	if t.Kind() != reflect.Slice { // is 'e' even a slice?
-		return -1
-	}
-
 	// it's a slice, so open up its values
 	v := reflect.ValueOf(e).Elem()
+	if v.Kind() != reflect.Slice { // is 'e' even a slice?
+		return -1
+	}
 
 	n := v.Len()
 	if cols < n && cols > 0 {
 		n = cols
 	}
 
-	var i int
-	switch t.Elem().Kind() { // underlying type of slice
-	case reflect.String:
-		for i = 0; i < n; i++ {
+	var setCell func(reflect.Value)
+	setCell = func(val reflect.Value) {
+		switch val.Kind() { // underlying type of slice
+		case reflect.String:
 			cell := r.AddCell()
-			cell.SetString(v.Index(i).Interface().(string))
-		}
-	case reflect.Int, reflect.Int8,
-		reflect.Int16, reflect.Int32:
-		for i = 0; i < n; i++ {
+			cell.SetString(val.Interface().(string))
+		case reflect.Int, reflect.Int8,
+			reflect.Int16, reflect.Int32:
 			cell := r.AddCell()
-			cell.SetInt(v.Index(i).Interface().(int))
-		}
-	case reflect.Int64:
-		for i = 0; i < n; i++ {
+			cell.SetInt(val.Interface().(int))
+		case reflect.Int64:
 			cell := r.AddCell()
-			cell.SetInt64(v.Index(i).Interface().(int64))
-		}
-	case reflect.Bool:
-		for i = 0; i < n; i++ {
+			cell.SetInt64(val.Interface().(int64))
+		case reflect.Bool:
 			cell := r.AddCell()
-			cell.SetBool(v.Index(i).Interface().(bool))
-		}
-	case reflect.Float64, reflect.Float32:
-		for i = 0; i < n; i++ {
+			cell.SetBool(val.Interface().(bool))
+		case reflect.Float64, reflect.Float32:
 			cell := r.AddCell()
-			cell.SetFloat(v.Index(i).Interface().(float64))
+			cell.SetFloat(val.Interface().(float64))
+		case reflect.Interface:
+			setCell(reflect.ValueOf(val.Interface()))
 		}
 	}
 
+	var i int
+	for i = 0; i < n; i++ {
+		setCell(v.Index(i))
+	}
 	return i
 }
 

+ 16 - 0
write_test.go

@@ -53,6 +53,7 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	type intA []int
 	type floatA []float64
 	type boolA []bool
+	type interfaceA []interface{}
 
 	s0 := strA{"Eric"}
 	row0 := sheet.AddRow()
@@ -83,4 +84,19 @@ func (r *RowSuite) TestWriteSlice(c *C) {
 	c.Assert(row3, NotNil)
 	c3 := row3.Cells[0].Bool()
 	c.Assert(c3, Equals, true)
+
+	s4 := interfaceA{"Eric", 10, 3.94, true}
+	row4 := sheet.AddRow()
+	row4.WriteSlice(&s4, -1)
+	c.Assert(row4, NotNil)
+	c40 := row4.Cells[0].String()
+	c.Assert(c40, Equals, "Eric")
+	c41, e41 := row4.Cells[1].Int()
+	c.Assert(e41, Equals, nil)
+	c.Assert(c41, Equals, 10)
+	c42, e42 := row4.Cells[2].Float()
+	c.Assert(e42, Equals, nil)
+	c.Assert(c42, Equals, 3.94)
+	c43 := row4.Cells[3].Bool()
+	c.Assert(c43, Equals, true)
 }