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

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

15
func TestOpenFile(t *testing.T) {
xurime's avatar
xurime 已提交
16
	// Test update a XLSX file.
xurime's avatar
xurime 已提交
17
	xlsx, err := OpenFile("./test/Book1.xlsx")
18 19 20
	if err != nil {
		t.Log(err)
	}
21
	// Test get all the rows in a not exists worksheet.
22
	rows := xlsx.GetRows("Sheet4")
23
	// Test get all the rows in a worksheet.
24
	rows = xlsx.GetRows("Sheet2")
25 26 27 28 29 30
	for _, row := range rows {
		for _, cell := range row {
			t.Log(cell, "\t")
		}
		t.Log("\r\n")
	}
31
	xlsx.UpdateLinkedValue()
32 33
	xlsx.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(100.1588), 'f', -1, 32))
	xlsx.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
34 35
	// Test set cell value with illegal row number.
	xlsx.SetCellDefault("Sheet2", "A", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
36
	xlsx.SetCellInt("Sheet2", "A1", 100)
37 38
	// Test set cell integer value with illegal row number.
	xlsx.SetCellInt("Sheet2", "A", 100)
39
	xlsx.SetCellStr("Sheet2", "C11", "Knowns")
40
	// Test max characters in a cell.
41 42 43
	xlsx.SetCellStr("Sheet2", "D11", strings.Repeat("c", 32769))
	xlsx.NewSheet(":\\/?*[]Maximum 31 characters allowed in sheet title.")
	// Test set worksheet name with illegal name.
44 45
	xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")
	xlsx.SetCellInt("Sheet3", "A23", 10)
46 47
	xlsx.SetCellStr("Sheet3", "b230", "10")
	xlsx.SetCellStr("Sheet10", "b230", "10")
48 49
	// Test set cell string value with illegal row number.
	xlsx.SetCellStr("Sheet10", "A", "10")
50
	xlsx.SetActiveSheet(2)
51 52
	// Test get cell formula with given rows number.
	xlsx.GetCellFormula("Sheet1", "B19")
53
	// Test get cell formula with illegal worksheet name.
54 55 56 57
	xlsx.GetCellFormula("Sheet2", "B20")
	// Test get cell formula with illegal rows number.
	xlsx.GetCellFormula("Sheet1", "B20")
	xlsx.GetCellFormula("Sheet1", "B")
xurime's avatar
xurime 已提交
58
	// Test read cell value with given illegal rows number.
59
	xlsx.GetCellValue("Sheet2", "a-1")
60
	xlsx.GetCellValue("Sheet2", "A")
xurime's avatar
xurime 已提交
61
	// Test read cell value with given lowercase column number.
62 63 64 65
	xlsx.GetCellValue("Sheet2", "a5")
	xlsx.GetCellValue("Sheet2", "C11")
	xlsx.GetCellValue("Sheet2", "D11")
	xlsx.GetCellValue("Sheet2", "D12")
xurime's avatar
xurime 已提交
66
	// Test SetCellValue function.
67
	xlsx.SetCellValue("Sheet2", "F1", " Hello")
68 69
	xlsx.SetCellValue("Sheet2", "G1", []byte("World"))
	xlsx.SetCellValue("Sheet2", "F2", 42)
70 71 72 73 74 75 76 77 78 79 80 81 82 83
	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)
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
	// 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)
		}
	}
99
	xlsx.SetCellValue("Sheet2", "G2", nil)
100
	xlsx.SetCellValue("Sheet2", "G4", time.Now())
101 102
	// 02:46:40
	xlsx.SetCellValue("Sheet2", "G5", time.Duration(1e13))
xurime's avatar
xurime 已提交
103
	// Test completion column.
104
	xlsx.SetCellValue("Sheet2", "M2", nil)
xurime's avatar
xurime 已提交
105
	// Test read cell value with given axis large than exists row.
106
	xlsx.GetCellValue("Sheet2", "E231")
107
	// Test get active worksheet of XLSX and get worksheet name of XLSX by given worksheet index.
108
	xlsx.GetSheetName(xlsx.GetActiveSheetIndex())
109
	// Test get worksheet index of XLSX by given worksheet name.
110
	xlsx.GetSheetIndex("Sheet1")
111
	// Test get worksheet name of XLSX by given invalid worksheet index.
112
	xlsx.GetSheetName(4)
113
	// Test get worksheet map of XLSX.
114
	xlsx.GetSheetMap()
