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

import (
4
	"fmt"
xurime's avatar
xurime 已提交
5
	"image/color"
6 7 8
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
9
	"io/ioutil"
10
	"reflect"
xurime's avatar
xurime 已提交
11
	"strconv"
xurime's avatar
xurime 已提交
12
	"strings"
xurime's avatar
xurime 已提交
13
	"testing"
14
	"time"
V
Veniamin Albaev 已提交
15 16

	"github.com/stretchr/testify/assert"
xurime's avatar
xurime 已提交
17 18
)

19
func TestOpenFile(t *testing.T) {
xurime's avatar
xurime 已提交
20
	// Test update a XLSX file.
xurime's avatar
xurime 已提交
21
	xlsx, err := OpenFile("./test/Book1.xlsx")
22
	if err != nil {
23
		t.Error(err)
24
	}
25
	// Test get all the rows in a not exists worksheet.
xurime's avatar
xurime 已提交
26
	xlsx.GetRows("Sheet4")
27
	// Test get all the rows in a worksheet.
xurime's avatar
xurime 已提交
28
	rows := xlsx.GetRows("Sheet2")
29 30 31 32 33 34
	for _, row := range rows {
		for _, cell := range row {
			t.Log(cell, "\t")
		}
		t.Log("\r\n")
	}
35
	xlsx.UpdateLinkedValue()
36 37
	xlsx.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(100.1588), 'f', -1, 32))
	xlsx.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
38 39
	// Test set cell value with illegal row number.
	xlsx.SetCellDefault("Sheet2", "A", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
40
	xlsx.SetCellInt("Sheet2", "A1", 100)
41 42
	// Test set cell integer value with illegal row number.
	xlsx.SetCellInt("Sheet2", "A", 100)
43
	xlsx.SetCellStr("Sheet2", "C11", "Knowns")
44
	// Test max characters in a cell.
45 46 47
	xlsx.SetCellStr("Sheet2", "D11", strings.Repeat("c", 32769))
	xlsx.NewSheet(":\\/?*[]Maximum 31 characters allowed in sheet title.")
	// Test set worksheet name with illegal name.
48 49
	xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")
	xlsx.SetCellInt("Sheet3", "A23", 10)
50 51
	xlsx.SetCellStr("Sheet3", "b230", "10")
	xlsx.SetCellStr("Sheet10", "b230", "10")
52 53
	// Test set cell string value with illegal row number.
	xlsx.SetCellStr("Sheet10", "A", "10")
54
	xlsx.SetActiveSheet(2)
55 56
	// Test get cell formula with given rows number.
	xlsx.GetCellFormula("Sheet1", "B19")
57
	// Test get cell formula with illegal worksheet name.
58 59 60 61
	xlsx.GetCellFormula("Sheet2", "B20")
	// Test get cell formula with illegal rows number.
	xlsx.GetCellFormula("Sheet1", "B20")
	xlsx.GetCellFormula("Sheet1", "B")
62 63 64 65
	// Test get shared cell formula
	xlsx.GetCellFormula("Sheet2", "H11")
	xlsx.GetCellFormula("Sheet2", "I11")
	getSharedForumula(&xlsxWorksheet{}, "")
xurime's avatar
xurime 已提交
66
	// Test read cell value with given illegal rows number.
67
	xlsx.GetCellValue("Sheet2", "a-1")
68
	xlsx.GetCellValue("Sheet2", "A")
xurime's avatar
xurime 已提交
69
	// Test read cell value with given lowercase column number.
70 71 72 73
	xlsx.GetCellValue("Sheet2", "a5")
	xlsx.GetCellValue("Sheet2", "C11")
	xlsx.GetCellValue("Sheet2", "D11")
	xlsx.GetCellValue("Sheet2", "D12")
xurime's avatar
xurime 已提交
74
	// Test SetCellValue function.
75
	xlsx.SetCellValue("Sheet2", "F1", " Hello")
76 77
	xlsx.SetCellValue("Sheet2", "G1", []byte("World"))
	xlsx.SetCellValue("Sheet2", "F2", 42)
78 79 80 81 82 83 84 85 86 87 88 89 90 91
	xlsx.SetCellValue("Sheet2", "F3", int8(1<<8/2-1))
	xlsx.SetCellValue("Sheet2", "F4", int16(1<<16/2-1))
	xlsx.SetCellValue("Sheet2", "F5", int32(1<<32/2-1))
	xlsx.SetCellValue("Sheet2", "F6", int64(1<<32/2-1))
	xlsx.SetCellValue("Sheet2", "F7", float32(42.65418))
	xlsx.SetCellValue("Sheet2", "F8", float64(-42.65418))
	xlsx.SetCellValue("Sheet2", "F9", float32(42))
	xlsx.SetCellValue("Sheet2", "F10", float64(42))
	xlsx.SetCellValue("Sheet2", "F11", uint(1<<32-1))
	xlsx.SetCellValue("Sheet2", "F12", uint8(1<<8-1))
	xlsx.SetCellValue("Sheet2", "F13", uint16(1<<16-1))
	xlsx.SetCellValue("Sheet2", "F14", uint32(1<<32-1))
	xlsx.SetCellValue("Sheet2", "F15", uint64(1<<32-1))
	xlsx.SetCellValue("Sheet2", "F16", true)
92 93
	xlsx.SetCellValue("Sheet2", "F17", complex64(5+10i))
	t.Log(letterOnlyMapF('x'))
94 95 96
	shiftJulianToNoon(1, -0.6)
	timeFromExcelTime(61, true)
	timeFromExcelTime(62, true)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
	// Test boolean write
	booltest := []struct {
		value    bool
		expected string
	}{
		{false, "0"},
		{true, "1"},
	}
	for _, test := range booltest {
		xlsx.SetCellValue("Sheet2", "F16", test.value)
		value := xlsx.GetCellValue("Sheet2", "F16")
		if value != test.expected {
			t.Errorf(`Expecting result of xlsx.SetCellValue("Sheet2", "F16", %v) to be %v (false), got: %s `, test.value, test.expected, value)
		}
	}
112
	xlsx.SetCellValue("Sheet2", "G2", nil)
113
	xlsx.SetCellValue("Sheet2", "G4", time.Now())
114 115
	// 02:46:40
	xlsx.SetCellValue("Sheet2", "G5", time.Duration(1e13))
xurime's avatar
xurime 已提交
116
	// Test completion column.
117
	xlsx.SetCellValue("Sheet2", "M2", nil)
xurime's avatar
xurime 已提交
118
	// Test read cell value with given axis large than exists row.
119
	xlsx.GetCellValue("Sheet2", "E231")
120
	// Test get active worksheet of XLSX and get worksheet name of XLSX by given worksheet index.
121
	xlsx.GetSheetName(xlsx.GetActiveSheetIndex())
122
	// Test get worksheet index of XLSX by given worksheet name.
123
	xlsx.GetSheetIndex("Sheet1")
124
	// Test get worksheet name of XLSX by given invalid worksheet index.
125
	xlsx.GetSheetName(4)
126
	// Test get worksheet map of XLSX.
127
	xlsx.GetSheetMap()
128
	for i := 1; i <= 300; i++ {
129
		xlsx.SetCellStr("Sheet3", "c"+strconv.Itoa(i), strconv.Itoa(i))
130 131 132
	}
	err = xlsx.Save()
	if err != nil {
133
		t.Error(err)
134 135
	}
	// Test write file to not exist directory.
136
	err = xlsx.SaveAs("")
137 138
	if err != nil {
		t.Log(err)
xurime's avatar
xurime 已提交
139
	}
140 141 142
}

