excelize_test.go 45.5 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

func TestSetDeleteSheet(t *testing.T) {
xurime's avatar
xurime 已提交
611
	xlsx, err := OpenFile("./test/Book3.xlsx")
612 613 614 615 616 617 618 619
	if err != nil {
		t.Log(err)
	}
	xlsx.DeleteSheet("XLSXSheet3")
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
620
	xlsx, err = OpenFile("./test/Book4.xlsx")
621 622 623 624
	if err != nil {
		t.Log(err)
	}
	xlsx.DeleteSheet("Sheet1")
xurime's avatar
xurime 已提交
625
	xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
xurime's avatar
xurime 已提交
626
	err = xlsx.SaveAs("./test/Book_delete_sheet.xlsx")
627 628 629 630
	if err != nil {
		t.Log(err)
	}
}
631 632

func TestGetPicture(t *testing.T) {
xurime's avatar
xurime 已提交
633
	xlsx, err := OpenFile("./test/Book2.xlsx")
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
	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 已提交
655 656 657
	xlsx.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
	xlsx.getDrawingRelationships("", "")
	xlsx.getSheetRelationshipsTargetByID("", "")
658
	xlsx.deleteSheetRelationships("", "")
659
}
660

661
func TestSheetVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
662
	xlsx, err := OpenFile("./test/Book2.xlsx")
663 664 665
	if err != nil {
		t.Log(err)
	}
666 667 668 669
	xlsx.SetSheetVisible("Sheet2", false)
	xlsx.SetSheetVisible("Sheet1", false)
	xlsx.SetSheetVisible("Sheet1", true)
	xlsx.GetSheetVisible("Sheet1")
670 671 672 673 674 675
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

676
func TestRowVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
677
	xlsx, err := OpenFile("./test/Book2.xlsx")
678 679 680
	if err != nil {
		t.Log(err)
	}
681 682 683
	xlsx.SetRowVisible("Sheet3", 2, false)
	xlsx.SetRowVisible("Sheet3", 2, true)
	xlsx.GetRowVisible("Sheet3", 2)
684 685 686 687 688 689
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

690
func TestColumnVisibility(t *testing.T) {
xurime's avatar
xurime 已提交
691
	xlsx, err := OpenFile("./test/Book2.xlsx")
692 693 694 695 696 697 698 699 700 701 702
	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 已提交
703
	xlsx, err = OpenFile("./test/Book3.xlsx")
704 705 706 707 708 709
	if err != nil {
		t.Log(err)
	}
	xlsx.GetColVisible("Sheet1", "B")
}

710
func TestCopySheet(t *testing.T) {
xurime's avatar
xurime 已提交
711
	xlsx, err := OpenFile("./test/Book2.xlsx")
712 713 714 715 716 717 718
	if err != nil {
		t.Log(err)
	}
	err = xlsx.CopySheet(0, -1)
	if err != nil {
		t.Log(err)
	}
719 720
	idx := xlsx.NewSheet("CopySheet")
	err = xlsx.CopySheet(1, idx)
721 722 723
	if err != nil {
		t.Log(err)
	}
724 725 726 727
	xlsx.SetCellValue("Sheet4", "F1", "Hello")
	if xlsx.GetCellValue("Sheet1", "F1") == "Hello" {
		t.Error("Invalid value \"Hello\" in Sheet1")
	}
728 729 730 731 732
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}
733

xurime's avatar
xurime 已提交
734
func TestAddTable(t *testing.T) {
xurime's avatar
xurime 已提交
735
	xlsx, err := OpenFile("./test/Book2.xlsx")
xurime's avatar
xurime 已提交
736 737 738 739 740 741 742 743 744 745 746 747
	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)
	}
}

748
func TestAddShape(t *testing.T) {
xurime's avatar
xurime 已提交
749
	xlsx, err := OpenFile("./test/Book2.xlsx")
750 751 752
	if err != nil {
		t.Log(err)
	}
753 754 755 756
	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}`)
757 758 759 760 761 762
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

763
func TestAddComments(t *testing.T) {
xurime's avatar
xurime 已提交
764
	xlsx, err := OpenFile("./test/Book2.xlsx")
765 766 767
	if err != nil {
		t.Log(err)
	}
xurime's avatar
xurime 已提交
768
	s := strings.Repeat("c", 32768)
769 770
	xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
	xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
771 772 773 774 775 776
	err = xlsx.Save()
	if err != nil {
		t.Log(err)
	}
}

777
func TestAutoFilter(t *testing.T) {
xurime's avatar
xurime 已提交
778
	xlsx, err := OpenFile("./test/Book2.xlsx")
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
	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)
	}
}

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

xurime's avatar
xurime 已提交
911 912 913
func TestSetPane(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
914 915 916 917 918 919
	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 已提交
920
	err := xlsx.SaveAs("./test/Book_set_panes.xlsx")
xurime's avatar
xurime 已提交
921 922 923 924 925
	if err != nil {
		t.Log(err)
	}
}

926 927 928 929 930 931 932 933
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)
		}
	}
934
	xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
935 936
	xlsx.RemoveRow("Sheet1", -1)
	xlsx.RemoveRow("Sheet1", 4)
937
	xlsx.MergeCell("Sheet1", "B3", "B5")
938 939 940 941 942 943 944
	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 已提交
945
	err = xlsx.SaveAs("./test/Book_removerow.xlsx")
946 947 948 949
	if err != nil {
		t.Log(err)
	}
}
950 951 952 953

func TestConditionalFormat(t *testing.T) {
	xlsx := NewFile()
	for j := 1; j <= 10; j++ {
954
		for i := 0; i <= 15; i++ {
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
			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"}]`)
991 992
	// 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 已提交
993
	err = xlsx.SaveAs("./test/Book_conditional_format.xlsx")
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
	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 已提交
1006
	xlsx, err = OpenFile("./test/Book1.xlsx")
1007 1008 1009 1010
	t.Log(err)
	_, err = xlsx.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
	t.Log(err)
}
xurime's avatar
xurime 已提交
1011 1012 1013 1014 1015 1016 1017 1018 1019

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")
	}
}
1020 1021 1022 1023

func TestSharedStrings(t *testing.T) {
	xlsx, err := OpenFile("./test/SharedStrings.xlsx")
	if err != nil {
1024
		t.Error(err)
1025 1026 1027 1028
		return
	}
	xlsx.GetRows("Sheet1")
}