115
	for i := 1; i <= 300; i++ {
116
		xlsx.SetCellStr("Sheet3", "c"+strconv.Itoa(i), strconv.Itoa(i))
117 118 119 120 121 122
	}
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
	// Test write file to not exist directory.
123
	err = xlsx.SaveAs("")
124 125
	if err != nil {
		t.Log(err)
xurime's avatar
xurime 已提交
126
	}
127

128 129 130
}

func TestAddPicture(t *testing.T) {
xurime's avatar
xurime 已提交
131
	xlsx, err := OpenFile("./test/Book1.xlsx")
xurime's avatar
xurime 已提交
132
	if err != nil {
133
		t.Log(err)
xurime's avatar
xurime 已提交
134
	}
135 136
	// 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"}`)
137 138 139
	if err != nil {
		t.Log(err)
	}
140 141
	// Test add picture to worksheet with offset and external hyperlink.
	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"}`)
142 143 144
	if err != nil {
		t.Log(err)
	}
145
	// Test add picture to worksheet with invalid file path.
146
	err = xlsx.AddPicture("Sheet1", "G21", "./test/images/excel.icon", "")
147 148 149
	if err != nil {
		t.Log(err)
	}
150
	// Test add picture to worksheet with unsupport file type.
xurime's avatar
xurime 已提交
151
	err = xlsx.AddPicture("Sheet1", "G21", "./test/Book1.xlsx", "")
152 153 154
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
155
	// Test write file to given path.
xurime's avatar
xurime 已提交
156
	err = xlsx.SaveAs("./test/Book2.xlsx")
157 158 159
	if err != nil {
		t.Log(err)
	}
160
}
xurime's avatar
xurime 已提交
161

162
func TestBrokenFile(t *testing.T) {
xurime's avatar
xurime 已提交
163
	// Test write file with broken file struct.
164 165
	xlsx := File{}
	err := xlsx.Save()
xurime's avatar
xurime 已提交
166 167 168 169
	if err != nil {
		t.Log(err)
	}
	// Test write file with broken file struct with given path.
xurime's avatar
xurime 已提交
170
	err = xlsx.SaveAs("./test/Book3.xlsx")
xurime's avatar
xurime 已提交
171 172 173 174
	if err != nil {
		t.Log(err)
	}

175 176
	// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
	f3, err := OpenFile("./test/badWorkbook.xlsx")
xurime's avatar
xurime 已提交
177
	f3.GetActiveSheetIndex()
178
	f3.SetActiveSheet(2)
179 180 181
	if err != nil {
		t.Log(err)
	}
182 183

	// Test open a XLSX file with given illegal path.
xurime's avatar
xurime 已提交
184
	_, err = OpenFile("./test/Book.xlsx")
185 186 187
	if err != nil {
		t.Log(err)
	}
188 189
}