func TestAddPicture(t *testing.T) {
xurime's avatar
xurime 已提交
143
	xlsx, err := OpenFile("./test/Book1.xlsx")
xurime's avatar
xurime 已提交
144
	if err != nil {
145
		t.Error(err)
xurime's avatar
xurime 已提交
146
	}
147 148
	// Test add picture to worksheet with offset and location hyperlink.
	err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", `{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
149
	if err != nil {
150
		t.Error(err)
151
	}
152 153
	// Test add picture to worksheet with offset, external hyperlink and positioning.
	err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
154
	if err != nil {
155
		t.Error(err)
156
	}
157
	// Test add picture to worksheet with invalid file path.
158
	err = xlsx.AddPicture("Sheet1", "G21", "./test/images/excel.icon", "")
159 160 161
	if err != nil {
		t.Log(err)
	}
162
	// Test add picture to worksheet with unsupport file type.
xurime's avatar
xurime 已提交
163
	err = xlsx.AddPicture("Sheet1", "G21", "./test/Book1.xlsx", "")
164 165 166
	if err != nil {
		t.Log(err)
	}
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
	err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1))
	if err != nil {
		t.Log(err)
	}
	// Test add picture to worksheet with invalid file data.
	err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", ".jpg", make([]byte, 1))
	if err != nil {
		t.Log(err)
	}
	file, err := ioutil.ReadFile("./test/images/excel.jpg")
	if err != nil {
		t.Error(err)
	}
	// Test add picture to worksheet from bytes.
	err = xlsx.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".jpg", file)
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
185
	// Test write file to given path.
xurime's avatar
xurime 已提交
186
	err = xlsx.SaveAs("./test/Book2.xlsx")
187
	if err != nil {
188
		t.Error(err)
189
	}
190
}
xurime's avatar
xurime 已提交
191

192
func TestBrokenFile(t *testing.T) {
xurime's avatar
xurime 已提交
193
	// Test write file with broken file struct.
194 195
	xlsx := File{}
	err := xlsx.Save()
xurime's avatar
xurime 已提交
196 197 198 199
	if err != nil {
		t.Log(err)
	}
	// Test write file with broken file struct with given path.
xurime's avatar
xurime 已提交
200
	err = xlsx.SaveAs("./test/Book3.xlsx")
xurime's avatar
xurime 已提交
201 202 203 204
	if err != nil {
		t.Log(err)
	}

205 206
	// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
	f3, err := OpenFile("./test/badWorkbook.xlsx")
xurime's avatar
xurime 已提交
207
	f3.GetActiveSheetIndex()
208
	f3.SetActiveSheet(2)
209 210 211
	if err != nil {
		t.Log(err)
	}
212 213

	// Test open a XLSX file with given illegal path.
xurime's avatar
xurime 已提交
214
	_, err = OpenFile("./test/Book.xlsx")
215 216 217
	if err != nil {
		t.Log(err)
	}
218 219
}

220
func TestNewFile(t *testing.T) {
221
	// Test create a XLSX file.
222
	xlsx := NewFile()
223
	xlsx.NewSheet("Sheet1")
224 225 226 227
	xlsx.NewSheet("XLSXSheet2")
	xlsx.NewSheet("XLSXSheet3")
	xlsx.SetCellInt("XLSXSheet2", "A23", 56)
	xlsx.SetCellStr("Sheet1", "B20", "42")
228
	xlsx.SetActiveSheet(0)
229 230
	// Test add picture to sheet with scaling and positioning.
	err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
xurime's avatar
xurime 已提交
231
	if err != nil {
232
		t.Error(err)
xurime's avatar
xurime 已提交
233
	}
234
	// Test add picture to worksheet without formatset.
235
	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "")
236 237 238 239 240
	if err != nil {
		t.Error(err)
	}
	// Test add picture to worksheet with invalid formatset.
	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", `{`)
xurime's avatar
xurime 已提交
241
	if err != nil {
242
		t.Log(err)
xurime's avatar
xurime 已提交
243
	}
xurime's avatar
xurime 已提交
244
	err = xlsx.SaveAs("./test/Book3.xlsx")
245
	if err != nil {
246
		t.Error(err)
247
	}
xurime's avatar
xurime 已提交
248
}
249

250
func TestColWidth(t *testing.T) {
251
	xlsx := NewFile()
252 253 254 255
	xlsx.SetColWidth("Sheet1", "B", "A", 12)
	xlsx.SetColWidth("Sheet1", "A", "B", 12)
	xlsx.GetColWidth("Sheet1", "A")
	xlsx.GetColWidth("Sheet1", "C")
xurime's avatar
xurime 已提交
256
	err := xlsx.SaveAs("./test/Book4.xlsx")
257
	if err != nil {
258
		t.Error(err)
259
	}
260 261 262 263 264
	convertRowHeightToPixels(0)
}

func TestRowHeight(t *testing.T) {
	xlsx := NewFile()
265 266
	xlsx.SetRowHeight("Sheet1", 1, 50)
	xlsx.SetRowHeight("Sheet1", 4, 90)
267
	t.Log(xlsx.GetRowHeight("Sheet1", 1))
268
	t.Log(xlsx.GetRowHeight("Sheet1", 0))
xurime's avatar
xurime 已提交
269
	err := xlsx.SaveAs("./test/Book5.xlsx")
270
	if err != nil {
271
		t.Error(err)
272 273
	}
	convertColWidthToPixels(0)
274 275 276
}

