excelize_test.go 31.2 KB
Newer Older
xurime's avatar
xurime 已提交
1 2 3
package excelize

import (
4 5 6
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
7
	"io/ioutil"
xurime's avatar
xurime 已提交
8
	"strconv"
xurime's avatar
xurime 已提交
9
	"testing"
10
	"time"
xurime's avatar
xurime 已提交
11 12
)

13
func TestOpenFile(t *testing.T) {
xurime's avatar
xurime 已提交
14
	// Test update a XLSX file.
15
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
16 17 18
	if err != nil {
		t.Log(err)
	}
19
	// Test get all the rows in a not exists sheet.
20
	rows := xlsx.GetRows("Sheet4")
21
	// Test get all the rows in a sheet.
22
	rows = xlsx.GetRows("Sheet2")
23 24 25 26 27 28
	for _, row := range rows {
		for _, cell := range row {
			t.Log(cell, "\t")
		}
		t.Log("\r\n")
	}
29 30 31 32 33 34 35 36 37 38 39 40
	xlsx.UpdateLinkedValue()
	xlsx.SetCellDefault("SHEET2", "A1", strconv.FormatFloat(float64(100.1588), 'f', -1, 32))
	xlsx.SetCellDefault("SHEET2", "A1", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
	xlsx.SetCellInt("SHEET2", "A1", 100)
	xlsx.SetCellStr("SHEET2", "C11", "Knowns")
	// Test max characters in a cell.
	var s = "c"
	for i := 0; i < 32768; i++ {
		s += "c"
	}
	xlsx.SetCellStr("SHEET2", "D11", s)
	xlsx.NewSheet(3, ":\\/?*[]Maximum 31 characters allowed in sheet title.")
41
	// Test set sheet name with illegal name.
42 43 44 45 46 47 48 49
	xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")
	xlsx.SetCellInt("Sheet3", "A23", 10)
	xlsx.SetCellStr("SHEET3", "b230", "10")
	xlsx.SetCellStr("SHEET10", "b230", "10")
	xlsx.SetActiveSheet(2)
	xlsx.GetCellFormula("Sheet1", "B19") // Test get cell formula with given rows number.
	xlsx.GetCellFormula("Sheet2", "B20") // Test get cell formula with illegal sheet index.
	xlsx.GetCellFormula("Sheet1", "B20") // Test get cell formula with illegal rows number.
xurime's avatar
xurime 已提交
50
	// Test read cell value with given illegal rows number.
51
	xlsx.GetCellValue("Sheet2", "a-1")
xurime's avatar
xurime 已提交
52
	// Test read cell value with given lowercase column number.
53 54 55 56
	xlsx.GetCellValue("Sheet2", "a5")
	xlsx.GetCellValue("Sheet2", "C11")
	xlsx.GetCellValue("Sheet2", "D11")
	xlsx.GetCellValue("Sheet2", "D12")
xurime's avatar
xurime 已提交
57
	// Test SetCellValue function.
58
	xlsx.SetCellValue("Sheet2", "F1", " Hello")
59 60 61 62 63 64 65 66 67 68 69
	xlsx.SetCellValue("Sheet2", "G1", []byte("World"))
	xlsx.SetCellValue("Sheet2", "F2", 42)
	xlsx.SetCellValue("Sheet2", "F2", int8(42))
	xlsx.SetCellValue("Sheet2", "F2", int16(42))
	xlsx.SetCellValue("Sheet2", "F2", int32(42))
	xlsx.SetCellValue("Sheet2", "F2", int64(42))
	xlsx.SetCellValue("Sheet2", "F2", float32(42.65418))
	xlsx.SetCellValue("Sheet2", "F2", float64(-42.65418))
	xlsx.SetCellValue("Sheet2", "F2", float32(42))
	xlsx.SetCellValue("Sheet2", "F2", float64(42))
	xlsx.SetCellValue("Sheet2", "G2", nil)
70 71
	xlsx.SetCellValue("Sheet2", "G3", uint8(8))
	xlsx.SetCellValue("Sheet2", "G4", time.Now())
xurime's avatar
xurime 已提交
72
	// Test completion column.
73
	xlsx.SetCellValue("Sheet2", "M2", nil)
xurime's avatar
xurime 已提交
74
	// Test read cell value with given axis large than exists row.
75
	xlsx.GetCellValue("Sheet2", "E231")
76
	// Test get active sheet of XLSX and get sheet name of XLSX by given sheet index.
77
	xlsx.GetSheetName(xlsx.GetActiveSheetIndex())
78 79
	// Test get sheet index of XLSX by given worksheet name.
	xlsx.GetSheetIndex("Sheet1")
80
	// Test get sheet name of XLSX by given invalid sheet index.
81
	xlsx.GetSheetName(4)
82
	// Test get sheet map of XLSX.
83
	xlsx.GetSheetMap()
84
	for i := 1; i <= 300; i++ {
85 86 87 88 89 90 91
		xlsx.SetCellStr("SHEET3", "c"+strconv.Itoa(i), strconv.Itoa(i))
	}
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
	// Test write file to not exist directory.
92
	err = xlsx.SaveAs("")
93 94
	if err != nil {
		t.Log(err)
xurime's avatar
xurime 已提交
95
	}
96 97 98 99
}

func TestAddPicture(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
xurime's avatar
xurime 已提交
100
	if err != nil {
101
		t.Log(err)
xurime's avatar
xurime 已提交
102
	}
103
	// Test add picture to sheet.
104
	err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", `{"x_offset": 140, "y_offset": 120}`)
105 106 107
	if err != nil {
		t.Log(err)
	}
108
	// Test add picture to sheet with offset.
109
	err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10}`)
110 111 112
	if err != nil {
		t.Log(err)
	}
113
	// Test add picture to sheet with invalid file path.
114
	err = xlsx.AddPicture("Sheet1", "G21", "./test/images/excel.icon", "")
115 116 117 118
	if err != nil {
		t.Log(err)
	}
	// Test add picture to sheet with unsupport file type.
119
	err = xlsx.AddPicture("Sheet1", "G21", "./test/Workbook1.xlsx", "")
120 121 122
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
123
	// Test write file to given path.
124
	err = xlsx.SaveAs("./test/Workbook_2.xlsx")
125 126 127
	if err != nil {
		t.Log(err)
	}
128
}
xurime's avatar
xurime 已提交
129

130
func TestBrokenFile(t *testing.T) {
xurime's avatar
xurime 已提交
131
	// Test write file with broken file struct.
132 133
	xlsx := File{}
	err := xlsx.Save()
xurime's avatar
xurime 已提交
134 135 136 137
	if err != nil {
		t.Log(err)
	}
	// Test write file with broken file struct with given path.
138
	err = xlsx.SaveAs("./test/Workbook_3.xlsx")
xurime's avatar
xurime 已提交
139 140 141 142
	if err != nil {
		t.Log(err)
	}

143 144
	// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
	f3, err := OpenFile("./test/badWorkbook.xlsx")
xurime's avatar
xurime 已提交
145
	f3.GetActiveSheetIndex()
146
	f3.SetActiveSheet(2)
147 148 149
	if err != nil {
		t.Log(err)
	}
150 151 152

	// Test open a XLSX file with given illegal path.
	_, err = OpenFile("./test/Workbook.xlsx")
153 154 155
	if err != nil {
		t.Log(err)
	}
156 157
}

158
func TestNewFile(t *testing.T) {
159
	// Test create a XLSX file.
160
	xlsx := NewFile()
161 162 163 164 165
	xlsx.NewSheet(2, "XLSXSheet2")
	xlsx.NewSheet(3, "XLSXSheet3")
	xlsx.SetCellInt("Sheet2", "A23", 56)
	xlsx.SetCellStr("SHEET1", "B20", "42")
	xlsx.SetActiveSheet(0)
166
	// Test add picture to sheet with scaling.
167
	err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5}`)