190
func TestNewFile(t *testing.T) {
191
	// Test create a XLSX file.
192
	xlsx := NewFile()
193 194 195 196
	xlsx.NewSheet("XLSXSheet2")
	xlsx.NewSheet("XLSXSheet3")
	xlsx.SetCellInt("XLSXSheet2", "A23", 56)
	xlsx.SetCellStr("Sheet1", "B20", "42")
197
	xlsx.SetActiveSheet(0)
198
	// Test add picture to sheet with scaling.
199
	err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5}`)
xurime's avatar
xurime 已提交
200
	if err != nil {
201
		t.Log(err)
xurime's avatar
xurime 已提交
202
	}
203
	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "")
xurime's avatar
xurime 已提交
204 205 206
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
207
	err = xlsx.SaveAs("./test/Book3.xlsx")
208 209 210
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
211
}
212

213
func TestColWidth(t *testing.T) {
214
	xlsx := NewFile()
215 216 217 218
	xlsx.SetColWidth("Sheet1", "B", "A", 12)
	xlsx.SetColWidth("Sheet1", "A", "B", 12)
	xlsx.GetColWidth("Sheet1", "A")
	xlsx.GetColWidth("Sheet1", "C")
xurime's avatar
xurime 已提交
219
	err := xlsx.SaveAs("./test/Book4.xlsx")
220 221 222
	if err != nil {
		t.Log(err)
	}
223 224 225 226 227 228 229 230 231
	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))
xurime's avatar
xurime 已提交
232
	err := xlsx.SaveAs("./test/Book5.xlsx")
233 234 235 236
	if err != nil {
		t.Log(err)
	}
	convertColWidthToPixels(0)
237 238 239
}

func TestSetCellHyperLink(t *testing.T) {
xurime's avatar
xurime 已提交
240
	xlsx, err := OpenFile("./test/Book1.xlsx")
241 242 243 244
	if err != nil {
		t.Log(err)
	}
	// Test set cell hyperlink in a work sheet already have hyperlinks.
245
	xlsx.SetCellHyperLink("Sheet1", "B19", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
246
	// Test add first hyperlink in a work sheet.
247
	xlsx.SetCellHyperLink("Sheet2", "C1", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
248
	// Test add Location hyperlink in a work sheet.
249 250 251
	xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location")
	xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", "")
	xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location")
252 253 254 255 256 257
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

258
func TestGetCellHyperLink(t *testing.T) {
xurime's avatar
xurime 已提交
259
	xlsx, err := OpenFile("./test/Book1.xlsx")
260 261 262 263 264 265 266 267 268 269 270 271 272
	if err != nil {
		t.Log(err)
	}
	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)
}

273
func TestSetCellFormula(t *testing.T) {
xurime's avatar
xurime 已提交
274
	xlsx, err := OpenFile("./test/Book1.xlsx")
275 276 277
	if err != nil {
		t.Log(err)
	}
278 279
	xlsx.SetCellFormula("Sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)")
	xlsx.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)")
280 281
	// Test set cell formula with illegal rows number.
	xlsx.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)")
282
	err = xlsx.Save()
283 284 285 286
	if err != nil {
		t.Log(err)
	}
}
287 288

func TestSetSheetBackground(t *testing.T) {
xurime's avatar
xurime 已提交
289
	xlsx, err := OpenFile("./test/Book1.xlsx")
290 291 292
	if err != nil {
		t.Log(err)
	}
293
	err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.png")
294 295 296
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
297
	err = xlsx.SetSheetBackground("Sheet2", "./test/Book1.xlsx")
298 299 300
	if err != nil {
		t.Log(err)
	}
301
	err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg")
302 303 304
	if err != nil {
		t.Log(err)
	}
305
	err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg")
306 307 308 309 310 311 312 313
	if err != nil {
		t.Log(err)
	}
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
xurime's avatar
xurime 已提交
314

315
func TestMergeCell(t *testing.T) {
xurime's avatar
xurime 已提交
316
	xlsx, err := OpenFile("./test/Book1.xlsx")
xurime's avatar
xurime 已提交
317 318 319
	if err != nil {
		t.Log(err)
	}
320 321 322 323 324 325 326 327 328 329 330
	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))
331
	xlsx.SetCellHyperLink("Sheet1", "J11", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
332 333 334
	xlsx.SetCellFormula("Sheet1", "G12", "SUM(Sheet1!B19,Sheet1!C19)")
	xlsx.GetCellValue("Sheet1", "H11")
	xlsx.GetCellFormula("Sheet1", "G12")
xurime's avatar
xurime 已提交
335 336 337 338 339
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
N
Nikolas Silva 已提交
340

341
func TestSetCellStyleAlignment(t *testing.T) {
xurime's avatar
xurime 已提交
342
	xlsx, err := OpenFile("./test/Book2.xlsx")
343 344 345
	if err != nil {
		t.Log(err)
	}
346 347 348 349 350 351
	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)
352 353 354 355 356
	// 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")
357 358 359 360 361 362 363
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

func TestSetCellStyleBorder(t *testing.T) {
xurime's avatar
xurime 已提交
364
	xlsx, err := OpenFile("./test/Book2.xlsx")
365 366 367
	if err != nil {
		t.Log(err)
	}
368
	var style int
369
	// Test set border with invalid style parameter.
370
	style, err = xlsx.NewStyle("")
371 372 373
	if err != nil {
		t.Log(err)
	}
374 375
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

376
	// Test set border with invalid style index number.
377
	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}]}`)
378 379 380
	if err != nil {
		t.Log(err)
	}
381 382
	xlsx.SetCellStyle("Sheet1", "J21", "L25", style)

383
	// Test set border on overlapping area with vertical variants shading styles gradient fill.
384
	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}]}`)
385 386 387
	if err != nil {
		t.Log(err)
	}
388 389 390
	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}}`)
391 392 393
	if err != nil {
		t.Log(err)
	}
394 395 396 397 398 399 400 401
	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)

402
	// Test set border and solid style pattern fill for a single cell.
