stream_test.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. package excelize
  2. import (
  3. "encoding/xml"
  4. "fmt"
  5. "io/ioutil"
  6. "math/rand"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "testing"
  11. "time"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. func BenchmarkStreamWriter(b *testing.B) {
  15. file := NewFile()
  16. row := make([]interface{}, 10)
  17. for colID := 0; colID < 10; colID++ {
  18. row[colID] = colID
  19. }
  20. for n := 0; n < b.N; n++ {
  21. streamWriter, _ := file.NewStreamWriter("Sheet1")
  22. for rowID := 10; rowID <= 110; rowID++ {
  23. cell, _ := CoordinatesToCellName(1, rowID)
  24. _ = streamWriter.SetRow(cell, row)
  25. }
  26. }
  27. b.ReportAllocs()
  28. }
  29. func TestStreamWriter(t *testing.T) {
  30. file := NewFile()
  31. streamWriter, err := file.NewStreamWriter("Sheet1")
  32. assert.NoError(t, err)
  33. // Test max characters in a cell.
  34. row := make([]interface{}, 1)
  35. row[0] = strings.Repeat("c", TotalCellChars+2)
  36. assert.NoError(t, streamWriter.SetRow("A1", row))
  37. // Test leading and ending space(s) character characters in a cell.
  38. row = make([]interface{}, 1)
  39. row[0] = " characters"
  40. assert.NoError(t, streamWriter.SetRow("A2", row))
  41. row = make([]interface{}, 1)
  42. row[0] = []byte("Word")
  43. assert.NoError(t, streamWriter.SetRow("A3", row))
  44. // Test set cell with style.
  45. styleID, err := file.NewStyle(`{"font":{"color":"#777777"}}`)
  46. assert.NoError(t, err)
  47. assert.NoError(t, streamWriter.SetRow("A4", []interface{}{Cell{StyleID: styleID}, Cell{Formula: "SUM(A10,B10)"}}), RowOpts{Height: 45})
  48. assert.NoError(t, streamWriter.SetRow("A5", []interface{}{&Cell{StyleID: styleID, Value: "cell"}, &Cell{Formula: "SUM(A10,B10)"}}))
  49. assert.NoError(t, streamWriter.SetRow("A6", []interface{}{time.Now()}))
  50. assert.NoError(t, streamWriter.SetRow("A7", nil, RowOpts{Hidden: true}))
  51. assert.EqualError(t, streamWriter.SetRow("A7", nil, RowOpts{Height: MaxRowHeight + 1}), ErrMaxRowHeight.Error())
  52. for rowID := 10; rowID <= 51200; rowID++ {
  53. row := make([]interface{}, 50)
  54. for colID := 0; colID < 50; colID++ {
  55. row[colID] = rand.Intn(640000)
  56. }
  57. cell, _ := CoordinatesToCellName(1, rowID)
  58. assert.NoError(t, streamWriter.SetRow(cell, row))
  59. }
  60. assert.NoError(t, streamWriter.Flush())
  61. // Save spreadsheet by the given path.
  62. assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamWriter.xlsx")))
  63. // Test set cell column overflow.
  64. assert.EqualError(t, streamWriter.SetRow("XFD1", []interface{}{"A", "B", "C"}), ErrColumnNumber.Error())
  65. // Test close temporary file error.
  66. file = NewFile()
  67. streamWriter, err = file.NewStreamWriter("Sheet1")
  68. assert.NoError(t, err)
  69. for rowID := 10; rowID <= 25600; rowID++ {
  70. row := make([]interface{}, 50)
  71. for colID := 0; colID < 50; colID++ {
  72. row[colID] = rand.Intn(640000)
  73. }
  74. cell, _ := CoordinatesToCellName(1, rowID)
  75. assert.NoError(t, streamWriter.SetRow(cell, row))
  76. }
  77. assert.NoError(t, streamWriter.rawData.Close())
  78. assert.Error(t, streamWriter.Flush())
  79. streamWriter.rawData.tmp, err = ioutil.TempFile(os.TempDir(), "excelize-")
  80. assert.NoError(t, err)
  81. _, err = streamWriter.rawData.Reader()
  82. assert.NoError(t, err)
  83. assert.NoError(t, streamWriter.rawData.tmp.Close())
  84. assert.NoError(t, os.Remove(streamWriter.rawData.tmp.Name()))
  85. // Test unsupported charset
  86. file = NewFile()
  87. file.Sheet.Delete("xl/worksheets/sheet1.xml")
  88. file.Pkg.Store("xl/worksheets/sheet1.xml", MacintoshCyrillicCharset)
  89. _, err = file.NewStreamWriter("Sheet1")
  90. assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
  91. // Test read cell.
  92. file = NewFile()
  93. streamWriter, err = file.NewStreamWriter("Sheet1")
  94. assert.NoError(t, err)
  95. assert.NoError(t, streamWriter.SetRow("A1", []interface{}{Cell{StyleID: styleID, Value: "Data"}}))
  96. assert.NoError(t, streamWriter.Flush())
  97. cellValue, err := file.GetCellValue("Sheet1", "A1")
  98. assert.NoError(t, err)
  99. assert.Equal(t, "Data", cellValue)
  100. }
  101. func TestStreamSetColWidth(t *testing.T) {
  102. file := NewFile()
  103. streamWriter, err := file.NewStreamWriter("Sheet1")
  104. assert.NoError(t, err)
  105. assert.NoError(t, streamWriter.SetColWidth(3, 2, 20))
  106. assert.EqualError(t, streamWriter.SetColWidth(0, 3, 20), ErrColumnNumber.Error())
  107. assert.EqualError(t, streamWriter.SetColWidth(TotalColumns+1, 3, 20), ErrColumnNumber.Error())
  108. assert.EqualError(t, streamWriter.SetColWidth(1, 3, MaxColumnWidth+1), ErrColumnWidth.Error())
  109. assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
  110. assert.EqualError(t, streamWriter.SetColWidth(2, 3, 20), ErrStreamSetColWidth.Error())
  111. }
  112. func TestStreamTable(t *testing.T) {
  113. file := NewFile()
  114. streamWriter, err := file.NewStreamWriter("Sheet1")
  115. assert.NoError(t, err)
  116. // Write some rows. We want enough rows to force a temp file (>16MB).
  117. assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
  118. row := []interface{}{1, 2, 3}
  119. for r := 2; r < 10000; r++ {
  120. assert.NoError(t, streamWriter.SetRow(fmt.Sprintf("A%d", r), row))
  121. }
  122. // Write a table.
  123. assert.NoError(t, streamWriter.AddTable("A1", "C2", ``))
  124. assert.NoError(t, streamWriter.Flush())
  125. // Verify the table has names.
  126. var table xlsxTable
  127. val, ok := file.Pkg.Load("xl/tables/table1.xml")
  128. assert.True(t, ok)
  129. assert.NoError(t, xml.Unmarshal(val.([]byte), &table))
  130. assert.Equal(t, "A", table.TableColumns.TableColumn[0].Name)
  131. assert.Equal(t, "B", table.TableColumns.TableColumn[1].Name)
  132. assert.Equal(t, "C", table.TableColumns.TableColumn[2].Name)
  133. assert.NoError(t, streamWriter.AddTable("A1", "C1", ``))
  134. // Test add table with illegal formatset.
  135. assert.EqualError(t, streamWriter.AddTable("B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
  136. // Test add table with illegal cell coordinates.
  137. assert.EqualError(t, streamWriter.AddTable("A", "B1", `{}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  138. assert.EqualError(t, streamWriter.AddTable("A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
  139. }
  140. func TestStreamMergeCells(t *testing.T) {
  141. file := NewFile()
  142. streamWriter, err := file.NewStreamWriter("Sheet1")
  143. assert.NoError(t, err)
  144. assert.NoError(t, streamWriter.MergeCell("A1", "D1"))
  145. // Test merge cells with illegal cell coordinates.
  146. assert.EqualError(t, streamWriter.MergeCell("A", "D1"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  147. assert.NoError(t, streamWriter.Flush())
  148. // Save spreadsheet by the given path.
  149. assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamMergeCells.xlsx")))
  150. }
  151. func TestNewStreamWriter(t *testing.T) {
  152. // Test error exceptions
  153. file := NewFile()
  154. _, err := file.NewStreamWriter("Sheet1")
  155. assert.NoError(t, err)
  156. _, err = file.NewStreamWriter("SheetN")
  157. assert.EqualError(t, err, "sheet SheetN is not exist")
  158. }
  159. func TestSetRow(t *testing.T) {
  160. // Test error exceptions
  161. file := NewFile()
  162. streamWriter, err := file.NewStreamWriter("Sheet1")
  163. assert.NoError(t, err)
  164. assert.EqualError(t, streamWriter.SetRow("A", []interface{}{}), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  165. }
  166. func TestSetCellValFunc(t *testing.T) {
  167. c := &xlsxC{}
  168. assert.NoError(t, setCellValFunc(c, 128))
  169. assert.NoError(t, setCellValFunc(c, int8(-128)))
  170. assert.NoError(t, setCellValFunc(c, int16(-32768)))
  171. assert.NoError(t, setCellValFunc(c, int32(-2147483648)))
  172. assert.NoError(t, setCellValFunc(c, int64(-9223372036854775808)))
  173. assert.NoError(t, setCellValFunc(c, uint(128)))
  174. assert.NoError(t, setCellValFunc(c, uint8(255)))
  175. assert.NoError(t, setCellValFunc(c, uint16(65535)))
  176. assert.NoError(t, setCellValFunc(c, uint32(4294967295)))
  177. assert.NoError(t, setCellValFunc(c, uint64(18446744073709551615)))
  178. assert.NoError(t, setCellValFunc(c, float32(100.1588)))
  179. assert.NoError(t, setCellValFunc(c, float64(100.1588)))
  180. assert.NoError(t, setCellValFunc(c, " Hello"))
  181. assert.NoError(t, setCellValFunc(c, []byte(" Hello")))
  182. assert.NoError(t, setCellValFunc(c, time.Now().UTC()))
  183. assert.NoError(t, setCellValFunc(c, time.Duration(1e13)))
  184. assert.NoError(t, setCellValFunc(c, true))
  185. assert.NoError(t, setCellValFunc(c, nil))
  186. assert.NoError(t, setCellValFunc(c, complex64(5+10i)))
  187. }