func TestSetCellHyperLink(t *testing.T) {
xurime's avatar
xurime 已提交
277
	xlsx, err := OpenFile("./test/Book1.xlsx")
278 279 280 281
	if err != nil {
		t.Log(err)
	}
	// Test set cell hyperlink in a work sheet already have hyperlinks.
282
	xlsx.SetCellHyperLink("Sheet1", "B19", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
283
	// Test add first hyperlink in a work sheet.
284
	xlsx.SetCellHyperLink("Sheet2", "C1", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
285
	// Test add Location hyperlink in a work sheet.
286 287 288
	xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location")
	xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", "")
	xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location")
289 290
	err = xlsx.Save()
	if err != nil {
291
		t.Error(err)
292 293 294
	}
}

295
func TestGetCellHyperLink(t *testing.T) {
xurime's avatar
xurime 已提交
296
	xlsx, err := OpenFile("./test/Book1.xlsx")
297
	if err != nil {
298
		t.Error(err)
299 300 301 302 303 304 305 306 307 308 309
	}
	link, target := xlsx.GetCellHyperLink("Sheet1", "")
	t.Log(link, target)
	link, target = xlsx.GetCellHyperLink("Sheet1", "B19")
	t.Log(link, target)
	link, target = xlsx.GetCellHyperLink("Sheet2", "D6")
	t.Log(link, target)
	link, target = xlsx.GetCellHyperLink("Sheet3", "H3")
	t.Log(link, target)
}

310
func TestSetCellFormula(t *testing.T) {
xurime's avatar
xurime 已提交
311
	xlsx, err := OpenFile("./test/Book1.xlsx")
312
	if err != nil {
313
		t.Error(err)
314
	}
315 316
	xlsx.SetCellFormula("Sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)")
	xlsx.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)")
317 318
	// Test set cell formula with illegal rows number.
	xlsx.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)")
319
	err = xlsx.Save()
320
	if err != nil {
321
		t.Error(err)
322 323
	}
}
324 325

func TestSetSheetBackground(t *testing.T) {
xurime's avatar
xurime 已提交
326
	xlsx, err := OpenFile("./test/Book1.xlsx")
327
	if err != nil {
328
		t.Error(err)
329
	}
330
	err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.png")
331 332 333
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
334
	err = xlsx.SetSheetBackground("Sheet2", "./test/Book1.xlsx")
335 336 337
	if err != nil {
		t.Log(err)
	}
338
	err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg")
339
	if err != nil {
340
		t.Error(err)
341
	}
342
	err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg")
343
	if err != nil {
344
		t.Error(err)
345 346 347
	}
	err = xlsx.Save()
	if err != nil {
348
		t.Error(err)
349 350
	}
}
xurime's avatar
xurime 已提交
351

352
func TestMergeCell(t *testing.T) {
xurime's avatar
xurime 已提交
353
	xlsx, err := OpenFile("./test/Book1.xlsx")
xurime's avatar
xurime 已提交
354
	if err != nil {
355
		t.Error(err)
xurime's avatar
xurime 已提交
356
	}
357 358 359 360 361 362 363 364 365 366 367
	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))
368
	xlsx.SetCellHyperLink("Sheet1", "J11", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
369 370
	xlsx.SetCellFormula("Sheet1", "G12", "SUM(Sheet1!B19,Sheet1!C19)")
	xlsx.GetCellValue("Sheet1", "H11")
371
	xlsx.GetCellValue("Sheet2", "A6") // Merged cell ref is single coordinate.
372
	xlsx.GetCellFormula("Sheet1", "G12")
xurime's avatar
xurime 已提交
373 374
	err = xlsx.Save()
	if err != nil {
375
		t.Error(err)
xurime's avatar
xurime 已提交
376 377
	}
}
N
Nikolas Silva 已提交
378

S
sairoutine 已提交
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
func TestGetMergeCells(t *testing.T) {
	wants := []struct {
		value string
		start string
		end   string
	}{
		{
			value: "A1",
			start: "A1",
			end:   "B1",
		},
		{
			value: "A2",
			start: "A2",
			end:   "A3",
		},
		{
			value: "A4",
			start: "A4",
			end:   "B5",
		},
		{
			value: "A7",
			start: "A7",
			end:   "C10",
		},
	}

	xlsx, err := OpenFile("./test/MergeCell.xlsx")
	if err != nil {
		t.Error(err)
	}

	mergeCells := xlsx.GetMergeCells("Sheet1")
	if len(mergeCells) != len(wants) {
		t.Fatalf("Expected count of merge cells %d, but got %d\n", len(wants), len(mergeCells))
	}

	for i, m := range mergeCells {
		if wants[i].value != m.GetCellValue() {
			t.Fatalf("Expected merged cell value %s, but got %s\n", wants[i].value, m.GetCellValue())
		}

		if wants[i].start != m.GetStartAxis() {
			t.Fatalf("Expected merged cell value %s, but got %s\n", wants[i].start, m.GetStartAxis())
		}

		if wants[i].end != m.GetEndAxis() {
			t.Fatalf("Expected merged cell value %s, but got %s\n", wants[i].end, m.GetEndAxis())
		}
	}
}

432
func TestSetCellStyleAlignment(t *testing.T) {
xurime's avatar
xurime 已提交
433
	xlsx, err := OpenFile("./test/Book2.xlsx")
434
	if err != nil {
435
		t.Error(err)
436
	}
437 438 439
	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 {
440
		t.Error(err)
441 442
	}
	xlsx.SetCellStyle("Sheet1", "A22", "A22", style)
443 444 445 446 447
	// Test set cell style with given illegal rows number.
	xlsx.SetCellStyle("Sheet1", "A", "A22", style)
	xlsx.SetCellStyle("Sheet1", "A22", "A", style)
	// Test get cell style with given illegal rows number.
	xlsx.GetCellStyle("Sheet1", "A")
448 449
	err = xlsx.Save()
	if err != nil {
450
		t.Error(err)
451 452 453 454
	}
}

func TestSetCellStyleBorder(t *testing.T) {
xurime's avatar
xurime 已提交
455
	xlsx, err := OpenFile("./test/Book2.xlsx")
456
	if err != nil {
457
		t.Error(err)
458
	}
459
	var style int
460
	// Test set border with invalid style parameter.
461
	style, err = xlsx.NewStyle("")
462 463 464
	if err != nil {
		t.Log(err)
	}
465 466
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

467
	// Test set border with invalid style index number.
468
	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}]}`)
469 470 471
	if err != nil {
		t.Log(err)
	}
472 473
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

474
	// Test set border on overlapping area with vertical variants shading styles gradient fill.
475
	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}]}`)
