read_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package xlsx
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. . "gopkg.in/check.v1"
  7. )
  8. type ReadSuite struct{}
  9. var _ = Suite(&ReadSuite{})
  10. var (
  11. errorNoPair = errors.New("Integer to be unmarshaled is not a pair")
  12. errorNotEnoughCells = errors.New("Row has not enough cells")
  13. )
  14. type pairUnmarshaler int
  15. func (i *pairUnmarshaler) Unmarshal(row *Row) error {
  16. if len(row.Cells) == 0 {
  17. return errorNotEnoughCells
  18. }
  19. cellInt, err := row.Cells[0].Int()
  20. if err != nil {
  21. return err
  22. }
  23. if cellInt%2 != 0 {
  24. return errorNoPair
  25. }
  26. *i = pairUnmarshaler(cellInt)
  27. return nil
  28. }
  29. type structUnmarshaler struct {
  30. private bool
  31. custom string
  32. normal int
  33. }
  34. func (s *structUnmarshaler) Unmarshal(r *Row) error {
  35. if len(r.Cells) < 3 {
  36. return errorNotEnoughCells
  37. }
  38. s.private = r.Cells[0].Bool()
  39. var err error
  40. s.normal, err = r.Cells[2].Int()
  41. if err != nil {
  42. return err
  43. }
  44. currency, err := r.Cells[1].String()
  45. if err != nil {
  46. return err
  47. }
  48. s.custom = fmt.Sprintf("$ %s", currency)
  49. return nil
  50. }
  51. func (r *RowSuite) TestInterface(c *C) {
  52. var p pairUnmarshaler
  53. var s structUnmarshaler
  54. f := NewFile()
  55. sheet, _ := f.AddSheet("TestReadTime")
  56. row := sheet.AddRow()
  57. values := []interface{}{1, "500", true}
  58. row.WriteSlice(&values, -1)
  59. errPair := row.ReadStruct(&p)
  60. err := row.ReadStruct(&s)
  61. c.Assert(errPair, Equals, errorNoPair)
  62. c.Assert(err, Equals, nil)
  63. var empty pairUnmarshaler
  64. c.Assert(p, Equals, empty)
  65. c.Assert(s.normal, Equals, 1)
  66. c.Assert(s.private, Equals, true)
  67. c.Assert(s.custom, Equals, "$ 500")
  68. }
  69. func (r *RowSuite) TestTime(c *C) {
  70. type Timer struct {
  71. Initial time.Time `xlsx:"0"`
  72. Final time.Time `xlsx:"1"`
  73. }
  74. initial := time.Date(1990, 12, 30, 10, 30, 30, 0, time.UTC)
  75. t := Timer{
  76. Initial: initial,
  77. Final: initial.Add(time.Hour * 24),
  78. }
  79. f := NewFile()
  80. sheet, _ := f.AddSheet("TestReadTime")
  81. row := sheet.AddRow()
  82. row.AddCell().SetDateTime(t.Initial)
  83. ctime2 := row.AddCell()
  84. ctime2.SetDate(t.Final)
  85. t2 := Timer{}
  86. err := row.ReadStruct(&t2)
  87. if err != nil {
  88. c.Error(err)
  89. c.FailNow()
  90. }
  91. //removing ns presition
  92. t2.Initial = t2.Initial.Add(time.Duration(-1 * t2.Initial.Nanosecond()))
  93. c.Assert(t2.Initial, Equals, t.Initial)
  94. //since we wrote a plain Date, we must also remove the hour/min/sec part
  95. h, m, s := t.Final.Clock()
  96. t.Final = t.Final.Add(-1 * (time.Duration(h)*time.Hour + time.Duration(m)*time.Minute + time.Duration(s)*time.Second))
  97. c.Assert(t2.Final, Equals, t.Final)
  98. }
  99. func (r *RowSuite) TestEmbedStruct(c *C) {
  100. type Embed struct {
  101. privateVal bool `xlsx:"0"`
  102. IgnoredVal int `xlsx:"-"`
  103. VisibleVal string `xlsx:"2"`
  104. }
  105. type structTest struct {
  106. Embed
  107. FinalVal string `xlsx:"3"`
  108. }
  109. f := NewFile()
  110. sheet, _ := f.AddSheet("TestRead")
  111. row := sheet.AddRow()
  112. v := structTest{
  113. Embed: Embed{
  114. privateVal: true,
  115. IgnoredVal: 10,
  116. VisibleVal: "--This is a test value--",
  117. },
  118. FinalVal: "--end of struct",
  119. }
  120. values := []string{
  121. fmt.Sprint(v.privateVal),
  122. fmt.Sprint(v.IgnoredVal),
  123. fmt.Sprint(v.VisibleVal),
  124. fmt.Sprint(v.FinalVal),
  125. }
  126. row.WriteSlice(&values, -1)
  127. for _, cell := range row.Cells {
  128. v, _ := cell.String()
  129. c.Log(v)
  130. }
  131. read := new(structTest)
  132. err := row.ReadStruct(read)
  133. if err != nil {
  134. c.Error(err)
  135. c.FailNow()
  136. }
  137. c.Assert(read.privateVal, Equals, false)
  138. c.Assert(read.VisibleVal, Equals, v.VisibleVal)
  139. c.Assert(read.IgnoredVal, Equals, 0)
  140. c.Assert(read.FinalVal, Equals, v.FinalVal)
  141. }
  142. func (r *RowSuite) TestReadStructPrivateFields(c *C) {
  143. type nested struct {
  144. IgnoredVal int `xlsx:"-"`
  145. VisibleVal string `xlsx:"6"`
  146. privateVal bool `xlsx:"7"`
  147. }
  148. type structTest struct {
  149. IntVal int16 `xlsx:"0"`
  150. StringVal string `xlsx:"1"`
  151. FloatVal float64 `xlsx:"2"`
  152. IgnoredVal int `xlsx:"-"`
  153. BoolVal bool `xlsx:"4"`
  154. Nested nested
  155. }
  156. val := structTest{
  157. IntVal: 16,
  158. StringVal: "heyheyhey :)!",
  159. FloatVal: 3.14159216,
  160. IgnoredVal: 7,
  161. BoolVal: true,
  162. Nested: nested{
  163. privateVal: true,
  164. IgnoredVal: 90,
  165. VisibleVal: "Hello",
  166. },
  167. }
  168. writtenValues := []string{
  169. fmt.Sprint(val.IntVal), val.StringVal, fmt.Sprint(val.FloatVal),
  170. fmt.Sprint(val.IgnoredVal), fmt.Sprint(val.BoolVal),
  171. fmt.Sprint(val.Nested.IgnoredVal), val.Nested.VisibleVal,
  172. fmt.Sprint(val.Nested.privateVal),
  173. }
  174. f := NewFile()
  175. sheet, _ := f.AddSheet("TestRead")
  176. row := sheet.AddRow()
  177. row.WriteSlice(&writtenValues, -1)
  178. for i, cell := range row.Cells {
  179. str, _ := cell.String()
  180. c.Log(i, " ", str)
  181. }
  182. readStruct := structTest{}
  183. err := row.ReadStruct(&readStruct)
  184. if err != nil {
  185. c.Error(err)
  186. c.FailNow()
  187. }
  188. c.Assert(err, Equals, nil)
  189. c.Assert(readStruct.IntVal, Equals, val.IntVal)
  190. c.Assert(readStruct.StringVal, Equals, val.StringVal)
  191. c.Assert(readStruct.IgnoredVal, Equals, 0)
  192. c.Assert(readStruct.FloatVal, Equals, val.FloatVal)
  193. c.Assert(readStruct.BoolVal, Equals, val.BoolVal)
  194. c.Assert(readStruct.Nested.IgnoredVal, Equals, 0)
  195. c.Assert(readStruct.Nested.VisibleVal, Equals, "Hello")
  196. c.Assert(readStruct.Nested.privateVal, Equals, false)
  197. }
  198. func (r *RowSuite) TestReadStruct(c *C) {
  199. type structTest struct {
  200. IntVal int8 `xlsx:"0"`
  201. StringVal string `xlsx:"1"`
  202. FloatVal float64 `xlsx:"2"`
  203. IgnoredVal int `xlsx:"-"`
  204. BoolVal bool `xlsx:"4"`
  205. }
  206. structVal := structTest{
  207. IntVal: 10,
  208. StringVal: "heyheyhey :)!",
  209. FloatVal: 3.14159216,
  210. IgnoredVal: 7,
  211. BoolVal: true,
  212. }
  213. f := NewFile()
  214. sheet, _ := f.AddSheet("TestRead")
  215. row := sheet.AddRow()
  216. row.WriteStruct(&structVal, -1)
  217. for i, cell := range row.Cells {
  218. str, _ := cell.String()
  219. c.Log(i, " ", str)
  220. }
  221. readStruct := &structTest{}
  222. err := row.ReadStruct(readStruct)
  223. c.Log(readStruct)
  224. c.Log(structVal)
  225. c.Assert(err, Equals, nil)
  226. c.Assert(readStruct.IntVal, Equals, structVal.IntVal)
  227. c.Assert(readStruct.StringVal, Equals, structVal.StringVal)
  228. c.Assert(readStruct.IgnoredVal, Equals, 0)
  229. c.Assert(readStruct.FloatVal, Equals, structVal.FloatVal)
  230. c.Assert(readStruct.BoolVal, Equals, structVal.BoolVal)
  231. }