rows_test.go 23 KB

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