xurime's avatar
xurime 已提交
168
	if err != nil {
169
		t.Log(err)
xurime's avatar
xurime 已提交
170
	}
171
	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "")
xurime's avatar
xurime 已提交
172 173 174
	if err != nil {
		t.Log(err)
	}
175
	err = xlsx.SaveAs("./test/Workbook_3.xlsx")
176 177 178
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
179
}
180

181
func TestColWidth(t *testing.T) {
182
	xlsx := NewFile()
183 184
	xlsx.SetColWidth("sheet1", "B", "A", 12)
	xlsx.SetColWidth("sheet1", "A", "B", 12)
185 186
	xlsx.GetColWidth("sheet1", "A")
	xlsx.GetColWidth("sheet1", "C")
187
	err := xlsx.SaveAs("./test/Workbook_4.xlsx")
188 189 190
	if err != nil {
		t.Log(err)
	}
191 192 193 194 195 196 197 198 199 200 201 202 203 204
	convertRowHeightToPixels(0)
}

func TestRowHeight(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetRowHeight("Sheet1", 0, 50)
	xlsx.SetRowHeight("Sheet1", 3, 90)
	t.Log(xlsx.GetRowHeight("Sheet1", 1))
	t.Log(xlsx.GetRowHeight("Sheet1", 3))
	err := xlsx.SaveAs("./test/Workbook_5.xlsx")
	if err != nil {
		t.Log(err)
	}
	convertColWidthToPixels(0)
205 206 207 208 209 210 211 212
}