476 477 478
	if err != nil {
		t.Log(err)
	}
479 480 481
	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}}`)
482 483 484
	if err != nil {
		t.Log(err)
	}
485 486 487 488 489 490 491 492
	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)

493
	// Test set border and solid style pattern fill for a single cell.
494
	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}}`)
495 496 497
	if err != nil {
		t.Log(err)
	}
498 499

	xlsx.SetCellStyle("Sheet1", "O22", "O22", style)
500 501
	err = xlsx.Save()
	if err != nil {
502
		t.Error(err)
503 504 505
	}
}

506
func TestSetCellStyleNumberFormat(t *testing.T) {
xurime's avatar
xurime 已提交
507
	xlsx, err := OpenFile("./test/Book2.xlsx")
508
	if err != nil {
509
		t.Error(err)
510
	}
xurime's avatar
xurime 已提交
511
	// Test only set fill and number format for a cell.
512 513 514 515 516 517 518 519 520 521 522 523 524
	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)
			}
525
			style, err := xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":5},"number_format": ` + strconv.Itoa(d) + `}`)
526 527 528
			if err != nil {
				t.Log(err)
			}
529
			xlsx.SetCellStyle("Sheet2", c, c, style)
530 531 532
			t.Log(xlsx.GetCellValue("Sheet2", c))
		}
	}
533 534 535 536 537 538
	var style int
	style, err = xlsx.NewStyle(`{"number_format":-1}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet2", "L33", "L33", style)
539
	err = xlsx.Save()
540
	if err != nil {
541
		t.Error(err)
542
	}
543 544
}

545
func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
xurime's avatar
xurime 已提交
546
	xlsx, err := OpenFile("./test/Book3.xlsx")
547
	if err != nil {
548
		t.Error(err)
549 550
	}
	xlsx.SetCellValue("Sheet1", "A1", 56)
551
	xlsx.SetCellValue("Sheet1", "A2", -32.3)
552 553 554 555 556 557
	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)
558
	style, err = xlsx.NewStyle(`{"number_format": 188, "decimal_places": 31, "negred": true}`)
559 560 561 562 563 564 565 566 567 568
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet1", "A2", "A2", style)

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

xurime's avatar
xurime 已提交
569
	xlsx, err = OpenFile("./test/Book4.xlsx")
570 571 572
	if err != nil {
		t.Log(err)
	}
573 574
	xlsx.SetCellValue("Sheet1", "A1", 42920.5)
	xlsx.SetCellValue("Sheet1", "A2", 42920.5)
575

xurime's avatar
xurime 已提交
576
	_, err = xlsx.NewStyle(`{"number_format": 26, "lang": "zh-tw"}`)
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
	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 {
599
		t.Error(err)
600 601 602
	}
}

603 604 605 606 607 608 609 610 611 612 613 614 615 616
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)
xurime's avatar
xurime 已提交
617
	err = xlsx.SaveAs("./test/Book_custom_number_format.xlsx")
618
	if err != nil {
619
		t.Error(err)
620 621 622
	}
}

623
func TestSetCellStyleFill(t *testing.T) {
xurime's avatar
xurime 已提交
624
	xlsx, err := OpenFile("./test/Book2.xlsx")
625
	if err != nil {
626
		t.Error(err)
627
	}
628
	var style int
629
	// Test set fill for cell with invalid parameter.
630
	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":6}}`)
631 632 633
	if err != nil {
		t.Log(err)
	}
634 635 636
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF"],"shading":1}}`)
637 638 639
	if err != nil {
		t.Log(err)
	}
640 641 642
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":[],"pattern":1}}`)
643 644 645
	if err != nil {
		t.Log(err)
	}
646
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)
xurime's avatar
xurime 已提交
647

648
	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":19}}`)
649 650 651
	if err != nil {
		t.Log(err)
	}
652 653
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

654 655
	err = xlsx.Save()
	if err != nil {
656
		t.Error(err)
657 658 659 660
	}
}

func TestSetCellStyleFont(t *testing.T) {
xurime's avatar
xurime 已提交
661
	xlsx, err := OpenFile("./test/Book2.xlsx")
662
	if err != nil {
663
		t.Error(err)
664
	}
665 666
	var style int
	style, err = xlsx.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}`)
667 668 669
	if err != nil {
		t.Log(err)
	}
670 671 672
	xlsx.SetCellStyle("Sheet2", "A1", "A1", style)

	style, err = xlsx.NewStyle(`{"font":{"italic":true,"underline":"double"}}`)
673 674 675
	if err != nil {
		t.Log(err)
	}
676 677 678
	xlsx.SetCellStyle("Sheet2", "A2", "A2", style)

	style, err = xlsx.NewStyle(`{"font":{"bold":true}}`)
679 680 681
	if err != nil {
		t.Log(err)
	}
682 683 684
	xlsx.SetCellStyle("Sheet2", "A3", "A3", style)

	style, err = xlsx.NewStyle(`{"font":{"bold":true,"family":"","size":0,"color":"","underline":""}}`)
685 686 687
	if err != nil {
		t.Log(err)
	}
688 689 690
	xlsx.SetCellStyle("Sheet2", "A4", "A4", style)

	style, err = xlsx.NewStyle(`{"font":{"color":"#777777"}}`)
691 692 693
	if err != nil {
		t.Log(err)
	}
694
	xlsx.SetCellStyle("Sheet2", "A5", "A5", style)
695 696
	err = xlsx.Save()
	if err != nil {
697
		t.Error(err)
698 699
	}
}
700

701 702 703
func TestSetCellStyleProtection(t *testing.T) {
	xlsx, err := OpenFile("./test/Book2.xlsx")
	if err != nil {
704
		t.Error(err)
705 706 707 708 709 710 711 712 713
	}
	var style int
	style, err = xlsx.NewStyle(`{"protection":{"hidden":true, "locked":true}}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet2", "A6", "A6", style)
	err = xlsx.Save()
	if err != nil {
714
		t.Error(err)
715 716 717
	}
}