403
	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}}`)
404 405 406
	if err != nil {
		t.Log(err)
	}
407 408

	xlsx.SetCellStyle("Sheet1", "O22", "O22", style)
409 410 411 412 413 414
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

415
func TestSetCellStyleNumberFormat(t *testing.T) {
xurime's avatar
xurime 已提交
416
	xlsx, err := OpenFile("./test/Book2.xlsx")
417 418 419
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
420
	// Test only set fill and number format for a cell.
421 422 423 424 425 426 427 428 429 430 431 432 433
	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)
			}
434
			style, err := xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":5},"number_format": ` + strconv.Itoa(d) + `}`)
435 436 437
			if err != nil {
				t.Log(err)
			}
438
			xlsx.SetCellStyle("Sheet2", c, c, style)
439 440 441
			t.Log(xlsx.GetCellValue("Sheet2", c))
		}
	}
442 443 444 445 446 447
	var style int
	style, err = xlsx.NewStyle(`{"number_format":-1}`)
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellStyle("Sheet2", "L33", "L33", style)
448
	err = xlsx.Save()
449 450 451
	if err != nil {
		t.Log(err)
	}
452 453
}

454
func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
xurime's avatar
xurime 已提交
455
	xlsx, err := OpenFile("./test/Book3.xlsx")
456 457 458 459
	if err != nil {
		t.Log(err)
	}
	xlsx.SetCellValue("Sheet1", "A1", 56)
460
	xlsx.SetCellValue("Sheet1", "A2", -32.3)
461 462 463 464 465 466
	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)
467
	style, err = xlsx.NewStyle(`{"number_format": 188, "decimal_places": 31, "negred": true}`)
468 469 470 471 472 473 474 475 476 477
	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 已提交
478
	xlsx, err = OpenFile("./test/Book4.xlsx")
479 480 481
	if err != nil {
		t.Log(err)
	}
482 483
	xlsx.SetCellValue("Sheet1", "A1", 42920.5)
	xlsx.SetCellValue("Sheet1", "A2", 42920.5)
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511

	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)
	}
}

512 513 514 515 516 517 518 519 520 521 522 523 524 525
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 已提交
526
	err = xlsx.SaveAs("./test/Book_custom_number_format.xlsx")
527 528 529 530 531
	if err != nil {
		t.Log(err)
	}
}

532
func TestSetCellStyleFill(t *testing.T) {
xurime's avatar
xurime 已提交
533
	xlsx, err := OpenFile("./test/Book2.xlsx")
534 535 536
	if err != nil {
		t.Log(err)
	}
537
	var style int
538
	// Test set fill for cell with invalid parameter.
539
	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":6}}`)
540 541 542
	if err != nil {
		t.Log(err)
	}
543 544 545
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF"],"shading":1}}`)
546 547 548
	if err != nil {
		t.Log(err)
	}
549 550 551
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":[],"pattern":1}}`)
552 553 554
	if err != nil {
		t.Log(err)
	}
555
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)
xurime's avatar
xurime 已提交
556

557
	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":19}}`)
558 559 560
	if err != nil {
		t.Log(err)
	}
561 562
	xlsx.SetCellStyle("Sheet1", "O23", "O23", style)

563 564 565
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
566 567 568 569
	}
}