func TestSetCellHyperLink(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
	if err != nil {
		t.Log(err)
	}
	// Test set cell hyperlink in a work sheet already have hyperlinks.
213
	xlsx.SetCellHyperLink("sheet1", "B19", "https://github.com/xuri/excelize", "External")
214
	// Test add first hyperlink in a work sheet.
215
	xlsx.SetCellHyperLink("sheet2", "C1", "https://github.com/xuri/excelize", "External")
216 217 218 219
	// Test add Location hyperlink in a work sheet.
	xlsx.SetCellHyperLink("sheet2", "D6", "Sheet1!D8", "Location")
	xlsx.SetCellHyperLink("sheet2", "C3", "Sheet1!D8", "")
	xlsx.SetCellHyperLink("sheet2", "", "Sheet1!D60", "Location")
220 221 222 223 224 225 226 227
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

func TestSetCellFormula(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
228 229 230
	if err != nil {
		t.Log(err)
	}
231 232 233
	xlsx.SetCellFormula("sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)")
	xlsx.SetCellFormula("sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)")
	err = xlsx.Save()
234 235 236 237
	if err != nil {
		t.Log(err)
	}
}
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264

func TestSetSheetBackground(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.SetSheetBackground("sheet2", "./test/images/background.png")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.SetSheetBackground("sheet2", "./test/Workbook1.xlsx")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.SetSheetBackground("sheet2", "./test/images/background.jpg")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.SetSheetBackground("sheet2", "./test/images/background.jpg")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
xurime's avatar
xurime 已提交
265

266
func TestMergeCell(t *testing.T) {
xurime's avatar
xurime 已提交
267 268 269 270
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
	if err != nil {
		t.Log(err)
	}
271 272 273 274 275 276 277 278 279 280 281
	xlsx.MergeCell("Sheet1", "D9", "D9")
	xlsx.MergeCell("Sheet1", "D9", "E9")
	xlsx.MergeCell("Sheet1", "H14", "G13")
	xlsx.MergeCell("Sheet1", "C9", "D8")
	xlsx.MergeCell("Sheet1", "F11", "G13")
	xlsx.MergeCell("Sheet1", "H7", "B15")
	xlsx.MergeCell("Sheet1", "D11", "F13")
	xlsx.MergeCell("Sheet1", "G10", "K12")
	xlsx.SetCellValue("Sheet1", "G11", "set value in merged cell")
	xlsx.SetCellInt("Sheet1", "H11", 100)
	xlsx.SetCellValue("Sheet1", "I11", float64(0.5))
282
	xlsx.SetCellHyperLink("Sheet1", "J11", "https://github.com/xuri/excelize", "External")
283 284 285
	xlsx.SetCellFormula("Sheet1", "G12", "SUM(Sheet1!B19,Sheet1!C19)")
	xlsx.GetCellValue("Sheet1", "H11")
	xlsx.GetCellFormula("Sheet1", "G12")
xurime's avatar
xurime 已提交
286 287 288 289 290
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
N
Nikolas Silva 已提交
291

292 293 294 295 296
func TestSetCellStyleAlignment(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
297 298 299 300 301 302
	var style int
	style, err = xlsx.NewStyle(`{"alignment":{"horizontal":"center","ident":1,"justify_last_line":true,"reading_order":0,"relative_indent":1,"shrink_to_fit":true,"text_rotation":45,"vertical":"top","wrap_text":true}}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A22", "A22", style)
303 304 305 306 307 308 309
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

func TestSetCellStyleBorder(t *testing.T) {
310 311 312 313
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
314
	var style int
315
	// Test set border with invalid style parameter.
316
	style, err = xlsx.NewStyle("")
317 318 319
	if err != nil {
		t.Log(err)
	}
320 321
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

322
	// Test set border with invalid style index number.
323
	style, err = xlsx.NewStyle(`{"border":[{"type":"left","color":"0000FF","style":-1},{"type":"top","color":"00FF00","style":14},{"type":"bottom","color":"FFFF00","style":5},{"type":"right","color":"FF0000","style":6},{"type":"diagonalDown","color":"A020F0","style":9},{"type":"diagonalUp","color":"A020F0","style":8}]}`)
324 325 326
	if err != nil {
		t.Log(err)
	}
327 328
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

329
	// Test set border on overlapping area with vertical variants shading styles gradient fill.
330
	style, err = xlsx.NewStyle(`{"border":[{"type":"left","color":"0000FF","style":2},{"type":"top","color":"00FF00","style":12},{"type":"bottom","color":"FFFF00","style":5},{"type":"right","color":"FF0000","style":6},{"type":"diagonalDown","color":"A020F0","style":9},{"type":"diagonalUp","color":"A020F0","style":8}]}`)
331 332 333
	if err != nil {
		t.Log(err)
	}
334 335 336
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

	style, err = xlsx.NewStyle(`{"border":[{"type":"left","color":"0000FF","style":2},{"type":"top","color":"00FF00","style":3},{"type":"bottom","color":"FFFF00","style":4},{"type":"right","color":"FF0000","style":5},{"type":"diagonalDown","color":"A020F0","style":6},{"type":"diagonalUp","color":"A020F0","style":7}],"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":1}}`)
337 338 339
	if err != nil {
		t.Log(err)
	}
340 341 342 343 344 345 346 347
	xlsx.SetCellStyle("Sheet1", "M28", "K24", style)

	style, err = xlsx.NewStyle(`{"border":[{"type":"left","color":"0000FF","style":2},{"type":"top","color":"00FF00","style":3},{"type":"bottom","color":"FFFF00","style":4},{"type":"right","color":"FF0000","style":5},{"type":"diagonalDown","color":"A020F0","style":6},{"type":"diagonalUp","color":"A020F0","style":7}],"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":4}}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "M28", "K24", style)

348
	// Test set border and solid style pattern fill for a single cell.
349
	style, err = xlsx.NewStyle(`{"border":[{"type":"left","color":"0000FF","style":8},{"type":"top","color":"00FF00","style":9},{"type":"bottom","color":"FFFF00","style":10},{"type":"right","color":"FF0000","style":11},{"type":"diagonalDown","color":"A020F0","style":12},{"type":"diagonalUp","color":"A020F0","style":13}],"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":1}}`)
350 351 352
	if err != nil {
		t.Log(err)
	}
353 354

	xlsx.SetCellStyle("Sheet1", "O22", "O22", style)
355 356 357 358 359 360
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

361
func TestSetCellStyleNumberFormat(t *testing.T) {
362 363 364 365
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
366
	// Test only set fill and number format for a cell.
367 368 369 370 371 372 373 374 375 376 377 378 379
	col := []string{"L", "M", "N", "O", "P"}
	data := []int{0, 1, 2, 3, 4, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49}
	value := []string{"37947.7500001", "-37947.7500001", "0.007", "2.1", "String"}
	for i, v := range value {
		for k, d := range data {
			c := col[i] + strconv.Itoa(k+1)
			var val float64
			val, err = strconv.ParseFloat(v, 64)
			if err != nil {
				xlsx.SetCellValue("Sheet2", c, v)
			} else {
				xlsx.SetCellValue("Sheet2", c, val)
			}
380
			style, err := xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":5},"number_format": ` + strconv.Itoa(d) + `}`)
381 382 383
			if err != nil {
				t.Log(err)
			}
384
			xlsx.SetCellStyle("Sheet2", c, c, style)
385 386 387
			t.Log(xlsx.GetCellValue("Sheet2", c))
		}
	}
388 389 390 391 392 393
	var style int
	style, err = xlsx.NewStyle(`{"number_format":-1}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet2", "L33", "L33", style)
394
	err = xlsx.Save()
395 396 397
	if err != nil {
		t.Log(err)
	}
398 399
}

400 401 402 403 404 405
func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_3.xlsx")
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellValue("Sheet1", "A1", 56)
406
	xlsx.SetCellValue("Sheet1", "A2", -32.3)
407 408 409 410 411 412
	var style int
	style, err = xlsx.NewStyle(`{"number_format": 188, "decimal_places": -1}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A1", "A1", style)
413
	style, err = xlsx.NewStyle(`{"number_format": 188, "decimal_places": 31, "negred": true}`)
414 415 416 417 418 419 420 421 422 423 424 425 426 427
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A2", "A2", style)

	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}

	xlsx, err = OpenFile("./test/Workbook_4.xlsx")
	if err != nil {
		t.Log(err)
	}
428 429
	xlsx.SetCellValue("Sheet1", "A1", 42920.5)
	xlsx.SetCellValue("Sheet1", "A2", 42920.5)
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457

	style, err = xlsx.NewStyle(`{"number_format": 26, "lang": "zh-tw"}`)
	if err != nil {
		t.Log(err)
	}
	style, err = xlsx.NewStyle(`{"number_format": 27}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A1", "A1", style)
	style, err = xlsx.NewStyle(`{"number_format": 31, "lang": "ko-kr"}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A2", "A2", style)

	style, err = xlsx.NewStyle(`{"number_format": 71, "lang": "th-th"}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A2", "A2", style)

	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
func TestSetCellStyleCustomNumberFormat(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetCellValue("Sheet1", "A1", 42920.5)
	xlsx.SetCellValue("Sheet1", "A2", 42920.5)
	style, err := xlsx.NewStyle(`{"custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A1", "A1", style)
	style, err = xlsx.NewStyle(`{"custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A2", "A2", style)
	err = xlsx.SaveAs("./test/Workbook_custom_number_format.xlsx")
	if err != nil {
		t.Log(err)
	}
}

478 479
func TestSetCellStyleFill(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
480 481 482
	if err != nil {
		t.Log(err)
	}
483
	var style int
484
	// Test set fill for cell with invalid parameter.
485
	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":6}}`)
486 487 488
	if err != nil {
		t.Log(err)
	}
489 490 491
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF"],"shading":1}}`)
492 493 494
	if err != nil {
		t.Log(err)
	}
495 496 497
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":[],"pattern":1}}`)
498 499 500
	if err != nil {
		t.Log(err)
	}
501
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)
xurime's avatar
xurime 已提交
502

503
	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":19}}`)
504 505 506
	if err != nil {
		t.Log(err)
	}
507 508
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

509 510 511
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
512 513 514 515 516 517 518 519
	}
}

func TestSetCellStyleFont(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
520 521
	var style int
	style, err = xlsx.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}`)
522 523 524
	if err != nil {
		t.Log(err)
	}
525 526 527
	xlsx.SetCellStyle("Sheet2", "A1", "A1", style)

	style, err = xlsx.NewStyle(`{"font":{"italic":true,"underline":"double"}}`)
528 529 530
	if err != nil {
		t.Log(err)
	}
531 532 533
	xlsx.SetCellStyle("Sheet2", "A2", "A2", style)

	style, err = xlsx.NewStyle(`{"font":{"bold":true}}`)
534 535 536
	if err != nil {
		t.Log(err)
	}
537 538 539
	xlsx.SetCellStyle("Sheet2", "A3", "A3", style)

	style, err = xlsx.NewStyle(`{"font":{"bold":true,"family":"","size":0,"color":"","underline":""}}`)
540 541 542
	if err != nil {
		t.Log(err)
	}
543 544 545
	xlsx.SetCellStyle("Sheet2", "A4", "A4", style)

	style, err = xlsx.NewStyle(`{"font":{"color":"#777777"}}`)
546 547 548
	if err != nil {
		t.Log(err)
	}
549
	xlsx.SetCellStyle("Sheet2", "A5", "A5", style)
550 551 552
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
553 554
	}
}
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570

func TestSetDeleteSheet(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_3.xlsx")
	if err != nil {
		t.Log(err)
	}
	xlsx.DeleteSheet("XLSXSheet3")
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
	xlsx, err = OpenFile("./test/Workbook_4.xlsx")
	if err != nil {
		t.Log(err)
	}
	xlsx.DeleteSheet("Sheet1")
xurime's avatar
xurime 已提交
571 572
	xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
	err = xlsx.SaveAs("./test/Workbook_delete_sheet.xlsx")
573 574 575 576
	if err != nil {
		t.Log(err)
	}
}
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601

func TestGetPicture(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
	file, raw := xlsx.GetPicture("Sheet1", "F21")
	if file == "" {
		err = ioutil.WriteFile(file, raw, 0644)
		if err != nil {
			t.Log(err)
		}
	}
	// Try to get picture from a worksheet that doesn't contain any images.
	file, raw = xlsx.GetPicture("Sheet3", "I9")
	if file != "" {
		err = ioutil.WriteFile(file, raw, 0644)
		if err != nil {
			t.Log(err)
		}
	}
	// Try to get picture from a cell that doesn't contain an image.
	file, raw = xlsx.GetPicture("Sheet2", "A2")
	t.Log(file, len(raw))
}
602

603 604 605 606 607
func TestSheetVisibility(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
608 609 610 611
	xlsx.SetSheetVisible("Sheet2", false)
	xlsx.SetSheetVisible("Sheet1", false)
	xlsx.SetSheetVisible("Sheet1", true)
	xlsx.GetSheetVisible("Sheet1")
612 613 614 615 616 617
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

618 619 620 621 622
func TestRowVisibility(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
623 624 625
	xlsx.SetRowVisible("Sheet3", 2, false)
	xlsx.SetRowVisible("Sheet3", 2, true)
	xlsx.GetRowVisible("Sheet3", 2)
626 627 628 629 630 631
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
func TestColumnVisibility(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
	xlsx.SetColVisible("Sheet1", "F", false)
	xlsx.SetColVisible("Sheet1", "F", true)
	xlsx.GetColVisible("Sheet1", "F")
	xlsx.SetColVisible("Sheet3", "E", false)
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
	xlsx, err = OpenFile("./test/Workbook_3.xlsx")
	if err != nil {
		t.Log(err)
	}
	xlsx.GetColVisible("Sheet1", "B")
}

652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
func TestCopySheet(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.CopySheet(0, -1)
	if err != nil {
		t.Log(err)
	}
	xlsx.NewSheet(4, "CopySheet")
	err = xlsx.CopySheet(1, 4)
	if err != nil {
		t.Log(err)
	}
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
671

xurime's avatar
xurime 已提交
672 673 674 675 676 677 678 679 680 681 682 683 684 685
func TestAddTable(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
	xlsx.AddTable("Sheet1", "B26", "A21", ``)
	xlsx.AddTable("Sheet2", "A2", "B5", `{"table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
	xlsx.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

686 687 688 689 690
func TestAddShape(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
691 692 693 694
	xlsx.AddShape("Sheet1", "A30", `{"type":"rect","paragraph":[{"text":"Rectangle","font":{"color":"CD5C5C"}},{"text":"Shape","font":{"bold":true,"color":"2980B9"}}]}`)
	xlsx.AddShape("Sheet1", "B30", `{"type":"rect","paragraph":[{"text":"Rectangle"},{}]}`)
	xlsx.AddShape("Sheet1", "C30", `{"type":"rect","paragraph":[]}`)
	xlsx.AddShape("Sheet3", "H1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}], "height": 90}`)
695 696 697 698 699 700
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

701 702 703 704 705
func TestAddComments(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
706 707 708 709 710 711
	var s = "c"
	for i := 0; i < 32767; i++ {
		s += "c"
	}
	xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
	xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
712 713 714 715 716 717
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
func TestAutoFilter(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook_2.xlsx")
	if err != nil {
		t.Log(err)
	}
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", ``)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x != blanks"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x == blanks"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x != nonblanks"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x == nonblanks"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x <= 1 and x >= 2"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x == 1 or x == 2"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x == 1 or x == 2*"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x <= 1 and x >= blanks"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x -- y or x == *2*"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x != y or x ? *2"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x -- y o r x == *2"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"B","expression":"x -- y"}`)
	t.Log(err)
	err = xlsx.AutoFilter("Sheet3", "D4", "B1", `{"column":"A","expression":"x -- y"}`)
	t.Log(err)
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

757 758 759 760 761
func TestAddChart(t *testing.T) {
	xlsx, err := OpenFile("./test/Workbook1.xlsx")
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
762 763 764 765 766 767 768 769
	categories := map[string]string{"A30": "Small", "A31": "Normal", "A32": "Large", "B29": "Apple", "C29": "Orange", "D29": "Pear"}
	values := map[string]int{"B30": 2, "C30": 3, "D30": 3, "B31": 5, "C31": 2, "D31": 4, "B32": 6, "C32": 7, "D32": 8}
	for k, v := range categories {
		xlsx.SetCellValue("Sheet1", k, v)
	}
	for k, v := range values {
		xlsx.SetCellValue("Sheet1", k, v)
	}
770 771
	xlsx.AddChart("SHEET1", "P1", `{"type":"bar3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	xlsx.AddChart("SHEET1", "X1", `{"type":"bar","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
xurime's avatar
xurime 已提交
772
	xlsx.AddChart("SHEET1", "P16", `{"type":"doughnut","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut Chart"},"plotarea":{"show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
773
	xlsx.AddChart("SHEET1", "X16", `{"type":"line","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top","show_legend_key":false},"title":{"name":"Fruit Line Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
xurime's avatar
xurime 已提交
774 775
	xlsx.AddChart("SHEET1", "P30", `{"type":"pie3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
	xlsx.AddChart("SHEET1", "X30", `{"type":"pie","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"}`)
776 777 778
	xlsx.AddChart("SHEET2", "P1", `{"type":"radar","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top_right","show_legend_key":false},"title":{"name":"Fruit Radar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"span"}`)
	xlsx.AddChart("SHEET2", "X1", `{"type":"scatter","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Scatter Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	// Save xlsx file by the given path.
779 780 781 782 783 784 785 786 787 788 789 790 791 792
	err = xlsx.SaveAs("./test/Workbook_addchart.xlsx")
	if err != nil {
		t.Log(err)
	}
}

func TestInsertCol(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
		for i := 0; i <= 10; i++ {
			axis := ToAlphaString(i) + strconv.Itoa(j)
			xlsx.SetCellStr("Sheet1", axis, axis)
		}
	}
793
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
	xlsx.MergeCell("sheet1", "A1", "C3")
	err := xlsx.AutoFilter("Sheet1", "A2", "B2", `{"column":"B","expression":"x != blanks"}`)
	t.Log(err)
	xlsx.InsertCol("Sheet1", "A")
	err = xlsx.SaveAs("./test/Workbook_insertcol.xlsx")
	if err != nil {
		t.Log(err)
	}
}

func TestRemoveCol(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
		for i := 0; i <= 10; i++ {
			axis := ToAlphaString(i) + strconv.Itoa(j)
			xlsx.SetCellStr("Sheet1", axis, axis)
		}
	}
812 813
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
	xlsx.SetCellHyperLink("Sheet1", "C5", "https://github.com", "External")
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
	xlsx.MergeCell("sheet1", "A1", "B1")
	xlsx.MergeCell("sheet1", "A2", "B2")
	xlsx.RemoveCol("Sheet1", "A")
	xlsx.RemoveCol("Sheet1", "A")
	err := xlsx.SaveAs("./test/Workbook_removecol.xlsx")
	if err != nil {
		t.Log(err)
	}
}

func TestInsertRow(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
		for i := 0; i <= 10; i++ {
			axis := ToAlphaString(i) + strconv.Itoa(j)
			xlsx.SetCellStr("Sheet1", axis, axis)
		}
	}
832
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
833 834 835 836 837 838 839 840
	xlsx.InsertRow("Sheet1", -1)
	xlsx.InsertRow("Sheet1", 4)
	err := xlsx.SaveAs("./test/Workbook_insertrow.xlsx")
	if err != nil {
		t.Log(err)
	}
}

xurime's avatar
xurime 已提交
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
func TestSetPane(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
	xlsx.NewSheet(2, "Panes 2")
	xlsx.SetPanes("Sheet2", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`)
	xlsx.NewSheet(3, "Panes 3")
	xlsx.SetPanes("Sheet3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`)
	xlsx.NewSheet(4, "Panes 4")
	xlsx.SetPanes("Sheet4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`)
	err := xlsx.SaveAs("./test/Workbook_set_panes.xlsx")
	if err != nil {
		t.Log(err)
	}
}

856 857 858 859 860 861 862 863
func TestRemoveRow(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
		for i := 0; i <= 10; i++ {
			axis := ToAlphaString(i) + strconv.Itoa(j)
			xlsx.SetCellStr("Sheet1", axis, axis)
		}
	}
864
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
865 866 867 868 869 870 871 872 873 874 875
	xlsx.RemoveRow("Sheet1", -1)
	xlsx.RemoveRow("Sheet1", 4)
	xlsx.MergeCell("sheet1", "B3", "B5")
	xlsx.RemoveRow("Sheet1", 2)
	xlsx.RemoveRow("Sheet1", 4)
	err := xlsx.AutoFilter("Sheet1", "A2", "A2", `{"column":"A","expression":"x != blanks"}`)
	t.Log(err)
	xlsx.RemoveRow("Sheet1", 0)
	xlsx.RemoveRow("Sheet1", 1)
	xlsx.RemoveRow("Sheet1", 0)
	err = xlsx.SaveAs("./test/Workbook_removerow.xlsx")
876 877 878 879
	if err != nil {
		t.Log(err)
	}
}