718
func TestSetDeleteSheet(t *testing.T) {
xurime's avatar
xurime 已提交
719
	xlsx, err := OpenFile("./test/Book3.xlsx")
720
	if err != nil {
721
		t.Error(err)
722 723 724 725
	}
	xlsx.DeleteSheet("XLSXSheet3")
	err = xlsx.Save()
	if err != nil {
726
		t.Error(err)
727
	}
xurime's avatar
xurime 已提交
728
	xlsx, err = OpenFile("./test/Book4.xlsx")
729
	if err != nil {
730
		t.Error(err)
731 732
	}
	xlsx.DeleteSheet("Sheet1")
733
	xlsx.AddComment("Sheet1", "A1", "")
xurime's avatar
xurime 已提交
734
	xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
xurime's avatar
xurime 已提交
735
	err = xlsx.SaveAs("./test/Book_delete_sheet.xlsx")
736
	if err != nil {
737
		t.Error(err)
738 739
	}
}
740 741

func TestGetPicture(t *testing.T) {
xurime's avatar
xurime 已提交
742
	xlsx, err := OpenFile("./test/Book2.xlsx")
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
	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))
xurime's avatar
xurime 已提交
764 765 766
	xlsx.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
	xlsx.getDrawingRelationships("", "")
	xlsx.getSheetRelationshipsTargetByID("", "")
767
	xlsx.deleteSheetRelationships("", "")
768
}
769

770
func TestSheetVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
771
	xlsx, err := OpenFile("./test/Book2.xlsx")
772
	if err != nil {
773
		t.Error(err)
774
	}
775 776 777 778
	xlsx.SetSheetVisible("Sheet2", false)
	xlsx.SetSheetVisible("Sheet1", false)
	xlsx.SetSheetVisible("Sheet1", true)
	xlsx.GetSheetVisible("Sheet1")
779 780
	err = xlsx.Save()
	if err != nil {
781
		t.Error(err)
782 783 784
	}
}

785
func TestRowVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
786
	xlsx, err := OpenFile("./test/Book2.xlsx")
787
	if err != nil {
788
		t.Error(err)
789
	}
790 791 792
	xlsx.SetRowVisible("Sheet3", 2, false)
	xlsx.SetRowVisible("Sheet3", 2, true)
	xlsx.GetRowVisible("Sheet3", 2)
793 794
	err = xlsx.Save()
	if err != nil {
795
		t.Error(err)
796 797 798
	}
}

799
func TestColumnVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
800
	xlsx, err := OpenFile("./test/Book2.xlsx")
801
	if err != nil {
802
		t.Error(err)
803 804 805 806 807 808 809
	}
	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 {
810
		t.Error(err)
811
	}
xurime's avatar
xurime 已提交
812
	xlsx, err = OpenFile("./test/Book3.xlsx")
813
	if err != nil {
814
		t.Error(err)
815 816 817 818
	}
	xlsx.GetColVisible("Sheet1", "B")
}

819
func TestCopySheet(t *testing.T) {
xurime's avatar
xurime 已提交
820
	xlsx, err := OpenFile("./test/Book2.xlsx")
821
	if err != nil {
822
		t.Error(err)
823 824 825 826 827
	}
	err = xlsx.CopySheet(0, -1)
	if err != nil {
		t.Log(err)
	}
828 829
	idx := xlsx.NewSheet("CopySheet")
	err = xlsx.CopySheet(1, idx)
830 831 832
	if err != nil {
		t.Log(err)
	}
833 834 835 836
	xlsx.SetCellValue("Sheet4", "F1", "Hello")
	if xlsx.GetCellValue("Sheet1", "F1") == "Hello" {
		t.Error("Invalid value \"Hello\" in Sheet1")
	}
837 838
	err = xlsx.Save()
	if err != nil {
839
		t.Error(err)
840 841
	}
}
842

xurime's avatar
xurime 已提交
843
func TestAddTable(t *testing.T) {
xurime's avatar
xurime 已提交
844
	xlsx, err := OpenFile("./test/Book2.xlsx")
xurime's avatar
xurime 已提交
845
	if err != nil {
846
		t.Error(err)
xurime's avatar
xurime 已提交
847
	}
848 849 850 851 852 853 854 855 856 857 858 859
	err = xlsx.AddTable("Sheet1", "B26", "A21", `{}`)
	if err != nil {
		t.Error(err)
	}
	err = xlsx.AddTable("Sheet2", "A2", "B5", `{"table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
	if err != nil {
		t.Error(err)
	}
	err = xlsx.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
	if err != nil {
		t.Error(err)
	}
xurime's avatar
xurime 已提交
860 861
	err = xlsx.Save()
	if err != nil {
862
		t.Error(err)
xurime's avatar
xurime 已提交
863 864 865
	}
}

866
func TestAddShape(t *testing.T) {
xurime's avatar
xurime 已提交
867
	xlsx, err := OpenFile("./test/Book2.xlsx")
868
	if err != nil {
869
		t.Error(err)
870
	}
871 872 873 874
	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}`)
875
	xlsx.AddShape("Sheet3", "H1", "")
876 877
	err = xlsx.Save()
	if err != nil {
878
		t.Error(err)
879 880 881
	}
}

882
func TestAddComments(t *testing.T) {
xurime's avatar
xurime 已提交
883
	xlsx, err := OpenFile("./test/Book2.xlsx")
884
	if err != nil {
885
		t.Error(err)
886
	}
xurime's avatar
xurime 已提交
887
	s := strings.Repeat("c", 32768)
888 889
	xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
	xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
890 891
	err = xlsx.Save()
	if err != nil {
892
		t.Error(err)
893
	}
R
Rad Cirskis 已提交
894 895 896 897 898
	allComments := xlsx.GetComments()
	if len(allComments) != 2 {
		t.Error("Expected 2 comment entry elements.")
	}

899 900
}

901
func TestAutoFilter(t *testing.T) {
xurime's avatar
xurime 已提交
902
	xlsx, err := OpenFile("./test/Book2.xlsx")
903
	if err != nil {
904
		t.Error(err)
905
	}
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
	formats := []string{``,
		`{"column":"B","expression":"x != blanks"}`,
		`{"column":"B","expression":"x == blanks"}`,
		`{"column":"B","expression":"x != nonblanks"}`,
		`{"column":"B","expression":"x == nonblanks"}`,
		`{"column":"B","expression":"x <= 1 and x >= 2"}`,
		`{"column":"B","expression":"x == 1 or x == 2"}`,
		`{"column":"B","expression":"x == 1 or x == 2*"}`,
		`{"column":"B","expression":"x <= 1 and x >= blanks"}`,
		`{"column":"B","expression":"x -- y or x == *2*"}`,
		`{"column":"B","expression":"x != y or x ? *2"}`,
		`{"column":"B","expression":"x -- y o r x == *2"}`,
		`{"column":"B","expression":"x -- y"}`,
		`{"column":"A","expression":"x -- y"}`,
	}
	for _, format := range formats {
		err = xlsx.AutoFilter("Sheet3", "D4", "B1", format)
		t.Log(err)
	}
925 926
	err = xlsx.Save()
	if err != nil {
927
		t.Error(err)
928 929 930
	}
}