func TestSetCellStyleFont(t *testing.T) {
xurime's avatar
xurime 已提交
570
	xlsx, err := OpenFile("./test/Book2.xlsx")
571 572 573
	if err != nil {
		t.Log(err)
	}
574 575
	var style int
	style, err = xlsx.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}`)
576 577 578
	if err != nil {
		t.Log(err)
	}
579 580 581
	xlsx.SetCellStyle("Sheet2", "A1", "A1", style)

	style, err = xlsx.NewStyle(`{"font":{"italic":true,"underline":"double"}}`)
582 583 584
	if err != nil {
		t.Log(err)
	}
585 586 587
	xlsx.SetCellStyle("Sheet2", "A2", "A2", style)

	style, err = xlsx.NewStyle(`{"font":{"bold":true}}`)
588 589 590
	if err != nil {
		t.Log(err)
	}
591 592 593
	xlsx.SetCellStyle("Sheet2", "A3", "A3", style)

	style, err = xlsx.NewStyle(`{"font":{"bold":true,"family":"","size":0,"color":"","underline":""}}`)
594 595 596
	if err != nil {
		t.Log(err)
	}
597 598 599
	xlsx.SetCellStyle("Sheet2", "A4", "A4", style)

	style, err = xlsx.NewStyle(`{"font":{"color":"#777777"}}`)
600 601 602
	if err != nil {
		t.Log(err)
	}
603
	xlsx.SetCellStyle("Sheet2", "A5", "A5", style)
604 605 606
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
607 608
	}
}
609

610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
func TestSetCellStyleProtection(t *testing.T) {
	xlsx, err := OpenFile("./test/Book2.xlsx")
	if err != nil {
		t.Log(err)
	}
	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 {
		t.Log(err)
	}
}

627
func TestSetDeleteSheet(t *testing.T) {
xurime's avatar
xurime 已提交
628
	xlsx, err := OpenFile("./test/Book3.xlsx")
629 630 631 632 633 634 635 636
	if err != nil {
		t.Log(err)
	}
	xlsx.DeleteSheet("XLSXSheet3")
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
637
	xlsx, err = OpenFile("./test/Book4.xlsx")
638 639 640 641
	if err != nil {
		t.Log(err)
	}
	xlsx.DeleteSheet("Sheet1")
xurime's avatar
xurime 已提交
642
	xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
xurime's avatar
xurime 已提交
643
	err = xlsx.SaveAs("./test/Book_delete_sheet.xlsx")
644 645 646 647
	if err != nil {
		t.Log(err)
	}
}
648 649

func TestGetPicture(t *testing.T) {
xurime's avatar
xurime 已提交
650
	xlsx, err := OpenFile("./test/Book2.xlsx")
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
	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 已提交
672 673 674
	xlsx.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
	xlsx.getDrawingRelationships("", "")
	xlsx.getSheetRelationshipsTargetByID("", "")
675
	xlsx.deleteSheetRelationships("", "")
676
}
677

678
func TestSheetVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
679
	xlsx, err := OpenFile("./test/Book2.xlsx")
680 681 682
	if err != nil {
		t.Log(err)
	}
683 684 685 686
	xlsx.SetSheetVisible("Sheet2", false)
	xlsx.SetSheetVisible("Sheet1", false)
	xlsx.SetSheetVisible("Sheet1", true)
	xlsx.GetSheetVisible("Sheet1")
687 688 689 690 691 692
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

693
func TestRowVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
694
	xlsx, err := OpenFile("./test/Book2.xlsx")
695 696 697
	if err != nil {
		t.Log(err)
	}
698 699 700
	xlsx.SetRowVisible("Sheet3", 2, false)
	xlsx.SetRowVisible("Sheet3", 2, true)
	xlsx.GetRowVisible("Sheet3", 2)
701 702 703 704 705 706
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

707
func TestColumnVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
708
	xlsx, err := OpenFile("./test/Book2.xlsx")
709 710 711 712 713 714 715 716 717 718 719
	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)
	}
xurime's avatar
xurime 已提交
720
	xlsx, err = OpenFile("./test/Book3.xlsx")
721 722 723 724 725 726
	if err != nil {
		t.Log(err)
	}
	xlsx.GetColVisible("Sheet1", "B")
}

727
func TestCopySheet(t *testing.T) {
xurime's avatar
xurime 已提交
728
	xlsx, err := OpenFile("./test/Book2.xlsx")
729 730 731 732 733 734 735
	if err != nil {
		t.Log(err)
	}
	err = xlsx.CopySheet(0, -1)
	if err != nil {
		t.Log(err)
	}
736 737
	idx := xlsx.NewSheet("CopySheet")
	err = xlsx.CopySheet(1, idx)
738 739 740
	if err != nil {
		t.Log(err)
	}
741 742 743 744
	xlsx.SetCellValue("Sheet4", "F1", "Hello")
	if xlsx.GetCellValue("Sheet1", "F1") == "Hello" {
		t.Error("Invalid value \"Hello\" in Sheet1")
	}
745 746 747 748 749
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
750

xurime's avatar
xurime 已提交
751
func TestAddTable(t *testing.T) {
xurime's avatar
xurime 已提交
752
	xlsx, err := OpenFile("./test/Book2.xlsx")
xurime's avatar
xurime 已提交
753 754 755 756 757 758 759 760 761 762 763 764
	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)
	}
}

765
func TestAddShape(t *testing.T) {
xurime's avatar
xurime 已提交
766
	xlsx, err := OpenFile("./test/Book2.xlsx")
767 768 769
	if err != nil {
		t.Log(err)
	}
770 771 772 773
	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}`)
774 775 776 777 778 779
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

