rows_test.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. package excelize
  2. import (
  3. "bytes"
  4. "fmt"
  5. "path/filepath"
  6. "testing"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. )
  10. func TestRows(t *testing.T) {
  11. const sheet2 = "Sheet2"
  12. f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  13. if !assert.NoError(t, err) {
  14. t.FailNow()
  15. }
  16. rows, err := f.Rows(sheet2)
  17. if !assert.NoError(t, err) {
  18. t.FailNow()
  19. }
  20. var collectedRows [][]string
  21. for rows.Next() {
  22. columns, err := rows.Columns()
  23. assert.NoError(t, err)
  24. collectedRows = append(collectedRows, trimSliceSpace(columns))
  25. }
  26. if !assert.NoError(t, rows.Error()) {
  27. t.FailNow()
  28. }
  29. returnedRows, err := f.GetRows(sheet2)
  30. assert.NoError(t, err)
  31. for i := range returnedRows {
  32. returnedRows[i] = trimSliceSpace(returnedRows[i])
  33. }
  34. if !assert.Equal(t, collectedRows, returnedRows) {
  35. t.FailNow()
  36. }
  37. f = NewFile()
  38. f.XLSX["xl/worksheets/sheet1.xml"] = []byte(`<worksheet><sheetData><row r="1"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)
  39. _, err = f.Rows("Sheet1")
  40. assert.EqualError(t, err, `strconv.Atoi: parsing "A": invalid syntax`)
  41. f.XLSX["xl/worksheets/sheet1.xml"] = nil
  42. _, err = f.Rows("Sheet1")
  43. assert.NoError(t, err)
  44. }
  45. func TestRowsIterator(t *testing.T) {
  46. const (
  47. sheet2 = "Sheet2"
  48. expectedNumRow = 11
  49. )
  50. f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  51. require.NoError(t, err)
  52. rows, err := f.Rows(sheet2)
  53. require.NoError(t, err)
  54. var rowCount int
  55. for rows.Next() {
  56. rowCount++
  57. require.True(t, rowCount <= expectedNumRow, "rowCount is greater than expected")
  58. }
  59. assert.Equal(t, expectedNumRow, rowCount)
  60. // Valued cell sparse distribution test
  61. f = NewFile()
  62. cells := []string{"C1", "E1", "A3", "B3", "C3", "D3", "E3"}
  63. for _, cell := range cells {
  64. assert.NoError(t, f.SetCellValue("Sheet1", cell, 1))
  65. }
  66. rows, err = f.Rows("Sheet1")
  67. require.NoError(t, err)
  68. rowCount = 0
  69. for rows.Next() {
  70. rowCount++
  71. require.True(t, rowCount <= 3, "rowCount is greater than expected")
  72. }
  73. assert.Equal(t, 3, rowCount)
  74. }
  75. func TestRowsError(t *testing.T) {
  76. f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  77. if !assert.NoError(t, err) {
  78. t.FailNow()
  79. }
  80. _, err = f.Rows("SheetN")
  81. assert.EqualError(t, err, "sheet SheetN is not exist")
  82. }
  83. func TestRowHeight(t *testing.T) {
  84. f := NewFile()
  85. sheet1 := f.GetSheetName(0)
  86. assert.EqualError(t, f.SetRowHeight(sheet1, 0, defaultRowHeightPixels+1.0), "invalid row number 0")
  87. _, err := f.GetRowHeight("Sheet1", 0)
  88. assert.EqualError(t, err, "invalid row number 0")
  89. assert.NoError(t, f.SetRowHeight(sheet1, 1, 111.0))
  90. height, err := f.GetRowHeight(sheet1, 1)
  91. assert.NoError(t, err)
  92. assert.Equal(t, 111.0, height)
  93. // Test set row height overflow max row height limit.
  94. assert.EqualError(t, f.SetRowHeight(sheet1, 4, MaxRowHeight+1), "the height of the row must be smaller than or equal to 409 points")
  95. // Test get row height that rows index over exists rows.
  96. height, err = f.GetRowHeight(sheet1, 5)
  97. assert.NoError(t, err)
  98. assert.Equal(t, defaultRowHeight, height)
  99. // Test get row height that rows heights haven't changed.
  100. height, err = f.GetRowHeight(sheet1, 3)
  101. assert.NoError(t, err)
  102. assert.Equal(t, defaultRowHeight, height)
  103. // Test set and get row height on not exists worksheet.
  104. assert.EqualError(t, f.SetRowHeight("SheetN", 1, 111.0), "sheet SheetN is not exist")
  105. _, err = f.GetRowHeight("SheetN", 3)
  106. assert.EqualError(t, err, "sheet SheetN is not exist")
  107. // Test get row height with custom default row height.
  108. assert.NoError(t, f.SetSheetFormatPr(sheet1,
  109. DefaultRowHeight(30.0),
  110. CustomHeight(true),
  111. ))
  112. height, err = f.GetRowHeight(sheet1, 100)
  113. assert.NoError(t, err)
  114. assert.Equal(t, 30.0, height)
  115. // Test set row height with custom default row height with prepare XML.
  116. assert.NoError(t, f.SetCellValue(sheet1, "A10", "A10"))
  117. err = f.SaveAs(filepath.Join("test", "TestRowHeight.xlsx"))
  118. if !assert.NoError(t, err) {
  119. t.FailNow()
  120. }
  121. convertColWidthToPixels(0)
  122. }
  123. func TestColumns(t *testing.T) {
  124. f := NewFile()
  125. rows, err := f.Rows("Sheet1")
  126. assert.NoError(t, err)
  127. rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="2"><c r="A1" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
  128. _, err = rows.Columns()
  129. assert.NoError(t, err)
  130. rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="2"><c r="A1" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
  131. rows.curRow = 1
  132. _, err = rows.Columns()
  133. assert.NoError(t, err)
  134. rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="A"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)))
  135. rows.stashRow, rows.curRow = 0, 1
  136. _, err = rows.Columns()
  137. assert.EqualError(t, err, `strconv.Atoi: parsing "A": invalid syntax`)
  138. rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="1"><c r="A1" t="s"><v>1</v></c></row><row r="A"><c r="2" t="str"><v>B</v></c></row></sheetData></worksheet>`)))
  139. _, err = rows.Columns()
  140. assert.NoError(t, err)
  141. rows.curRow = 3
  142. rows.decoder = f.xmlNewDecoder(bytes.NewReader([]byte(`<worksheet><sheetData><row r="1"><c r="A" t="s"><v>1</v></c></row></sheetData></worksheet>`)))
  143. _, err = rows.Columns()
  144. assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  145. // Test token is nil
  146. rows.decoder = f.xmlNewDecoder(bytes.NewReader(nil))
  147. _, err = rows.Columns()
  148. assert.NoError(t, err)
  149. }
  150. func TestSharedStringsReader(t *testing.T) {
  151. f := NewFile()
  152. f.XLSX["xl/sharedStrings.xml"] = MacintoshCyrillicCharset
  153. f.sharedStringsReader()
  154. si := xlsxSI{}
  155. assert.EqualValues(t, "", si.String())
  156. }
  157. func TestRowVisibility(t *testing.T) {
  158. f, err := prepareTestBook1()
  159. if !assert.NoError(t, err) {
  160. t.FailNow()
  161. }
  162. f.NewSheet("Sheet3")
  163. assert.NoError(t, f.SetRowVisible("Sheet3", 2, false))
  164. assert.NoError(t, f.SetRowVisible("Sheet3", 2, true))
  165. visiable, err := f.GetRowVisible("Sheet3", 2)
  166. assert.Equal(t, true, visiable)
  167. assert.NoError(t, err)
  168. visiable, err = f.GetRowVisible("Sheet3", 25)
  169. assert.Equal(t, false, visiable)
  170. assert.NoError(t, err)
  171. assert.EqualError(t, f.SetRowVisible("Sheet3", 0, true), "invalid row number 0")
  172. assert.EqualError(t, f.SetRowVisible("SheetN", 2, false), "sheet SheetN is not exist")
  173. visible, err := f.GetRowVisible("Sheet3", 0)
  174. assert.Equal(t, false, visible)
  175. assert.EqualError(t, err, "invalid row number 0")
  176. _, err = f.GetRowVisible("SheetN", 1)
  177. assert.EqualError(t, err, "sheet SheetN is not exist")
  178. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestRowVisibility.xlsx")))
  179. }
  180. func TestRemoveRow(t *testing.T) {
  181. f := NewFile()
  182. sheet1 := f.GetSheetName(0)
  183. r, err := f.workSheetReader(sheet1)
  184. assert.NoError(t, err)
  185. const (
  186. colCount = 10
  187. rowCount = 10
  188. )
  189. fillCells(f, sheet1, colCount, rowCount)
  190. assert.NoError(t, f.SetCellHyperLink(sheet1, "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
  191. assert.EqualError(t, f.RemoveRow(sheet1, -1), "invalid row number -1")
  192. assert.EqualError(t, f.RemoveRow(sheet1, 0), "invalid row number 0")
  193. assert.NoError(t, f.RemoveRow(sheet1, 4))
  194. if !assert.Len(t, r.SheetData.Row, rowCount-1) {
  195. t.FailNow()
  196. }
  197. assert.NoError(t, f.MergeCell(sheet1, "B3", "B5"))
  198. assert.NoError(t, f.RemoveRow(sheet1, 2))
  199. if !assert.Len(t, r.SheetData.Row, rowCount-2) {
  200. t.FailNow()
  201. }
  202. assert.NoError(t, f.RemoveRow(sheet1, 4))
  203. if !assert.Len(t, r.SheetData.Row, rowCount-3) {
  204. t.FailNow()
  205. }
  206. err = f.AutoFilter(sheet1, "A2", "A2", `{"column":"A","expression":"x != blanks"}`)
  207. if !assert.NoError(t, err) {
  208. t.FailNow()
  209. }
  210. assert.NoError(t, f.RemoveRow(sheet1, 1))
  211. if !assert.Len(t, r.SheetData.Row, rowCount-4) {
  212. t.FailNow()
  213. }
  214. assert.NoError(t, f.RemoveRow(sheet1, 2))
  215. if !assert.Len(t, r.SheetData.Row, rowCount-5) {
  216. t.FailNow()
  217. }
  218. assert.NoError(t, f.RemoveRow(sheet1, 1))
  219. if !assert.Len(t, r.SheetData.Row, rowCount-6) {
  220. t.FailNow()
  221. }
  222. assert.NoError(t, f.RemoveRow(sheet1, 10))
  223. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestRemoveRow.xlsx")))
  224. // Test remove row on not exist worksheet
  225. assert.EqualError(t, f.RemoveRow("SheetN", 1), `sheet SheetN is not exist`)
  226. }
  227. func TestInsertRow(t *testing.T) {
  228. f := NewFile()
  229. sheet1 := f.GetSheetName(0)
  230. r, err := f.workSheetReader(sheet1)
  231. assert.NoError(t, err)
  232. const (
  233. colCount = 10
  234. rowCount = 10
  235. )
  236. fillCells(f, sheet1, colCount, rowCount)
  237. assert.NoError(t, f.SetCellHyperLink(sheet1, "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
  238. assert.EqualError(t, f.InsertRow(sheet1, -1), "invalid row number -1")
  239. assert.EqualError(t, f.InsertRow(sheet1, 0), "invalid row number 0")
  240. assert.NoError(t, f.InsertRow(sheet1, 1))
  241. if !assert.Len(t, r.SheetData.Row, rowCount+1) {
  242. t.FailNow()
  243. }
  244. assert.NoError(t, f.InsertRow(sheet1, 4))
  245. if !assert.Len(t, r.SheetData.Row, rowCount+2) {
  246. t.FailNow()
  247. }
  248. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertRow.xlsx")))
  249. }
  250. // Testing internal sructure state after insert operations.
  251. // It is important for insert workflow to be constant to avoid side effect with functions related to internal structure.
  252. func TestInsertRowInEmptyFile(t *testing.T) {
  253. f := NewFile()
  254. sheet1 := f.GetSheetName(0)
  255. r, err := f.workSheetReader(sheet1)
  256. assert.NoError(t, err)
  257. assert.NoError(t, f.InsertRow(sheet1, 1))
  258. assert.Len(t, r.SheetData.Row, 0)
  259. assert.NoError(t, f.InsertRow(sheet1, 2))
  260. assert.Len(t, r.SheetData.Row, 0)
  261. assert.NoError(t, f.InsertRow(sheet1, 99))
  262. assert.Len(t, r.SheetData.Row, 0)
  263. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertRowInEmptyFile.xlsx")))
  264. }
  265. func TestDuplicateRowFromSingleRow(t *testing.T) {
  266. const sheet = "Sheet1"
  267. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  268. cells := map[string]string{
  269. "A1": "A1 Value",
  270. "A2": "A2 Value",
  271. "A3": "A3 Value",
  272. "B1": "B1 Value",
  273. "B2": "B2 Value",
  274. "B3": "B3 Value",
  275. }
  276. t.Run("FromSingleRow", func(t *testing.T) {
  277. f := NewFile()
  278. assert.NoError(t, f.SetCellStr(sheet, "A1", cells["A1"]))
  279. assert.NoError(t, f.SetCellStr(sheet, "B1", cells["B1"]))
  280. assert.NoError(t, f.DuplicateRow(sheet, 1))
  281. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "FromSingleRow_1"))) {
  282. t.FailNow()
  283. }
  284. expect := map[string]string{
  285. "A1": cells["A1"], "B1": cells["B1"],
  286. "A2": cells["A1"], "B2": cells["B1"],
  287. }
  288. for cell, val := range expect {
  289. v, err := f.GetCellValue(sheet, cell)
  290. assert.NoError(t, err)
  291. if !assert.Equal(t, val, v, cell) {
  292. t.FailNow()
  293. }
  294. }
  295. assert.NoError(t, f.DuplicateRow(sheet, 2))
  296. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "FromSingleRow_2"))) {
  297. t.FailNow()
  298. }
  299. expect = map[string]string{
  300. "A1": cells["A1"], "B1": cells["B1"],
  301. "A2": cells["A1"], "B2": cells["B1"],
  302. "A3": cells["A1"], "B3": cells["B1"],
  303. }
  304. for cell, val := range expect {
  305. v, err := f.GetCellValue(sheet, cell)
  306. assert.NoError(t, err)
  307. if !assert.Equal(t, val, v, cell) {
  308. t.FailNow()
  309. }
  310. }
  311. })
  312. }
  313. func TestDuplicateRowUpdateDuplicatedRows(t *testing.T) {
  314. const sheet = "Sheet1"
  315. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  316. cells := map[string]string{
  317. "A1": "A1 Value",
  318. "A2": "A2 Value",
  319. "A3": "A3 Value",
  320. "B1": "B1 Value",
  321. "B2": "B2 Value",
  322. "B3": "B3 Value",
  323. }
  324. t.Run("UpdateDuplicatedRows", func(t *testing.T) {
  325. f := NewFile()
  326. assert.NoError(t, f.SetCellStr(sheet, "A1", cells["A1"]))
  327. assert.NoError(t, f.SetCellStr(sheet, "B1", cells["B1"]))
  328. assert.NoError(t, f.DuplicateRow(sheet, 1))
  329. assert.NoError(t, f.SetCellStr(sheet, "A2", cells["A2"]))
  330. assert.NoError(t, f.SetCellStr(sheet, "B2", cells["B2"]))
  331. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "UpdateDuplicatedRows"))) {
  332. t.FailNow()
  333. }
  334. expect := map[string]string{
  335. "A1": cells["A1"], "B1": cells["B1"],
  336. "A2": cells["A2"], "B2": cells["B2"],
  337. }
  338. for cell, val := range expect {
  339. v, err := f.GetCellValue(sheet, cell)
  340. assert.NoError(t, err)
  341. if !assert.Equal(t, val, v, cell) {
  342. t.FailNow()
  343. }
  344. }
  345. })
  346. }
  347. func TestDuplicateRowFirstOfMultipleRows(t *testing.T) {
  348. const sheet = "Sheet1"
  349. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  350. cells := map[string]string{
  351. "A1": "A1 Value",
  352. "A2": "A2 Value",
  353. "A3": "A3 Value",
  354. "B1": "B1 Value",
  355. "B2": "B2 Value",
  356. "B3": "B3 Value",
  357. }
  358. newFileWithDefaults := func() *File {
  359. f := NewFile()
  360. for cell, val := range cells {
  361. assert.NoError(t, f.SetCellStr(sheet, cell, val))
  362. }
  363. return f
  364. }
  365. t.Run("FirstOfMultipleRows", func(t *testing.T) {
  366. f := newFileWithDefaults()
  367. assert.NoError(t, f.DuplicateRow(sheet, 1))
  368. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "FirstOfMultipleRows"))) {
  369. t.FailNow()
  370. }
  371. expect := map[string]string{
  372. "A1": cells["A1"], "B1": cells["B1"],
  373. "A2": cells["A1"], "B2": cells["B1"],
  374. "A3": cells["A2"], "B3": cells["B2"],
  375. "A4": cells["A3"], "B4": cells["B3"],
  376. }
  377. for cell, val := range expect {
  378. v, err := f.GetCellValue(sheet, cell)
  379. assert.NoError(t, err)
  380. if !assert.Equal(t, val, v, cell) {
  381. t.FailNow()
  382. }
  383. }
  384. })
  385. }
  386. func TestDuplicateRowZeroWithNoRows(t *testing.T) {
  387. const sheet = "Sheet1"
  388. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  389. t.Run("ZeroWithNoRows", func(t *testing.T) {
  390. f := NewFile()
  391. assert.EqualError(t, f.DuplicateRow(sheet, 0), "invalid row number 0")
  392. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "ZeroWithNoRows"))) {
  393. t.FailNow()
  394. }
  395. val, err := f.GetCellValue(sheet, "A1")
  396. assert.NoError(t, err)
  397. assert.Equal(t, "", val)
  398. val, err = f.GetCellValue(sheet, "B1")
  399. assert.NoError(t, err)
  400. assert.Equal(t, "", val)
  401. val, err = f.GetCellValue(sheet, "A2")
  402. assert.NoError(t, err)
  403. assert.Equal(t, "", val)
  404. val, err = f.GetCellValue(sheet, "B2")
  405. assert.NoError(t, err)
  406. assert.Equal(t, "", val)
  407. assert.NoError(t, err)
  408. expect := map[string]string{
  409. "A1": "", "B1": "",
  410. "A2": "", "B2": "",
  411. }
  412. for cell, val := range expect {
  413. v, err := f.GetCellValue(sheet, cell)
  414. assert.NoError(t, err)
  415. if !assert.Equal(t, val, v, cell) {
  416. t.FailNow()
  417. }
  418. }
  419. })
  420. }
  421. func TestDuplicateRowMiddleRowOfEmptyFile(t *testing.T) {
  422. const sheet = "Sheet1"
  423. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  424. t.Run("MiddleRowOfEmptyFile", func(t *testing.T) {
  425. f := NewFile()
  426. assert.NoError(t, f.DuplicateRow(sheet, 99))
  427. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "MiddleRowOfEmptyFile"))) {
  428. t.FailNow()
  429. }
  430. expect := map[string]string{
  431. "A98": "",
  432. "A99": "",
  433. "A100": "",
  434. }
  435. for cell, val := range expect {
  436. v, err := f.GetCellValue(sheet, cell)
  437. assert.NoError(t, err)
  438. if !assert.Equal(t, val, v, cell) {
  439. t.FailNow()
  440. }
  441. }
  442. })
  443. }
  444. func TestDuplicateRowWithLargeOffsetToMiddleOfData(t *testing.T) {
  445. const sheet = "Sheet1"
  446. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  447. cells := map[string]string{
  448. "A1": "A1 Value",
  449. "A2": "A2 Value",
  450. "A3": "A3 Value",
  451. "B1": "B1 Value",
  452. "B2": "B2 Value",
  453. "B3": "B3 Value",
  454. }
  455. newFileWithDefaults := func() *File {
  456. f := NewFile()
  457. for cell, val := range cells {
  458. assert.NoError(t, f.SetCellStr(sheet, cell, val))
  459. }
  460. return f
  461. }
  462. t.Run("WithLargeOffsetToMiddleOfData", func(t *testing.T) {
  463. f := newFileWithDefaults()
  464. assert.NoError(t, f.DuplicateRowTo(sheet, 1, 3))
  465. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "WithLargeOffsetToMiddleOfData"))) {
  466. t.FailNow()
  467. }
  468. expect := map[string]string{
  469. "A1": cells["A1"], "B1": cells["B1"],
  470. "A2": cells["A2"], "B2": cells["B2"],
  471. "A3": cells["A1"], "B3": cells["B1"],
  472. "A4": cells["A3"], "B4": cells["B3"],
  473. }
  474. for cell, val := range expect {
  475. v, err := f.GetCellValue(sheet, cell)
  476. assert.NoError(t, err)
  477. if !assert.Equal(t, val, v, cell) {
  478. t.FailNow()
  479. }
  480. }
  481. })
  482. }
  483. func TestDuplicateRowWithLargeOffsetToEmptyRows(t *testing.T) {
  484. const sheet = "Sheet1"
  485. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  486. cells := map[string]string{
  487. "A1": "A1 Value",
  488. "A2": "A2 Value",
  489. "A3": "A3 Value",
  490. "B1": "B1 Value",
  491. "B2": "B2 Value",
  492. "B3": "B3 Value",
  493. }
  494. newFileWithDefaults := func() *File {
  495. f := NewFile()
  496. for cell, val := range cells {
  497. assert.NoError(t, f.SetCellStr(sheet, cell, val))
  498. }
  499. return f
  500. }
  501. t.Run("WithLargeOffsetToEmptyRows", func(t *testing.T) {
  502. f := newFileWithDefaults()
  503. assert.NoError(t, f.DuplicateRowTo(sheet, 1, 7))
  504. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "WithLargeOffsetToEmptyRows"))) {
  505. t.FailNow()
  506. }
  507. expect := map[string]string{
  508. "A1": cells["A1"], "B1": cells["B1"],
  509. "A2": cells["A2"], "B2": cells["B2"],
  510. "A3": cells["A3"], "B3": cells["B3"],
  511. "A7": cells["A1"], "B7": cells["B1"],
  512. }
  513. for cell, val := range expect {
  514. v, err := f.GetCellValue(sheet, cell)
  515. assert.NoError(t, err)
  516. if !assert.Equal(t, val, v, cell) {
  517. t.FailNow()
  518. }
  519. }
  520. })
  521. }
  522. func TestDuplicateRowInsertBefore(t *testing.T) {
  523. const sheet = "Sheet1"
  524. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  525. cells := map[string]string{
  526. "A1": "A1 Value",
  527. "A2": "A2 Value",
  528. "A3": "A3 Value",
  529. "B1": "B1 Value",
  530. "B2": "B2 Value",
  531. "B3": "B3 Value",
  532. }
  533. newFileWithDefaults := func() *File {
  534. f := NewFile()
  535. for cell, val := range cells {
  536. assert.NoError(t, f.SetCellStr(sheet, cell, val))
  537. }
  538. return f
  539. }
  540. t.Run("InsertBefore", func(t *testing.T) {
  541. f := newFileWithDefaults()
  542. assert.NoError(t, f.DuplicateRowTo(sheet, 2, 1))
  543. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "InsertBefore"))) {
  544. t.FailNow()
  545. }
  546. expect := map[string]string{
  547. "A1": cells["A2"], "B1": cells["B2"],
  548. "A2": cells["A1"], "B2": cells["B1"],
  549. "A3": cells["A2"], "B3": cells["B2"],
  550. "A4": cells["A3"], "B4": cells["B3"],
  551. }
  552. for cell, val := range expect {
  553. v, err := f.GetCellValue(sheet, cell)
  554. assert.NoError(t, err)
  555. if !assert.Equal(t, val, v, cell) {
  556. t.FailNow()
  557. }
  558. }
  559. })
  560. }
  561. func TestDuplicateRowInsertBeforeWithLargeOffset(t *testing.T) {
  562. const sheet = "Sheet1"
  563. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  564. cells := map[string]string{
  565. "A1": "A1 Value",
  566. "A2": "A2 Value",
  567. "A3": "A3 Value",
  568. "B1": "B1 Value",
  569. "B2": "B2 Value",
  570. "B3": "B3 Value",
  571. }
  572. newFileWithDefaults := func() *File {
  573. f := NewFile()
  574. for cell, val := range cells {
  575. assert.NoError(t, f.SetCellStr(sheet, cell, val))
  576. }
  577. return f
  578. }
  579. t.Run("InsertBeforeWithLargeOffset", func(t *testing.T) {
  580. f := newFileWithDefaults()
  581. assert.NoError(t, f.DuplicateRowTo(sheet, 3, 1))
  582. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "InsertBeforeWithLargeOffset"))) {
  583. t.FailNow()
  584. }
  585. expect := map[string]string{
  586. "A1": cells["A3"], "B1": cells["B3"],
  587. "A2": cells["A1"], "B2": cells["B1"],
  588. "A3": cells["A2"], "B3": cells["B2"],
  589. "A4": cells["A3"], "B4": cells["B3"],
  590. }
  591. for cell, val := range expect {
  592. v, err := f.GetCellValue(sheet, cell)
  593. assert.NoError(t, err)
  594. if !assert.Equal(t, val, v) {
  595. t.FailNow()
  596. }
  597. }
  598. })
  599. }
  600. func TestDuplicateRowInsertBeforeWithMergeCells(t *testing.T) {
  601. const sheet = "Sheet1"
  602. outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx")
  603. cells := map[string]string{
  604. "A1": "A1 Value",
  605. "A2": "A2 Value",
  606. "A3": "A3 Value",
  607. "B1": "B1 Value",
  608. "B2": "B2 Value",
  609. "B3": "B3 Value",
  610. }
  611. newFileWithDefaults := func() *File {
  612. f := NewFile()
  613. for cell, val := range cells {
  614. assert.NoError(t, f.SetCellStr(sheet, cell, val))
  615. }
  616. assert.NoError(t, f.MergeCell(sheet, "B2", "C2"))
  617. assert.NoError(t, f.MergeCell(sheet, "C6", "C8"))
  618. return f
  619. }
  620. t.Run("InsertBeforeWithLargeOffset", func(t *testing.T) {
  621. f := newFileWithDefaults()
  622. assert.NoError(t, f.DuplicateRowTo(sheet, 2, 1))
  623. assert.NoError(t, f.DuplicateRowTo(sheet, 1, 8))
  624. if !assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, "InsertBeforeWithMergeCells"))) {
  625. t.FailNow()
  626. }
  627. expect := []MergeCell{
  628. {"B3:C3", "B2 Value"},
  629. {"C7:C10", ""},
  630. {"B1:C1", "B2 Value"},
  631. }
  632. mergeCells, err := f.GetMergeCells(sheet)
  633. assert.NoError(t, err)
  634. for idx, val := range expect {
  635. if !assert.Equal(t, val, mergeCells[idx]) {
  636. t.FailNow()
  637. }
  638. }
  639. })
  640. }
  641. func TestDuplicateRowInvalidRowNum(t *testing.T) {
  642. const sheet = "Sheet1"
  643. outFile := filepath.Join("test", "TestDuplicateRow.InvalidRowNum.%s.xlsx")
  644. cells := map[string]string{
  645. "A1": "A1 Value",
  646. "A2": "A2 Value",
  647. "A3": "A3 Value",
  648. "B1": "B1 Value",
  649. "B2": "B2 Value",
  650. "B3": "B3 Value",
  651. }
  652. invalidIndexes := []int{-100, -2, -1, 0}
  653. for _, row := range invalidIndexes {
  654. name := fmt.Sprintf("%d", row)
  655. t.Run(name, func(t *testing.T) {
  656. f := NewFile()
  657. for col, val := range cells {
  658. assert.NoError(t, f.SetCellStr(sheet, col, val))
  659. }
  660. assert.EqualError(t, f.DuplicateRow(sheet, row), fmt.Sprintf("invalid row number %d", row))
  661. for col, val := range cells {
  662. v, err := f.GetCellValue(sheet, col)
  663. assert.NoError(t, err)
  664. if !assert.Equal(t, val, v) {
  665. t.FailNow()
  666. }
  667. }
  668. assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, name)))
  669. })
  670. }
  671. for _, row1 := range invalidIndexes {
  672. for _, row2 := range invalidIndexes {
  673. name := fmt.Sprintf("[%d,%d]", row1, row2)
  674. t.Run(name, func(t *testing.T) {
  675. f := NewFile()
  676. for col, val := range cells {
  677. assert.NoError(t, f.SetCellStr(sheet, col, val))
  678. }
  679. assert.EqualError(t, f.DuplicateRowTo(sheet, row1, row2), fmt.Sprintf("invalid row number %d", row1))
  680. for col, val := range cells {
  681. v, err := f.GetCellValue(sheet, col)
  682. assert.NoError(t, err)
  683. if !assert.Equal(t, val, v) {
  684. t.FailNow()
  685. }
  686. }
  687. assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, name)))
  688. })
  689. }
  690. }
  691. }
  692. func TestDuplicateRowTo(t *testing.T) {
  693. f := File{}
  694. assert.EqualError(t, f.DuplicateRowTo("SheetN", 1, 2), "sheet SheetN is not exist")
  695. }
  696. func TestDuplicateMergeCells(t *testing.T) {
  697. f := File{}
  698. ws := &xlsxWorksheet{MergeCells: &xlsxMergeCells{
  699. Cells: []*xlsxMergeCell{{Ref: "A1:-"}},
  700. }}
  701. assert.EqualError(t, f.duplicateMergeCells("Sheet1", ws, 0, 0), `cannot convert cell "-" to coordinates: invalid cell name "-"`)
  702. ws.MergeCells.Cells[0].Ref = "A1:B1"
  703. assert.EqualError(t, f.duplicateMergeCells("SheetN", ws, 1, 2), "sheet SheetN is not exist")
  704. }
  705. func TestGetValueFromInlineStr(t *testing.T) {
  706. c := &xlsxC{T: "inlineStr"}
  707. f := NewFile()
  708. d := &xlsxSST{}
  709. val, err := c.getValueFrom(f, d)
  710. assert.NoError(t, err)
  711. assert.Equal(t, "", val)
  712. }
  713. func TestGetValueFromNumber(t *testing.T) {
  714. c := &xlsxC{T: "n", V: "2.2200000000000002"}
  715. f := NewFile()
  716. d := &xlsxSST{}
  717. val, err := c.getValueFrom(f, d)
  718. assert.NoError(t, err)
  719. assert.Equal(t, "2.22", val)
  720. c = &xlsxC{T: "n", V: "2.220000ddsf0000000002-r"}
  721. val, err = c.getValueFrom(f, d)
  722. assert.NoError(t, err)
  723. assert.Equal(t, "2.220000ddsf0000000002-r", val)
  724. c = &xlsxC{T: "n", V: "2.2."}
  725. val, err = c.getValueFrom(f, d)
  726. assert.NoError(t, err)
  727. assert.Equal(t, "2.2.", val)
  728. }
  729. func TestErrSheetNotExistError(t *testing.T) {
  730. err := ErrSheetNotExist{SheetName: "Sheet1"}
  731. assert.EqualValues(t, err.Error(), "sheet Sheet1 is not exist")
  732. }
  733. func TestCheckRow(t *testing.T) {
  734. f := NewFile()
  735. f.XLSX["xl/worksheets/sheet1.xml"] = []byte(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" ><sheetData><row r="2"><c><v>1</v></c><c r="F2"><v>2</v></c><c><v>3</v></c><c><v>4</v></c><c r="M2"><v>5</v></c></row></sheetData></worksheet>`)
  736. _, err := f.GetRows("Sheet1")
  737. assert.NoError(t, err)
  738. assert.NoError(t, f.SetCellValue("Sheet1", "A1", false))
  739. f = NewFile()
  740. f.XLSX["xl/worksheets/sheet1.xml"] = []byte(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" ><sheetData><row r="2"><c><v>1</v></c><c r="-"><v>2</v></c><c><v>3</v></c><c><v>4</v></c><c r="M2"><v>5</v></c></row></sheetData></worksheet>`)
  741. assert.EqualError(t, f.SetCellValue("Sheet1", "A1", false), `cannot convert cell "-" to coordinates: invalid cell name "-"`)
  742. }
  743. func TestNumberFormats(t *testing.T) {
  744. f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  745. if !assert.NoError(t, err) {
  746. t.FailNow()
  747. }
  748. cells := make([][]string, 0)
  749. cols, err := f.Cols("Sheet2")
  750. if !assert.NoError(t, err) {
  751. t.FailNow()
  752. }
  753. for cols.Next() {
  754. col, err := cols.Rows()
  755. assert.NoError(t, err)
  756. if err != nil {
  757. break
  758. }
  759. cells = append(cells, col)
  760. }
  761. assert.Equal(t, []string{"", "200", "450", "200", "510", "315", "127", "89", "348", "53", "37"}, cells[3])
  762. }
  763. func BenchmarkRows(b *testing.B) {
  764. f, _ := OpenFile(filepath.Join("test", "Book1.xlsx"))
  765. for i := 0; i < b.N; i++ {
  766. rows, _ := f.Rows("Sheet2")
  767. for rows.Next() {
  768. row, _ := rows.Columns()
  769. for i := range row {
  770. if i >= 0 {
  771. continue
  772. }
  773. }
  774. }
  775. }
  776. }
  777. func trimSliceSpace(s []string) []string {
  778. for {
  779. if len(s) > 0 && s[len(s)-1] == "" {
  780. s = s[:len(s)-1]
  781. } else {
  782. break
  783. }
  784. }
  785. return s
  786. }