931
func TestAddChart(t *testing.T) {
xurime's avatar
xurime 已提交
932
	xlsx, err := OpenFile("./test/Book1.xlsx")
933
	if err != nil {
934
		t.Error(err)
935
	}
xurime's avatar
xurime 已提交
936 937 938 939 940 941 942 943
	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)
	}
944
	xlsx.AddChart("Sheet1", "P1", "")
945 946 947 948 949 950 951
	xlsx.AddChart("Sheet1", "P1", `{"type":"col","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 2D Column 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":"colStacked","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 2D Stacked Column 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", "P16", `{"type":"colPercentStacked","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 100% Stacked Column 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", "X16", `{"type":"col3DClustered","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 Clustered Column 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", "P30", `{"type":"col3DStacked","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 3D 100% Stacked 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", "X30", `{"type":"col3DPercentStacked","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 3D 100% Stacked Column 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", "P45", `{"type":"col3D","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 3D Column 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"}`)
952 953
	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"}`)
954 955 956 957 958 959
	xlsx.AddChart("Sheet2", "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"}`)
	xlsx.AddChart("Sheet2", "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"}`)
	xlsx.AddChart("Sheet2", "P32", `{"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("Sheet2", "X32", `{"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"}`)
	xlsx.AddChart("Sheet2", "P48", `{"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 2D Clustered 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("Sheet2", "X48", `{"type":"barStacked","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 2D Stacked 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"}`)
960
	xlsx.AddChart("Sheet2", "P64", `{"type":"barPercentStacked","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 2D Stacked 100% 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"}`)
961
	xlsx.AddChart("Sheet2", "X64", `{"type":"bar3DClustered","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 3D Clustered 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"}`)
962 963
	xlsx.AddChart("Sheet2", "P80", `{"type":"bar3DStacked","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 3D Stacked 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","y_axis":{"maximum":7.5,"minimum":0.5}}`)
	xlsx.AddChart("Sheet2", "X80", `{"type":"bar3DPercentStacked","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 3D 100% Stacked 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","x_axis":{"reverse_order":true,"maximum":0,"minimum":0},"y_axis":{"reverse_order":true,"maximum":0,"minimum":0}}`)
964 965 966 967 968 969 970
	// area series charts
	xlsx.AddChart("Sheet2", "AF1", `{"type":"area","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 2D Area 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("Sheet2", "AN1", `{"type":"areaStacked","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 2D Stacked Area 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("Sheet2", "AF16", `{"type":"areaPercentStacked","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 2D 100% Stacked Area 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("Sheet2", "AN16", `{"type":"area3D","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 3D Area 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("Sheet2", "AF32", `{"type":"area3DStacked","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 3D Stacked Area 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("Sheet2", "AN32", `{"type":"area3DPercentStacked","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 3D 100% Stacked Area 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"}`)
971
	// Save xlsx file by the given path.
xurime's avatar
xurime 已提交
972
	err = xlsx.SaveAs("./test/Book_addchart.xlsx")
973
	if err != nil {
974
		t.Error(err)
975 976 977 978 979 980 981 982 983 984 985
	}
}

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)
		}
	}
986
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
987
	xlsx.MergeCell("Sheet1", "A1", "C3")
988 989 990
	err := xlsx.AutoFilter("Sheet1", "A2", "B2", `{"column":"B","expression":"x != blanks"}`)
	t.Log(err)
	xlsx.InsertCol("Sheet1", "A")
xurime's avatar
xurime 已提交
991
	err = xlsx.SaveAs("./test/Book_insertcol.xlsx")
992
	if err != nil {
993
		t.Error(err)
994 995 996 997 998 999 1000 1001 1002 1003 1004
	}
}

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)
		}
	}
1005
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
1006
	xlsx.SetCellHyperLink("Sheet1", "C5", "https://github.com", "External")
1007 1008
	xlsx.MergeCell("Sheet1", "A1", "B1")
	xlsx.MergeCell("Sheet1", "A2", "B2")
1009 1010
	xlsx.RemoveCol("Sheet1", "A")
	xlsx.RemoveCol("Sheet1", "A")
xurime's avatar
xurime 已提交
1011
	err := xlsx.SaveAs("./test/Book_removecol.xlsx")
1012
	if err != nil {
1013
		t.Error(err)
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
	}
}

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)
		}
	}
1025
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
1026 1027
	xlsx.InsertRow("Sheet1", -1)
	xlsx.InsertRow("Sheet1", 4)
xurime's avatar
xurime 已提交
1028
	err := xlsx.SaveAs("./test/Book_insertrow.xlsx")
1029
	if err != nil {
1030
		t.Error(err)
1031 1032 1033
	}
}

V
Veniamin Albaev 已提交
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
func TestDuplicateRow(t *testing.T) {
	const (
		file    = "./test/Book_DuplicateRow_%s.xlsx"
		sheet   = "Sheet1"
		a1      = "A1"
		b1      = "B1"
		a2      = "A2"
		b2      = "B2"
		a3      = "A3"
		b3      = "B3"
		a4      = "A4"
		b4      = "B4"
		a1Value = "A1 value"
		a2Value = "A2 value"
		a3Value = "A3 value"
		bnValue = "Bn value"
	)
	xlsx := NewFile()
	xlsx.SetCellStr(sheet, a1, a1Value)
	xlsx.SetCellStr(sheet, b1, bnValue)

	t.Run("FromSingleRow", func(t *testing.T) {
		xlsx.DuplicateRow(sheet, 1)
		xlsx.DuplicateRow(sheet, 2)

		if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "SignleRow"))) {
			assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a1))
			assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a2))
			assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a3))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b1))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b3))
		}
	})

	t.Run("UpdateDuplicatedRows", func(t *testing.T) {
		xlsx.SetCellStr(sheet, a2, a2Value)
		xlsx.SetCellStr(sheet, a3, a3Value)

		if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "Updated"))) {
			assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a1))
			assert.Equal(t, a2Value, xlsx.GetCellValue(sheet, a2))
			assert.Equal(t, a3Value, xlsx.GetCellValue(sheet, a3))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b1))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b3))
		}
	})

	t.Run("FromFirstOfMultipleRows", func(t *testing.T) {
		xlsx.DuplicateRow(sheet, 1)

		if assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(file, "FirstOfMultipleRows"))) {
			assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a1))
			assert.Equal(t, a1Value, xlsx.GetCellValue(sheet, a2))
			assert.Equal(t, a2Value, xlsx.GetCellValue(sheet, a3))
			assert.Equal(t, a3Value, xlsx.GetCellValue(sheet, a4))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b1))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b2))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b3))
			assert.Equal(t, bnValue, xlsx.GetCellValue(sheet, b4))
		}
	})
}