780
func TestAddComments(t *testing.T) {
xurime's avatar
xurime 已提交
781
	xlsx, err := OpenFile("./test/Book2.xlsx")
782 783 784
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
785
	s := strings.Repeat("c", 32768)
786 787
	xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
	xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
788 789 790 791 792 793
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

794
func TestAutoFilter(t *testing.T) {
xurime's avatar
xurime 已提交
795
	xlsx, err := OpenFile("./test/Book2.xlsx")
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
	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)
	}
}

833
func TestAddChart(t *testing.T) {
xurime's avatar
xurime 已提交
834
	xlsx, err := OpenFile("./test/Book1.xlsx")
835 836 837
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
838 839 840 841 842 843 844 845
	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)
	}
846 847 848 849 850 851 852
	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"}`)
853 854
	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"}`)
855 856 857 858 859 860 861 862 863 864
	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"}`)
	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 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", "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"}`)
	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"}`)
	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"}`)
865
	// Save xlsx file by the given path.
xurime's avatar
xurime 已提交
866
	err = xlsx.SaveAs("./test/Book_addchart.xlsx")
867 868 869 870 871 872 873 874 875 876 877 878 879
	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)
		}
	}
880
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
881
	xlsx.MergeCell("Sheet1", "A1", "C3")
882 883 884
	err := xlsx.AutoFilter("Sheet1", "A2", "B2", `{"column":"B","expression":"x != blanks"}`)
	t.Log(err)
	xlsx.InsertCol("Sheet1", "A")
xurime's avatar
xurime 已提交
885
	err = xlsx.SaveAs("./test/Book_insertcol.xlsx")
886 887 888 889 890 891 892 893 894 895 896 897 898
	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)
		}
	}
899
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
900
	xlsx.SetCellHyperLink("Sheet1", "C5", "https://github.com", "External")
901 902
	xlsx.MergeCell("Sheet1", "A1", "B1")
	xlsx.MergeCell("Sheet1", "A2", "B2")
903 904
	xlsx.RemoveCol("Sheet1", "A")
	xlsx.RemoveCol("Sheet1", "A")
xurime's avatar
xurime 已提交
905
	err := xlsx.SaveAs("./test/Book_removecol.xlsx")
906 907 908 909 910 911 912 913 914 915 916 917 918
	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)
		}
	}
919
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
920 921
	xlsx.InsertRow("Sheet1", -1)
	xlsx.InsertRow("Sheet1", 4)
xurime's avatar
xurime 已提交
922
	err := xlsx.SaveAs("./test/Book_insertrow.xlsx")
923 924 925 926 927
	if err != nil {
		t.Log(err)
	}
}

xurime's avatar
xurime 已提交
928 929 930
func TestSetPane(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
931 932 933 934 935 936
	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"}]}`)
xurime's avatar
xurime 已提交
937
	err := xlsx.SaveAs("./test/Book_set_panes.xlsx")
xurime's avatar
xurime 已提交
938 939 940 941 942
	if err != nil {
		t.Log(err)
	}
}

943 944 945 946 947 948 949 950
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)
		}
	}
951
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
952 953
	xlsx.RemoveRow("Sheet1", -1)
	xlsx.RemoveRow("Sheet1", 4)
954
	xlsx.MergeCell("Sheet1", "B3", "B5")
955 956 957 958 959 960 961
	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 已提交
962
	err = xlsx.SaveAs("./test/Book_removerow.xlsx")
963 964 965 966
	if err != nil {
		t.Log(err)
	}
}
967 968 969 970

func TestConditionalFormat(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
971
		for i := 0; i <= 15; i++ {
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
			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"}]`)
1008 1009
	// Use a formula to determine which cells to format.
	xlsx.SetConditionalFormat("Sheet1", "L1:L10", fmt.Sprintf(`[{"type":"formula", "criteria":"L2<3", "format":%d}]`, format1))
xurime's avatar
xurime 已提交
1010
	err = xlsx.SaveAs("./test/Book_conditional_format.xlsx")
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
	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 已提交
1023
	xlsx, err = OpenFile("./test/Book1.xlsx")
1024 1025 1026 1027
	t.Log(err)
	_, err = xlsx.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
	t.Log(err)
}
xurime's avatar
xurime 已提交
1028 1029 1030 1031 1032 1033 1034 1035 1036

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")
	}
}
1037 1038 1039 1040

func TestSharedStrings(t *testing.T) {
	xlsx, err := OpenFile("./test/SharedStrings.xlsx")
	if err != nil {
1041
		t.Error(err)
1042 1043 1044 1045
		return
	}
	xlsx.GetRows("Sheet1")
}
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062

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
	}
}