pivotTable_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package excelize
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "path/filepath"
  6. "strings"
  7. "testing"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. func TestAddPivotTable(t *testing.T) {
  11. f := NewFile()
  12. // Create some data in a sheet
  13. month := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
  14. year := []int{2017, 2018, 2019}
  15. types := []string{"Meat", "Dairy", "Beverages", "Produce"}
  16. region := []string{"East", "West", "North", "South"}
  17. assert.NoError(t, f.SetSheetRow("Sheet1", "A1", &[]string{"Month", "Year", "Type", "Sales", "Region"}))
  18. for i := 0; i < 30; i++ {
  19. assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("A%d", i+2), month[rand.Intn(12)]))
  20. assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("B%d", i+2), year[rand.Intn(3)]))
  21. assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("C%d", i+2), types[rand.Intn(4)]))
  22. assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("D%d", i+2), rand.Intn(5000)))
  23. assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+2), region[rand.Intn(4)]))
  24. }
  25. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  26. DataRange: "Sheet1!$A$1:$E$31",
  27. PivotTableRange: "Sheet1!$G$2:$M$34",
  28. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  29. Filter: []PivotTableField{{Data: "Region"}},
  30. Columns: []PivotTableField{{Data: "Type"}},
  31. Data: []PivotTableField{{Data: "Sales", Subtotal: "Sum", Name: "Summarize by Sum"}},
  32. }))
  33. // Use different order of coordinate tests
  34. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  35. DataRange: "Sheet1!$A$1:$E$31",
  36. PivotTableRange: "Sheet1!$U$34:$O$2",
  37. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  38. Columns: []PivotTableField{{Data: "Type"}},
  39. Data: []PivotTableField{{Data: "Sales", Subtotal: "Average", Name: "Summarize by Average"}},
  40. }))
  41. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  42. DataRange: "Sheet1!$A$1:$E$31",
  43. PivotTableRange: "Sheet1!$W$2:$AC$34",
  44. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  45. Columns: []PivotTableField{{Data: "Region"}},
  46. Data: []PivotTableField{{Data: "Sales", Subtotal: "Count", Name: "Summarize by Count"}},
  47. }))
  48. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  49. DataRange: "Sheet1!$A$1:$E$31",
  50. PivotTableRange: "Sheet1!$G$37:$W$50",
  51. Rows: []PivotTableField{{Data: "Month"}},
  52. Columns: []PivotTableField{{Data: "Region"}, {Data: "Year"}},
  53. Data: []PivotTableField{{Data: "Sales", Subtotal: "CountNums", Name: "Summarize by CountNums"}},
  54. }))
  55. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  56. DataRange: "Sheet1!$A$1:$E$31",
  57. PivotTableRange: "Sheet1!$AE$2:$AG$33",
  58. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  59. Data: []PivotTableField{{Data: "Sales", Subtotal: "Max", Name: "Summarize by Max"}},
  60. }))
  61. f.NewSheet("Sheet2")
  62. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  63. DataRange: "Sheet1!$A$1:$E$31",
  64. PivotTableRange: "Sheet2!$A$1:$AR$15",
  65. Rows: []PivotTableField{{Data: "Month"}},
  66. Columns: []PivotTableField{{Data: "Region"}, {Data: "Type"}, {Data: "Year"}},
  67. Data: []PivotTableField{{Data: "Sales", Subtotal: "Min", Name: "Summarize by Min"}},
  68. }))
  69. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  70. DataRange: "Sheet1!$A$1:$E$31",
  71. PivotTableRange: "Sheet2!$A$18:$AR$54",
  72. Rows: []PivotTableField{{Data: "Month"}, {Data: "Type"}},
  73. Columns: []PivotTableField{{Data: "Region"}, {Data: "Year"}},
  74. Data: []PivotTableField{{Data: "Sales", Subtotal: "Product", Name: "Summarize by Product"}},
  75. }))
  76. // Test empty pivot table options
  77. assert.EqualError(t, f.AddPivotTable(nil), "parameter is required")
  78. // Test invalid data range
  79. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  80. DataRange: "Sheet1!$A$1:$A$1",
  81. PivotTableRange: "Sheet1!$U$34:$O$2",
  82. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  83. Columns: []PivotTableField{{Data: "Type"}},
  84. Data: []PivotTableField{{Data: "Sales"}},
  85. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  86. // Test the data range of the worksheet that is not declared
  87. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  88. DataRange: "$A$1:$E$31",
  89. PivotTableRange: "Sheet1!$U$34:$O$2",
  90. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  91. Columns: []PivotTableField{{Data: "Type"}},
  92. Data: []PivotTableField{{Data: "Sales"}},
  93. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  94. // Test the worksheet declared in the data range does not exist
  95. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  96. DataRange: "SheetN!$A$1:$E$31",
  97. PivotTableRange: "Sheet1!$U$34:$O$2",
  98. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  99. Columns: []PivotTableField{{Data: "Type"}},
  100. Data: []PivotTableField{{Data: "Sales"}},
  101. }), "sheet SheetN is not exist")
  102. // Test the pivot table range of the worksheet that is not declared
  103. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  104. DataRange: "Sheet1!$A$1:$E$31",
  105. PivotTableRange: "$U$34:$O$2",
  106. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  107. Columns: []PivotTableField{{Data: "Type"}},
  108. Data: []PivotTableField{{Data: "Sales"}},
  109. }), `parameter 'PivotTableRange' parsing error: parameter is invalid`)
  110. // Test the worksheet declared in the pivot table range does not exist
  111. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  112. DataRange: "Sheet1!$A$1:$E$31",
  113. PivotTableRange: "SheetN!$U$34:$O$2",
  114. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  115. Columns: []PivotTableField{{Data: "Type"}},
  116. Data: []PivotTableField{{Data: "Sales"}},
  117. }), "sheet SheetN is not exist")
  118. // Test not exists worksheet in data range
  119. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  120. DataRange: "SheetN!$A$1:$E$31",
  121. PivotTableRange: "Sheet1!$U$34:$O$2",
  122. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  123. Columns: []PivotTableField{{Data: "Type"}},
  124. Data: []PivotTableField{{Data: "Sales"}},
  125. }), "sheet SheetN is not exist")
  126. // Test invalid row number in data range
  127. assert.EqualError(t, f.AddPivotTable(&PivotTableOption{
  128. DataRange: "Sheet1!$A$0:$E$31",
  129. PivotTableRange: "Sheet1!$U$34:$O$2",
  130. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  131. Columns: []PivotTableField{{Data: "Type"}},
  132. Data: []PivotTableField{{Data: "Sales"}},
  133. }), `parameter 'DataRange' parsing error: cannot convert cell "A0" to coordinates: invalid cell name "A0"`)
  134. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPivotTable1.xlsx")))
  135. // Test with field names that exceed the length limit and invalid subtotal
  136. assert.NoError(t, f.AddPivotTable(&PivotTableOption{
  137. DataRange: "Sheet1!$A$1:$E$31",
  138. PivotTableRange: "Sheet1!$G$2:$M$34",
  139. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  140. Columns: []PivotTableField{{Data: "Type"}},
  141. Data: []PivotTableField{{Data: "Sales", Subtotal: "-", Name: strings.Repeat("s", 256)}},
  142. }))
  143. // Test adjust range with invalid range
  144. _, _, err := f.adjustRange("")
  145. assert.EqualError(t, err, "parameter is required")
  146. // Test get pivot fields order with empty data range
  147. _, err = f.getPivotFieldsOrder("")
  148. assert.EqualError(t, err, `parameter 'DataRange' parsing error: parameter is required`)
  149. // Test add pivot cache with empty data range
  150. assert.EqualError(t, f.addPivotCache(0, "", &PivotTableOption{}, nil), "parameter 'DataRange' parsing error: parameter is required")
  151. // Test add pivot cache with invalid data range
  152. assert.EqualError(t, f.addPivotCache(0, "", &PivotTableOption{
  153. DataRange: "$A$1:$E$31",
  154. PivotTableRange: "Sheet1!$U$34:$O$2",
  155. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  156. Columns: []PivotTableField{{Data: "Type"}},
  157. Data: []PivotTableField{{Data: "Sales"}},
  158. }, nil), "parameter 'DataRange' parsing error: parameter is invalid")
  159. // Test add pivot table with empty options
  160. assert.EqualError(t, f.addPivotTable(0, 0, "", &PivotTableOption{}), "parameter 'PivotTableRange' parsing error: parameter is required")
  161. // Test add pivot table with invalid data range
  162. assert.EqualError(t, f.addPivotTable(0, 0, "", &PivotTableOption{}), "parameter 'PivotTableRange' parsing error: parameter is required")
  163. // Test add pivot fields with empty data range
  164. assert.EqualError(t, f.addPivotFields(nil, &PivotTableOption{
  165. DataRange: "$A$1:$E$31",
  166. PivotTableRange: "Sheet1!$U$34:$O$2",
  167. Rows: []PivotTableField{{Data: "Month"}, {Data: "Year"}},
  168. Columns: []PivotTableField{{Data: "Type"}},
  169. Data: []PivotTableField{{Data: "Sales"}},
  170. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  171. // Test get pivot fields index with empty data range
  172. _, err = f.getPivotFieldsIndex([]PivotTableField{}, &PivotTableOption{})
  173. assert.EqualError(t, err, `parameter 'DataRange' parsing error: parameter is required`)
  174. }
  175. func TestAddPivotRowFields(t *testing.T) {
  176. f := NewFile()
  177. // Test invalid data range
  178. assert.EqualError(t, f.addPivotRowFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
  179. DataRange: "Sheet1!$A$1:$A$1",
  180. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  181. }
  182. func TestAddPivotPageFields(t *testing.T) {
  183. f := NewFile()
  184. // Test invalid data range
  185. assert.EqualError(t, f.addPivotPageFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
  186. DataRange: "Sheet1!$A$1:$A$1",
  187. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  188. }
  189. func TestAddPivotDataFields(t *testing.T) {
  190. f := NewFile()
  191. // Test invalid data range
  192. assert.EqualError(t, f.addPivotDataFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
  193. DataRange: "Sheet1!$A$1:$A$1",
  194. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  195. }
  196. func TestAddPivotColFields(t *testing.T) {
  197. f := NewFile()
  198. // Test invalid data range
  199. assert.EqualError(t, f.addPivotColFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
  200. DataRange: "Sheet1!$A$1:$A$1",
  201. Columns: []PivotTableField{{Data: "Type"}},
  202. }), `parameter 'DataRange' parsing error: parameter is invalid`)
  203. }
  204. func TestGetPivotFieldsOrder(t *testing.T) {
  205. f := NewFile()
  206. // Test get pivot fields order with not exist worksheet
  207. _, err := f.getPivotFieldsOrder("SheetN!$A$1:$E$31")
  208. assert.EqualError(t, err, "sheet SheetN is not exist")
  209. }
  210. func TestInStrSlice(t *testing.T) {
  211. assert.EqualValues(t, -1, inStrSlice([]string{}, ""))
  212. }
  213. func TestGetPivotTableFieldName(t *testing.T) {
  214. f := NewFile()
  215. f.getPivotTableFieldName("-", []PivotTableField{})
  216. }