xurime's avatar
xurime 已提交
1099 1100 1101
func TestSetPane(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
1102 1103 1104 1105 1106 1107
	xlsx.NewSheet("Panes 2")
	xlsx.SetPanes("Panes 2", `{"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("Panes 3")
	xlsx.SetPanes("Panes 3", `{"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("Panes 4")
	xlsx.SetPanes("Panes 4", `{"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"}]}`)
1108
	xlsx.SetPanes("Panes 4", "")
xurime's avatar
xurime 已提交
1109
	err := xlsx.SaveAs("./test/Book_set_panes.xlsx")
xurime's avatar
xurime 已提交
1110
	if err != nil {
1111
		t.Error(err)
xurime's avatar
xurime 已提交
1112 1113 1114
	}
}

1115 1116 1117 1118 1119 1120 1121 1122
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)
		}
	}
1123
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
1124 1125
	xlsx.RemoveRow("Sheet1", -1)
	xlsx.RemoveRow("Sheet1", 4)
1126
	xlsx.MergeCell("Sheet1", "B3", "B5")
1127 1128 1129 1130 1131 1132 1133
	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)
xurime's avatar
xurime 已提交
1134
	err = xlsx.SaveAs("./test/Book_removerow.xlsx")
1135
	if err != nil {
1136
		t.Error(err)
1137 1138
	}
}
1139 1140 1141 1142

