write.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package xlsx
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. // Writes an array to row r. Accepts a pointer to array type 'e',
  7. // and writes the number of columns to write, 'cols'. If 'cols' is < 0,
  8. // the entire array will be written if possible. Returns -1 if the 'e'
  9. // doesn't point to an array, otherwise the number of columns written.
  10. func (r *Row) WriteSlice(e interface{}, cols int) int {
  11. if cols == 0 {
  12. return cols
  13. }
  14. // it's a slice, so open up its values
  15. v := reflect.ValueOf(e).Elem()
  16. if v.Kind() != reflect.Slice { // is 'e' even a slice?
  17. return -1
  18. }
  19. n := v.Len()
  20. if cols < n && cols > 0 {
  21. n = cols
  22. }
  23. var setCell func(reflect.Value)
  24. setCell = func(val reflect.Value) {
  25. switch t := val.Interface().(type) {
  26. case fmt.Stringer: // check Stringer first
  27. cell := r.AddCell()
  28. cell.SetString(t.String())
  29. default:
  30. switch val.Kind() { // underlying type of slice
  31. case reflect.String:
  32. cell := r.AddCell()
  33. cell.SetString(t.(string))
  34. case reflect.Int, reflect.Int8,
  35. reflect.Int16, reflect.Int32:
  36. cell := r.AddCell()
  37. cell.SetInt(t.(int))
  38. case reflect.Int64:
  39. cell := r.AddCell()
  40. cell.SetInt64(t.(int64))
  41. case reflect.Bool:
  42. cell := r.AddCell()
  43. cell.SetBool(t.(bool))
  44. case reflect.Float64, reflect.Float32:
  45. cell := r.AddCell()
  46. cell.SetFloat(t.(float64))
  47. case reflect.Interface:
  48. setCell(reflect.ValueOf(t))
  49. }
  50. }
  51. }
  52. var i int
  53. for i = 0; i < n; i++ {
  54. setCell(v.Index(i))
  55. }
  56. return i
  57. }
  58. // Writes a struct to row r. Accepts a pointer to struct type 'e',
  59. // and the number of columns to write, `cols`. If 'cols' is < 0,
  60. // the entire struct will be written if possible. Returns -1 if the 'e'
  61. // doesn't point to a struct, otherwise the number of columns written
  62. func (r *Row) WriteStruct(e interface{}, cols int) int {
  63. if cols == 0 {
  64. return cols
  65. }
  66. v := reflect.ValueOf(e).Elem()
  67. if v.Kind() != reflect.Struct {
  68. return -1 // bail if it's not a struct
  69. }
  70. n := v.NumField() // number of fields in struct
  71. if cols < n && cols > 0 {
  72. n = cols
  73. }
  74. var k int
  75. for i := 0; i < n; i, k = i+1, k+1 {
  76. f := v.Field(i)
  77. cell := r.AddCell()
  78. switch t := f.Interface().(type) {
  79. case fmt.Stringer: // check Stringer first
  80. cell.SetString(t.String())
  81. default:
  82. switch f.Kind() {
  83. case reflect.Int, reflect.Int8,
  84. reflect.Int16, reflect.Int32:
  85. cell.SetInt(t.(int))
  86. case reflect.Int64:
  87. cell.SetInt64(t.(int64))
  88. case reflect.String:
  89. cell.SetString(t.(string))
  90. case reflect.Float64, reflect.Float32:
  91. cell.SetFloat(t.(float64))
  92. case reflect.Bool:
  93. cell.SetBool(t.(bool))
  94. default:
  95. k-- // nothing set so reset to previous
  96. }
  97. }
  98. }
  99. return k
  100. }