stream_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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)"}}))
  48. assert.NoError(t, streamWriter.SetRow("A5", []interface{}{&Cell{StyleID: styleID, Value: "cell"}, &Cell{Formula: "SUM(A10,B10)"}}))
  49. assert.EqualError(t, streamWriter.SetRow("A6", []interface{}{time.Now()}), ErrToExcelTime.Error())
  50. for rowID := 10; rowID <= 51200; rowID++ {
  51. row := make([]interface{}, 50)
  52. for colID := 0; colID < 50; colID++ {
  53. row[colID] = rand.Intn(640000)
  54. }
  55. cell, _ := CoordinatesToCellName(1, rowID)
  56. assert.NoError(t, streamWriter.SetRow(cell, row))
  57. }
  58. assert.NoError(t, streamWriter.Flush())
  59. // Save spreadsheet by the given path.
  60. assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamWriter.xlsx")))
  61. // Test set cell column overflow.
  62. assert.EqualError(t, streamWriter.SetRow("XFD1", []interface{}{"A", "B", "C"}), ErrColumnNumber.Error())
  63. // Test close temporary file error.
  64. file = NewFile()
  65. streamWriter, err = file.NewStreamWriter("Sheet1")
  66. assert.NoError(t, err)
  67. for rowID := 10; rowID <= 25600; rowID++ {
  68. row := make([]interface{}, 50)
  69. for colID := 0; colID < 50; colID++ {
  70. row[colID] = rand.Intn(640000)
  71. }
  72. cell, _ := CoordinatesToCellName(1, rowID)
  73. assert.NoError(t, streamWriter.SetRow(cell, row))
  74. }
  75. assert.NoError(t, streamWriter.rawData.Close())
  76. assert.Error(t, streamWriter.Flush())
  77. streamWriter.rawData.tmp, err = ioutil.TempFile(os.TempDir(), "excelize-")
  78. assert.NoError(t, err)
  79. _, err = streamWriter.rawData.Reader()
  80. assert.NoError(t, err)
  81. assert.NoError(t, streamWriter.rawData.tmp.Close())
  82. assert.NoError(t, os.Remove(streamWriter.rawData.tmp.Name()))
  83. // Test unsupported charset
  84. file = NewFile()
  85. delete(file.Sheet, "xl/worksheets/sheet1.xml")
  86. file.XLSX["xl/worksheets/sheet1.xml"] = MacintoshCyrillicCharset
  87. _, err = file.NewStreamWriter("Sheet1")
  88. assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
  89. // Test read cell.
  90. file = NewFile()
  91. streamWriter, err = file.NewStreamWriter("Sheet1")
  92. assert.NoError(t, err)
  93. assert.NoError(t, streamWriter.SetRow("A1", []interface{}{Cell{StyleID: styleID, Value: "Data"}}))
  94. assert.NoError(t, streamWriter.Flush())
  95. cellValue, err := file.GetCellValue("Sheet1", "A1")
  96. assert.NoError(t, err)
  97. assert.Equal(t, "Data", cellValue)
  98. }
  99. func TestStreamSetColWidth(t *testing.T) {
  100. file := NewFile()
  101. streamWriter, err := file.NewStreamWriter("Sheet1")
  102. assert.NoError(t, err)
  103. assert.NoError(t, streamWriter.SetColWidth(3, 2, 20))
  104. assert.EqualError(t, streamWriter.SetColWidth(0, 3, 20), ErrColumnNumber.Error())
  105. assert.EqualError(t, streamWriter.SetColWidth(TotalColumns+1, 3, 20), ErrColumnNumber.Error())
  106. assert.EqualError(t, streamWriter.SetColWidth(1, 3, MaxColumnWidth+1), ErrColumnWidth.Error())
  107. assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
  108. assert.EqualError(t, streamWriter.SetColWidth(2, 3, 20), ErrStreamSetColWidth.Error())
  109. }
  110. func TestStreamTable(t *testing.T) {
  111. file := NewFile()
  112. streamWriter, err := file.NewStreamWriter("Sheet1")
  113. assert.NoError(t, err)
  114. // Write some rows. We want enough rows to force a temp file (>16MB).
  115. assert.NoError(t, streamWriter.SetRow("A1", []interface{}{"A", "B", "C"}))
  116. row := []interface{}{1, 2, 3}
  117. for r := 2; r < 10000; r++ {
  118. assert.NoError(t, streamWriter.SetRow(fmt.Sprintf("A%d", r), row))
  119. }
  120. // Write a table.
  121. assert.NoError(t, streamWriter.AddTable("A1", "C2", ``))
  122. assert.NoError(t, streamWriter.Flush())
  123. // Verify the table has names.
  124. var table xlsxTable
  125. assert.NoError(t, xml.Unmarshal(file.XLSX["xl/tables/table1.xml"], &table))
  126. assert.Equal(t, "A", table.TableColumns.TableColumn[0].Name)
  127. assert.Equal(t, "B", table.TableColumns.TableColumn[1].Name)
  128. assert.Equal(t, "C", table.TableColumns.TableColumn[2].Name)
  129. assert.NoError(t, streamWriter.AddTable("A1", "C1", ``))
  130. // Test add table with illegal formatset.
  131. assert.EqualError(t, streamWriter.AddTable("B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
  132. // Test add table with illegal cell coordinates.
  133. assert.EqualError(t, streamWriter.AddTable("A", "B1", `{}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  134. assert.EqualError(t, streamWriter.AddTable("A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
  135. }
  136. func TestStreamMergeCells(t *testing.T) {
  137. file := NewFile()
  138. streamWriter, err := file.NewStreamWriter("Sheet1")
  139. assert.NoError(t, err)
  140. assert.NoError(t, streamWriter.MergeCell("A1", "D1"))
  141. // Test merge cells with illegal cell coordinates.
  142. assert.EqualError(t, streamWriter.MergeCell("A", "D1"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  143. assert.NoError(t, streamWriter.Flush())
  144. // Save spreadsheet by the given path.
  145. assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamMergeCells.xlsx")))
  146. }
  147. func TestNewStreamWriter(t *testing.T) {
  148. // Test error exceptions
  149. file := NewFile()
  150. _, err := file.NewStreamWriter("Sheet1")
  151. assert.NoError(t, err)
  152. _, err = file.NewStreamWriter("SheetN")
  153. assert.EqualError(t, err, "sheet SheetN is not exist")
  154. }
  155. func TestSetRow(t *testing.T) {
  156. // Test error exceptions
  157. file := NewFile()
  158. streamWriter, err := file.NewStreamWriter("Sheet1")
  159. assert.NoError(t, err)
  160. assert.EqualError(t, streamWriter.SetRow("A", []interface{}{}), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  161. }
  162. func TestSetCellValFunc(t *testing.T) {
  163. c := &xlsxC{}
  164. assert.NoError(t, setCellValFunc(c, 128))
  165. assert.NoError(t, setCellValFunc(c, int8(-128)))
  166. assert.NoError(t, setCellValFunc(c, int16(-32768)))
  167. assert.NoError(t, setCellValFunc(c, int32(-2147483648)))
  168. assert.NoError(t, setCellValFunc(c, int64(-9223372036854775808)))
  169. assert.NoError(t, setCellValFunc(c, uint(128)))
  170. assert.NoError(t, setCellValFunc(c, uint8(255)))
  171. assert.NoError(t, setCellValFunc(c, uint16(65535)))
  172. assert.NoError(t, setCellValFunc(c, uint32(4294967295)))
  173. assert.NoError(t, setCellValFunc(c, uint64(18446744073709551615)))
  174. assert.NoError(t, setCellValFunc(c, float32(100.1588)))
  175. assert.NoError(t, setCellValFunc(c, float64(100.1588)))
  176. assert.NoError(t, setCellValFunc(c, " Hello"))
  177. assert.NoError(t, setCellValFunc(c, []byte(" Hello")))
  178. assert.NoError(t, setCellValFunc(c, time.Now().UTC()))
  179. assert.NoError(t, setCellValFunc(c, time.Duration(1e13)))
  180. assert.NoError(t, setCellValFunc(c, true))
  181. assert.NoError(t, setCellValFunc(c, nil))
  182. assert.NoError(t, setCellValFunc(c, complex64(5+10i)))
  183. }