func TestConditionalFormat(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
1143
		for i := 0; i <= 15; i++ {
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
			xlsx.SetCellInt("Sheet1", ToAlphaString(i)+strconv.Itoa(j), j)
		}
	}
	var format1, format2, format3 int
	var err error
	// Rose format for bad conditional.
	format1, err = xlsx.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
	t.Log(err)
	// Light yellow format for neutral conditional.
	format2, err = xlsx.NewConditionalStyle(`{"fill":{"type":"pattern","color":["#FEEAA0"],"pattern":1}}`)
	t.Log(err)
	// Light green format for good conditional.
	format3, err = xlsx.NewConditionalStyle(`{"font":{"color":"#09600B"},"fill":{"type":"pattern","color":["#C7EECF"],"pattern":1}}`)
	t.Log(err)
	// Color scales: 2 color.
	xlsx.SetConditionalFormat("Sheet1", "A1:A10", `[{"type":"2_color_scale","criteria":"=","min_type":"min","max_type":"max","min_color":"#F8696B","max_color":"#63BE7B"}]`)
	// Color scales: 3 color.
	xlsx.SetConditionalFormat("Sheet1", "B1:B10", `[{"type":"3_color_scale","criteria":"=","min_type":"min","mid_type":"percentile","max_type":"max","min_color":"#F8696B","mid_color":"#FFEB84","max_color":"#63BE7B"}]`)
	// Hightlight cells rules: between...
	xlsx.SetConditionalFormat("Sheet1", "C1:C10", fmt.Sprintf(`[{"type":"cell","criteria":"between","format":%d,"minimum":"6","maximum":"8"}]`, format1))
	// Hightlight cells rules: Greater Than...
	xlsx.SetConditionalFormat("Sheet1", "D1:D10", fmt.Sprintf(`[{"type":"cell","criteria":">","format":%d,"value":"6"}]`, format3))
	// Hightlight cells rules: Equal To...
	xlsx.SetConditionalFormat("Sheet1", "E1:E10", fmt.Sprintf(`[{"type":"top","criteria":"=","format":%d}]`, format3))
	// Hightlight cells rules: Not Equal To...
	xlsx.SetConditionalFormat("Sheet1", "F1:F10", fmt.Sprintf(`[{"type":"unique","criteria":"=","format":%d}]`, format2))
	// Hightlight cells rules: Duplicate Values...
	xlsx.SetConditionalFormat("Sheet1", "G1:G10", fmt.Sprintf(`[{"type":"duplicate","criteria":"=","format":%d}]`, format2))
	// Top/Bottom rules: Top 10%.
	xlsx.SetConditionalFormat("Sheet1", "H1:H10", fmt.Sprintf(`[{"type":"top","criteria":"=","format":%d,"value":"6","percent":true}]`, format1))
	// Top/Bottom rules: Above Average...
	xlsx.SetConditionalFormat("Sheet1", "I1:I10", fmt.Sprintf(`[{"type":"average","criteria":"=","format":%d, "above_average": true}]`, format3))
	// Top/Bottom rules: Below Average...
	xlsx.SetConditionalFormat("Sheet1", "J1:J10", fmt.Sprintf(`[{"type":"average","criteria":"=","format":%d, "above_average": false}]`, format1))
	// Data Bars: Gradient Fill.
	xlsx.SetConditionalFormat("Sheet1", "K1:K10", `[{"type":"data_bar", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
1180 1181
	// Use a formula to determine which cells to format.
	xlsx.SetConditionalFormat("Sheet1", "L1:L10", fmt.Sprintf(`[{"type":"formula", "criteria":"L2<3", "format":%d}]`, format1))
1182 1183
	// Test set invalid format set in conditional format
	xlsx.SetConditionalFormat("Sheet1", "L1:L10", "")
xurime's avatar
xurime 已提交
1184
	err = xlsx.SaveAs("./test/Book_conditional_format.xlsx")
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
	if err != nil {
		t.Log(err)
	}

	// Set conditional format with illegal JSON string.
	_, err = xlsx.NewConditionalStyle("")
	t.Log(err)
	// Set conditional format with illegal valid type.
	xlsx.SetConditionalFormat("Sheet1", "K1:K10", `[{"type":"", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
	// Set conditional format with illegal criteria type.
	xlsx.SetConditionalFormat("Sheet1", "K1:K10", `[{"type":"data_bar", "criteria":"", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
	// Set conditional format with file without dxfs element.
xurime's avatar
xurime 已提交
1197
	xlsx, err = OpenFile("./test/Book1.xlsx")
1198 1199 1200 1201
	t.Log(err)
	_, err = xlsx.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
	t.Log(err)
}
xurime's avatar
xurime 已提交
1202 1203 1204 1205 1206 1207 1208 1209 1210

func TestTitleToNumber(t *testing.T) {
	if TitleToNumber("AK") != 36 {
		t.Error("Conver title to number failed")
	}
	if TitleToNumber("ak") != 36 {
		t.Error("Conver title to number failed")
	}
}
1211 1212 1213 1214

func TestSharedStrings(t *testing.T) {
	xlsx, err := OpenFile("./test/SharedStrings.xlsx")
	if err != nil {
1215
		t.Error(err)
1216 1217 1218 1219
		return
	}
	xlsx.GetRows("Sheet1")
}
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236

func TestSetSheetRow(t *testing.T) {
	xlsx, err := OpenFile("./test/Book1.xlsx")
	if err != nil {
		t.Error(err)
		return
	}
	xlsx.SetSheetRow("Sheet1", "B27", &[]interface{}{"cell", nil, int32(42), float64(42), time.Now()})
	xlsx.SetSheetRow("Sheet1", "", &[]interface{}{"cell", nil, 2})
	xlsx.SetSheetRow("Sheet1", "B27", []interface{}{})
	xlsx.SetSheetRow("Sheet1", "B27", &xlsx)
	err = xlsx.Save()
	if err != nil {
		t.Error(err)
		return
	}
}
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276

func TestRows(t *testing.T) {
	xlsx, err := OpenFile("./test/Book1.xlsx")
	if err != nil {
		t.Error(err)
		return
	}
	rows, err := xlsx.Rows("Sheet2")
	if err != nil {
		t.Error(err)
		return
	}
	rowStrs := make([][]string, 0)
	var i = 0
	for rows.Next() {
		i++
		columns := rows.Columns()
		rowStrs = append(rowStrs, columns)
	}
	if rows.Error() != nil {
		t.Error(rows.Error())
		return
	}
	dstRows := xlsx.GetRows("Sheet2")
	if len(dstRows) != len(rowStrs) {
		t.Error("values not equal")
		return
	}
	for i := 0; i < len(rowStrs); i++ {
		if !reflect.DeepEqual(trimSliceSpace(dstRows[i]), trimSliceSpace(rowStrs[i])) {
			t.Error("values not equal")
			return
		}
	}
	rows, err = xlsx.Rows("SheetN")
	if err != nil {
		t.Log(err)
	}
}

1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
func TestOutlineLevel(t *testing.T) {
	xlsx := NewFile()
	xlsx.NewSheet("Sheet2")
	xlsx.SetColOutlineLevel("Sheet1", "D", 4)
	xlsx.GetColOutlineLevel("Sheet1", "D")
	xlsx.GetColOutlineLevel("Shee2", "A")
	xlsx.SetColWidth("Sheet2", "A", "D", 13)
	xlsx.SetColOutlineLevel("Sheet2", "B", 2)
	xlsx.SetRowOutlineLevel("Sheet1", 2, 1)
	xlsx.GetRowOutlineLevel("Sheet1", 2)
	err := xlsx.SaveAs("./test/Book_outline_level.xlsx")
	if err != nil {
		t.Error(err)
		return
	}
	xlsx, err = OpenFile("./test/Book1.xlsx")
	if err != nil {
		t.Error(err)
		return
	}
	xlsx.SetColOutlineLevel("Sheet2", "B", 2)
}

xurime's avatar
xurime 已提交
1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
func TestThemeColor(t *testing.T) {
	t.Log(ThemeColor("000000", -0.1))
	t.Log(ThemeColor("000000", 0))
	t.Log(ThemeColor("000000", 1))
}

func TestHSL(t *testing.T) {
	var hsl HSL
	t.Log(hsl.RGBA())
	t.Log(hslModel(hsl))
	t.Log(hslModel(color.Gray16{Y: uint16(1)}))
	t.Log(HSLToRGB(0, 1, 0.4))
	t.Log(HSLToRGB(0, 1, 0.6))
	t.Log(hueToRGB(0, 0, -1))
	t.Log(hueToRGB(0, 0, 2))
	t.Log(hueToRGB(0, 0, 1.0/7))
	t.Log(hueToRGB(0, 0, 0.4))
	t.Log(hueToRGB(0, 0, 2.0/4))
	t.Log(RGBToHSL(255, 255, 0))
	t.Log(RGBToHSL(0, 255, 255))
	t.Log(RGBToHSL(250, 100, 50))
	t.Log(RGBToHSL(50, 100, 250))
	t.Log(RGBToHSL(250, 50, 100))
}

1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
func TestSearchSheet(t *testing.T) {
	xlsx, err := OpenFile("./test/SharedStrings.xlsx")
	if err != nil {
		t.Error(err)
		return
	}
	// Test search in a not exists worksheet.
	t.Log(xlsx.SearchSheet("Sheet4", ""))
	// Test search a not exists value.
	t.Log(xlsx.SearchSheet("Sheet1", "X"))
	t.Log(xlsx.SearchSheet("Sheet1", "A"))
}

R
r-uchino 已提交
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350
func TestRegSearchSheet(t *testing.T) {
	xlsx, err := OpenFile("./test/Book1.xlsx")
	if err != nil {
		t.Error(err)
		return
	}
	t.Log(xlsx.SearchSheet("Sheet1", "[0-9]"))
	// Test search in a not exists worksheet.
	t.Log(xlsx.SearchSheet("Sheet4", ""))
	// Test search a not exists value.
	t.Log(xlsx.SearchSheet("Sheet1", ""))
}

1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
func TestProtectSheet(t *testing.T) {
	xlsx := NewFile()
	xlsx.ProtectSheet("Sheet1", nil)
	xlsx.ProtectSheet("Sheet1", &FormatSheetProtection{
		Password:      "password",
		EditScenarios: false,
	})
	err := xlsx.SaveAs("./test/Book_protect_sheet.xlsx")
	if err != nil {
		t.Error(err)
	}
}

1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375
func TestUnprotectSheet(t *testing.T) {
	xlsx, err := OpenFile("./test/Book1.xlsx")
	if err != nil {
		t.Error(err)
	}
	xlsx.UnprotectSheet("Sheet1")
	err = xlsx.Save()
	if err != nil {
		t.Error(err)
	}
}

1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
func trimSliceSpace(s []string) []string {
	for {
		if len(s) > 0 && s[len(s)-1] == "" {
			s = s[:len(s)-1]
		} else {
			break
		}
	}
	return s
}