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

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

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

20
func TestOpenFile(t *testing.T) {
xurime's avatar
xurime 已提交
21
	// Test update a XLSX file.
22
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
23 24
	if !assert.NoError(t, err) {
		t.FailNow()
25
	}
V
Veniamin Albaev 已提交
26

27
	// Test get all the rows in a not exists worksheet.
28
	f.GetRows("Sheet4")
29
	// Test get all the rows in a worksheet.
30
	rows, err := f.GetRows("Sheet2")
31
	assert.NoError(t, err)
32 33 34 35 36 37
	for _, row := range rows {
		for _, cell := range row {
			t.Log(cell, "\t")
		}
		t.Log("\r\n")
	}
38
	f.UpdateLinkedValue()
39

40 41
	f.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(100.1588), 'f', -1, 32))
	f.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
42

43
	// Test set cell value with illegal row number.
44
	assert.EqualError(t, f.SetCellDefault("Sheet2", "A", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64)),
45
		`cannot convert cell "A" to coordinates: invalid cell name "A"`)
46

47
	f.SetCellInt("Sheet2", "A1", 100)
48

49
	// Test set cell integer value with illegal row number.
50
	assert.EqualError(t, f.SetCellInt("Sheet2", "A", 100), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
51

52
	f.SetCellStr("Sheet2", "C11", "Knowns")
53
	// Test max characters in a cell.
54 55
	f.SetCellStr("Sheet2", "D11", strings.Repeat("c", 32769))
	f.NewSheet(":\\/?*[]Maximum 31 characters allowed in sheet title.")
56
	// Test set worksheet name with illegal name.
57 58 59 60
	f.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")
	f.SetCellInt("Sheet3", "A23", 10)
	f.SetCellStr("Sheet3", "b230", "10")
	assert.EqualError(t, f.SetCellStr("Sheet10", "b230", "10"), "sheet Sheet10 is not exist")
61

62
	// Test set cell string value with illegal row number.
63
	assert.EqualError(t, f.SetCellStr("Sheet1", "A", "10"), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
64

65
	f.SetActiveSheet(2)
66
	// Test get cell formula with given rows number.
67
	_, err = f.GetCellFormula("Sheet1", "B19")
68
	assert.NoError(t, err)
69
	// Test get cell formula with illegal worksheet name.
70
	_, err = f.GetCellFormula("Sheet2", "B20")
71
	assert.NoError(t, err)
72
	_, err = f.GetCellFormula("Sheet1", "B20")
73
	assert.NoError(t, err)
74 75

	// Test get cell formula with illegal rows number.
76
	_, err = f.GetCellFormula("Sheet1", "B")
77
	assert.EqualError(t, err, `cannot convert cell "B" to coordinates: invalid cell name "B"`)
78
	// Test get shared cell formula
79 80
	f.GetCellFormula("Sheet2", "H11")
	f.GetCellFormula("Sheet2", "I11")
81
	getSharedForumula(&xlsxWorksheet{}, "")
82

xurime's avatar
xurime 已提交
83
	// Test read cell value with given illegal rows number.
84
	_, err = f.GetCellValue("Sheet2", "a-1")
85
	assert.EqualError(t, err, `cannot convert cell "A-1" to coordinates: invalid cell name "A-1"`)
86
	_, err = f.GetCellValue("Sheet2", "A")
87
	assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
88

xurime's avatar
xurime 已提交
89
	// Test read cell value with given lowercase column number.
90 91 92 93
	f.GetCellValue("Sheet2", "a5")
	f.GetCellValue("Sheet2", "C11")
	f.GetCellValue("Sheet2", "D11")
	f.GetCellValue("Sheet2", "D12")
xurime's avatar
xurime 已提交
94
	// Test SetCellValue function.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
	assert.NoError(t, f.SetCellValue("Sheet2", "F1", " Hello"))
	assert.NoError(t, f.SetCellValue("Sheet2", "G1", []byte("World")))
	assert.NoError(t, f.SetCellValue("Sheet2", "F2", 42))
	assert.NoError(t, f.SetCellValue("Sheet2", "F3", int8(1<<8/2-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F4", int16(1<<16/2-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F5", int32(1<<32/2-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F6", int64(1<<32/2-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F7", float32(42.65418)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F8", float64(-42.65418)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F9", float32(42)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F10", float64(42)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F11", uint(1<<32-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F12", uint8(1<<8-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F13", uint16(1<<16-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F14", uint32(1<<32-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F15", uint64(1<<32-1)))
	assert.NoError(t, f.SetCellValue("Sheet2", "F16", true))
	assert.NoError(t, f.SetCellValue("Sheet2", "F17", complex64(5+10i)))
xurime's avatar
xurime 已提交
113 114

	// Test on not exists worksheet.
115 116 117 118 119
	assert.EqualError(t, f.SetCellDefault("SheetN", "A1", ""), "sheet SheetN is not exist")
	assert.EqualError(t, f.SetCellFloat("SheetN", "A1", 42.65418, 2, 32), "sheet SheetN is not exist")
	assert.EqualError(t, f.SetCellBool("SheetN", "A1", true), "sheet SheetN is not exist")
	assert.EqualError(t, f.SetCellFormula("SheetN", "A1", ""), "sheet SheetN is not exist")
	assert.EqualError(t, f.SetCellHyperLink("SheetN", "A1", "Sheet1!A40", "Location"), "sheet SheetN is not exist")
120

121 122 123 124 125 126 127 128 129
	// Test boolean write
	booltest := []struct {
		value    bool
		expected string
	}{
		{false, "0"},
		{true, "1"},
	}
	for _, test := range booltest {
130 131
		f.SetCellValue("Sheet2", "F16", test.value)
		val, err := f.GetCellValue("Sheet2", "F16")
132 133
		assert.NoError(t, err)
		assert.Equal(t, test.expected, val)
134
	}
135

136
	f.SetCellValue("Sheet2", "G2", nil)
137

138
	assert.EqualError(t, f.SetCellValue("Sheet2", "G4", time.Now()), "only UTC time expected")
139

140
	f.SetCellValue("Sheet2", "G4", time.Now().UTC())
141
	// 02:46:40
142
	f.SetCellValue("Sheet2", "G5", time.Duration(1e13))
xurime's avatar
xurime 已提交
143
	// Test completion column.
144
	f.SetCellValue("Sheet2", "M2", nil)
xurime's avatar
xurime 已提交
145
	// Test read cell value with given axis large than exists row.
146
	f.GetCellValue("Sheet2", "E231")
147
	// Test get active worksheet of XLSX and get worksheet name of XLSX by given worksheet index.
148
	f.GetSheetName(f.GetActiveSheetIndex())
149
	// Test get worksheet index of XLSX by given worksheet name.
150
	f.GetSheetIndex("Sheet1")
151
	// Test get worksheet name of XLSX by given invalid worksheet index.
152 153 154
	f.GetSheetName(4)
	// Test get worksheet map of f.
	f.GetSheetMap()
155
	for i := 1; i <= 300; i++ {
156
		f.SetCellStr("Sheet3", "c"+strconv.Itoa(i), strconv.Itoa(i))
157
	}
158
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestOpenFile.xlsx")))
V
Veniamin Albaev 已提交
159 160
}

xurime's avatar
xurime 已提交
161
func TestSaveFile(t *testing.T) {
162
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
xurime's avatar
xurime 已提交
163 164 165
	if !assert.NoError(t, err) {
		t.FailNow()
	}
166 167
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSaveFile.xlsx")))
	f, err = OpenFile(filepath.Join("test", "TestSaveFile.xlsx"))
xurime's avatar
xurime 已提交
168 169 170
	if !assert.NoError(t, err) {
		t.FailNow()
	}
171
	assert.NoError(t, f.Save())
xurime's avatar
xurime 已提交
172 173
}

V
Veniamin Albaev 已提交
174
func TestSaveAsWrongPath(t *testing.T) {
175
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
176 177
	if assert.NoError(t, err) {
		// Test write file to not exist directory.
178
		err = f.SaveAs("")
V
Veniamin Albaev 已提交
179 180 181
		if assert.Error(t, err) {
			assert.True(t, os.IsNotExist(err), "Error: %v: Expected os.IsNotExists(err) == true", err)
		}
xurime's avatar
xurime 已提交
182
	}
183 184
}

185
func TestBrokenFile(t *testing.T) {
xurime's avatar
xurime 已提交
186
	// Test write file with broken file struct.
187
	f := File{}
xurime's avatar
xurime 已提交
188

V
Veniamin Albaev 已提交
189
	t.Run("SaveWithoutName", func(t *testing.T) {
190
		assert.EqualError(t, f.Save(), "no path defined for file, consider File.WriteTo or File.Write")
V
Veniamin Albaev 已提交
191
	})
192

V
Veniamin Albaev 已提交
193 194
	t.Run("SaveAsEmptyStruct", func(t *testing.T) {
		// Test write file with broken file struct with given path.
195
		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestBrokenFile.SaveAsEmptyStruct.xlsx")))
V
Veniamin Albaev 已提交
196 197 198 199
	})

	t.Run("OpenBadWorkbook", func(t *testing.T) {
		// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
200
		f3, err := OpenFile(filepath.Join("test", "BadWorkbook.xlsx"))
V
Veniamin Albaev 已提交
201 202 203 204 205 206 207
		f3.GetActiveSheetIndex()
		f3.SetActiveSheet(2)
		assert.NoError(t, err)
	})

	t.Run("OpenNotExistsFile", func(t *testing.T) {
		// Test open a XLSX file with given illegal path.
208
		_, err := OpenFile(filepath.Join("test", "NotExistsFile.xlsx"))
V
Veniamin Albaev 已提交
209 210 211 212
		if assert.Error(t, err) {
			assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true")
		}
	})
213 214
}

215
func TestNewFile(t *testing.T) {
216
	// Test create a XLSX file.
217 218 219 220 221 222 223
	f := NewFile()
	f.NewSheet("Sheet1")
	f.NewSheet("XLSXSheet2")
	f.NewSheet("XLSXSheet3")
	f.SetCellInt("XLSXSheet2", "A23", 56)
	f.SetCellStr("Sheet1", "B20", "42")
	f.SetActiveSheet(0)
V
Veniamin Albaev 已提交
224

225
	// Test add picture to sheet with scaling and positioning.
226
	err := f.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
227
		`{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
V
Veniamin Albaev 已提交
228 229
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
230
	}
V
Veniamin Albaev 已提交
231

232
	// Test add picture to worksheet without formatset.
233
	err = f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), "")
V
Veniamin Albaev 已提交
234 235
	if !assert.NoError(t, err) {
		t.FailNow()
236
	}
V
Veniamin Albaev 已提交
237

238
	// Test add picture to worksheet with invalid formatset.
239
	err = f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), `{`)
V
Veniamin Albaev 已提交
240 241
	if !assert.Error(t, err) {
		t.FailNow()
242
	}
V
Veniamin Albaev 已提交
243

244
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestNewFile.xlsx")))
xurime's avatar
xurime 已提交
245
}
246

247
func TestColWidth(t *testing.T) {
248
	xlsx := NewFile()
249 250 251 252
	xlsx.SetColWidth("Sheet1", "B", "A", 12)
	xlsx.SetColWidth("Sheet1", "A", "B", 12)
	xlsx.GetColWidth("Sheet1", "A")
	xlsx.GetColWidth("Sheet1", "C")
253 254 255 256 257 258 259

	// Test set and get column width with illegal cell coordinates.
	_, err := xlsx.GetColWidth("Sheet1", "*")
	assert.EqualError(t, err, `invalid column name "*"`)
	assert.EqualError(t, xlsx.SetColWidth("Sheet1", "*", "B", 1), `invalid column name "*"`)
	assert.EqualError(t, xlsx.SetColWidth("Sheet1", "A", "*", 1), `invalid column name "*"`)

xurime's avatar
xurime 已提交
260 261 262 263
	// Test get column width on not exists worksheet.
	_, err = xlsx.GetColWidth("SheetN", "A")
	assert.EqualError(t, err, "sheet SheetN is not exist")

264
	err = xlsx.SaveAs(filepath.Join("test", "TestColWidth.xlsx"))
265
	if err != nil {
266
		t.Error(err)
267
	}
268 269 270
	convertRowHeightToPixels(0)
}

271 272 273 274 275 276
func TestAddDrawingVML(t *testing.T) {
	// Test addDrawingVML with illegal cell coordinates.
	f := NewFile()
	assert.EqualError(t, f.addDrawingVML(0, "", "*", 0, 0), `cannot convert cell "*" to coordinates: invalid cell name "*"`)
}

277
func TestSetCellHyperLink(t *testing.T) {
278
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
279 280 281 282
	if err != nil {
		t.Log(err)
	}
	// Test set cell hyperlink in a work sheet already have hyperlinks.
283
	assert.NoError(t, f.SetCellHyperLink("Sheet1", "B19", "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
284
	// Test add first hyperlink in a work sheet.
285
	assert.NoError(t, f.SetCellHyperLink("Sheet2", "C1", "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
286
	// Test add Location hyperlink in a work sheet.
287
	assert.NoError(t, f.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location"))
288

289
	assert.EqualError(t, f.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", ""), `invalid link type ""`)
290

291
	assert.EqualError(t, f.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location"), `invalid cell name ""`)
292

293 294 295 296 297 298 299 300 301
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellHyperLink.xlsx")))

	file := NewFile()
	for row := 1; row <= 65530; row++ {
		cell, err := CoordinatesToCellName(1, row)
		assert.NoError(t, err)
		assert.NoError(t, file.SetCellHyperLink("Sheet1", cell, "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
	}
	assert.EqualError(t, file.SetCellHyperLink("Sheet1", "A65531", "https://github.com/360EntSecGroup-Skylar/excelize", "External"), "over maximum limit hyperlinks in a worksheet")
302 303
}

304
func TestGetCellHyperLink(t *testing.T) {
305
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
306 307
	if !assert.NoError(t, err) {
		t.FailNow()
308
	}
V
Veniamin Albaev 已提交
309

310
	_, _, err = f.GetCellHyperLink("Sheet1", "")
311
	assert.EqualError(t, err, `invalid cell name ""`)
312

313
	link, target, err := f.GetCellHyperLink("Sheet1", "A22")
314
	assert.NoError(t, err)
315
	t.Log(link, target)
316
	link, target, err = f.GetCellHyperLink("Sheet2", "D6")
317
	assert.NoError(t, err)
318
	t.Log(link, target)
319
	link, target, err = f.GetCellHyperLink("Sheet3", "H3")
xurime's avatar
xurime 已提交
320
	assert.EqualError(t, err, "sheet Sheet3 is not exist")
321 322 323
	t.Log(link, target)
}

324
func TestSetCellFormula(t *testing.T) {
325
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
326 327
	if !assert.NoError(t, err) {
		t.FailNow()
328
	}
V
Veniamin Albaev 已提交
329

330 331
	f.SetCellFormula("Sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)")
	f.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)")
332

333
	// Test set cell formula with illegal rows number.
334
	assert.EqualError(t, f.SetCellFormula("Sheet1", "C", "SUM(Sheet2!D2,Sheet2!D9)"), `cannot convert cell "C" to coordinates: invalid cell name "C"`)
335

336
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellFormula1.xlsx")))
V
Veniamin Albaev 已提交
337

338
	f, err = OpenFile(filepath.Join("test", "CalcChain.xlsx"))
339 340 341 342
	if !assert.NoError(t, err) {
		t.FailNow()
	}
	// Test remove cell formula.
343 344
	f.SetCellFormula("Sheet1", "A1", "")
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellFormula2.xlsx")))
345
	// Test remove all cell formula.
346 347
	f.SetCellFormula("Sheet1", "B1", "")
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellFormula3.xlsx")))
348
}
349 350

func TestSetSheetBackground(t *testing.T) {
351
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
352 353
	if !assert.NoError(t, err) {
		t.FailNow()
354
	}
V
Veniamin Albaev 已提交
355

356
	err = f.SetSheetBackground("Sheet2", filepath.Join("test", "images", "background.jpg"))
V
Veniamin Albaev 已提交
357 358
	if !assert.NoError(t, err) {
		t.FailNow()
359
	}
V
Veniamin Albaev 已提交
360

361
	err = f.SetSheetBackground("Sheet2", filepath.Join("test", "images", "background.jpg"))
V
Veniamin Albaev 已提交
362 363
	if !assert.NoError(t, err) {
		t.FailNow()
364
	}
V
Veniamin Albaev 已提交
365

366
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetSheetBackground.xlsx")))
V
Veniamin Albaev 已提交
367 368 369
}

func TestSetSheetBackgroundErrors(t *testing.T) {
370
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
371 372
	if !assert.NoError(t, err) {
		t.FailNow()
373
	}
V
Veniamin Albaev 已提交
374

375
	err = f.SetSheetBackground("Sheet2", filepath.Join("test", "not_exists", "not_exists.png"))
V
Veniamin Albaev 已提交
376 377 378 379
	if assert.Error(t, err) {
		assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true")
	}

380
	err = f.SetSheetBackground("Sheet2", filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
381
	assert.EqualError(t, err, "unsupported image extension")
382
}
xurime's avatar
xurime 已提交
383

384
func TestMergeCell(t *testing.T) {
385
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
386 387
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
388
	}
V
Veniamin Albaev 已提交
389

390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
	f.MergeCell("Sheet1", "D9", "D9")
	f.MergeCell("Sheet1", "D9", "E9")
	f.MergeCell("Sheet1", "H14", "G13")
	f.MergeCell("Sheet1", "C9", "D8")
	f.MergeCell("Sheet1", "F11", "G13")
	f.MergeCell("Sheet1", "H7", "B15")
	f.MergeCell("Sheet1", "D11", "F13")
	f.MergeCell("Sheet1", "G10", "K12")
	f.SetCellValue("Sheet1", "G11", "set value in merged cell")
	f.SetCellInt("Sheet1", "H11", 100)
	f.SetCellValue("Sheet1", "I11", float64(0.5))
	f.SetCellHyperLink("Sheet1", "J11", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
	f.SetCellFormula("Sheet1", "G12", "SUM(Sheet1!B19,Sheet1!C19)")
	f.GetCellValue("Sheet1", "H11")
	f.GetCellValue("Sheet2", "A6") // Merged cell ref is single coordinate.
	f.GetCellFormula("Sheet1", "G12")
V
Veniamin Albaev 已提交
406

407
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestMergeCell.xlsx")))
xurime's avatar
xurime 已提交
408
}
N
Nikolas Silva 已提交
409

410
func TestSetCellStyleAlignment(t *testing.T) {
411
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
412 413
	if !assert.NoError(t, err) {
		t.FailNow()
414
	}
V
Veniamin Albaev 已提交
415

416
	var style int
417
	style, err = f.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}}`)
V
Veniamin Albaev 已提交
418 419
	if !assert.NoError(t, err) {
		t.FailNow()
420
	}
V
Veniamin Albaev 已提交
421

422
	assert.NoError(t, f.SetCellStyle("Sheet1", "A22", "A22", style))
423

424
	// Test set cell style with given illegal rows number.
425 426
	assert.EqualError(t, f.SetCellStyle("Sheet1", "A", "A22", style), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
	assert.EqualError(t, f.SetCellStyle("Sheet1", "A22", "A", style), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
427

428
	// Test get cell style with given illegal rows number.
429
	index, err := f.GetCellStyle("Sheet1", "A")
430 431
	assert.Equal(t, 0, index)
	assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
V
Veniamin Albaev 已提交
432

433
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleAlignment.xlsx")))
434 435 436
}

func TestSetCellStyleBorder(t *testing.T) {
437
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
438 439
	if !assert.NoError(t, err) {
		t.FailNow()
440
	}
441

V
Veniamin Albaev 已提交
442
	var style int
443

444
	// Test set border on overlapping area with vertical variants shading styles gradient fill.
445
	style, err = f.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}]}`)
V
Veniamin Albaev 已提交
446 447
	if !assert.NoError(t, err) {
		t.FailNow()
448
	}
449
	assert.NoError(t, f.SetCellStyle("Sheet1", "J21", "L25", style))
450

451
	style, err = f.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}}`)
V
Veniamin Albaev 已提交
452 453
	if !assert.NoError(t, err) {
		t.FailNow()
454
	}
455
	assert.NoError(t, f.SetCellStyle("Sheet1", "M28", "K24", style))
456

457
	style, err = f.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}}`)
V
Veniamin Albaev 已提交
458 459
	if !assert.NoError(t, err) {
		t.FailNow()
460
	}
461
	assert.NoError(t, f.SetCellStyle("Sheet1", "M28", "K24", style))
462

463
	// Test set border and solid style pattern fill for a single cell.
464
	style, err = f.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}}`)
V
Veniamin Albaev 已提交
465 466
	if !assert.NoError(t, err) {
		t.FailNow()
467
	}
468

469
	assert.NoError(t, f.SetCellStyle("Sheet1", "O22", "O22", style))
V
Veniamin Albaev 已提交
470

471
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleBorder.xlsx")))
V
Veniamin Albaev 已提交
472 473 474
}

func TestSetCellStyleBorderErrors(t *testing.T) {
475
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
476 477 478 479 480
	if !assert.NoError(t, err) {
		t.FailNow()
	}

	// Set border with invalid style parameter.
481
	_, err = f.NewStyle("")
V
Veniamin Albaev 已提交
482 483 484 485 486
	if !assert.EqualError(t, err, "unexpected end of JSON input") {
		t.FailNow()
	}

	// Set border with invalid style index number.
487
	_, err = f.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}]}`)
V
Veniamin Albaev 已提交
488 489
	if !assert.NoError(t, err) {
		t.FailNow()
490 491 492
	}
}

493
func TestSetCellStyleNumberFormat(t *testing.T) {
494
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
495 496
	if !assert.NoError(t, err) {
		t.FailNow()
497
	}
V
Veniamin Albaev 已提交
498

xurime's avatar
xurime 已提交
499
	// Test only set fill and number format for a cell.
500 501 502 503 504 505 506 507 508
	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 {
509
				f.SetCellValue("Sheet2", c, v)
510
			} else {
511
				f.SetCellValue("Sheet2", c, val)
512
			}
513
			style, err := f.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":5},"number_format": ` + strconv.Itoa(d) + `}`)
V
Veniamin Albaev 已提交
514 515
			if !assert.NoError(t, err) {
				t.FailNow()
516
			}
517 518
			assert.NoError(t, f.SetCellStyle("Sheet2", c, c, style))
			t.Log(f.GetCellValue("Sheet2", c))
519 520
		}
	}
521
	var style int
522
	style, err = f.NewStyle(`{"number_format":-1}`)
V
Veniamin Albaev 已提交
523 524
	if !assert.NoError(t, err) {
		t.FailNow()
525
	}
526
	assert.NoError(t, f.SetCellStyle("Sheet2", "L33", "L33", style))
V
Veniamin Albaev 已提交
527

528
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleNumberFormat.xlsx")))
529 530
}

531
func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
V
Veniamin Albaev 已提交
532
	t.Run("TestBook3", func(t *testing.T) {
533
		f, err := prepareTestBook3()
V
Veniamin Albaev 已提交
534 535 536
		if !assert.NoError(t, err) {
			t.FailNow()
		}
537

538 539
		f.SetCellValue("Sheet1", "A1", 56)
		f.SetCellValue("Sheet1", "A2", -32.3)
V
Veniamin Albaev 已提交
540
		var style int
541
		style, err = f.NewStyle(`{"number_format": 188, "decimal_places": -1}`)
V
Veniamin Albaev 已提交
542 543 544
		if !assert.NoError(t, err) {
			t.FailNow()
		}
545

546 547
		assert.NoError(t, f.SetCellStyle("Sheet1", "A1", "A1", style))
		style, err = f.NewStyle(`{"number_format": 188, "decimal_places": 31, "negred": true}`)
V
Veniamin Albaev 已提交
548 549 550
		if !assert.NoError(t, err) {
			t.FailNow()
		}
551

552
		assert.NoError(t, f.SetCellStyle("Sheet1", "A2", "A2", style))
553

554
		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleCurrencyNumberFormat.TestBook3.xlsx")))
V
Veniamin Albaev 已提交
555
	})
556

V
Veniamin Albaev 已提交
557
	t.Run("TestBook4", func(t *testing.T) {
558
		f, err := prepareTestBook4()
V
Veniamin Albaev 已提交
559 560 561
		if !assert.NoError(t, err) {
			t.FailNow()
		}
562 563
		f.SetCellValue("Sheet1", "A1", 42920.5)
		f.SetCellValue("Sheet1", "A2", 42920.5)
V
Veniamin Albaev 已提交
564

565
		_, err = f.NewStyle(`{"number_format": 26, "lang": "zh-tw"}`)
V
Veniamin Albaev 已提交
566 567 568 569
		if !assert.NoError(t, err) {
			t.FailNow()
		}

570
		style, err := f.NewStyle(`{"number_format": 27}`)
V
Veniamin Albaev 已提交
571 572 573 574
		if !assert.NoError(t, err) {
			t.FailNow()
		}

575 576
		assert.NoError(t, f.SetCellStyle("Sheet1", "A1", "A1", style))
		style, err = f.NewStyle(`{"number_format": 31, "lang": "ko-kr"}`)
V
Veniamin Albaev 已提交
577 578 579 580
		if !assert.NoError(t, err) {
			t.FailNow()
		}

581
		assert.NoError(t, f.SetCellStyle("Sheet1", "A2", "A2", style))
V
Veniamin Albaev 已提交
582

583
		style, err = f.NewStyle(`{"number_format": 71, "lang": "th-th"}`)
V
Veniamin Albaev 已提交
584 585 586
		if !assert.NoError(t, err) {
			t.FailNow()
		}
587
		assert.NoError(t, f.SetCellStyle("Sheet1", "A2", "A2", style))
V
Veniamin Albaev 已提交
588

589
		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleCurrencyNumberFormat.TestBook4.xlsx")))
V
Veniamin Albaev 已提交
590
	})
591 592
}

593
func TestSetCellStyleCustomNumberFormat(t *testing.T) {
594 595 596 597
	f := NewFile()
	f.SetCellValue("Sheet1", "A1", 42920.5)
	f.SetCellValue("Sheet1", "A2", 42920.5)
	style, err := f.NewStyle(`{"custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"}`)
598 599 600
	if err != nil {
		t.Log(err)
	}
601 602
	assert.NoError(t, f.SetCellStyle("Sheet1", "A1", "A1", style))
	style, err = f.NewStyle(`{"custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"}`)
603 604 605
	if err != nil {
		t.Log(err)
	}
606
	assert.NoError(t, f.SetCellStyle("Sheet1", "A2", "A2", style))
V
Veniamin Albaev 已提交
607

608
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleCustomNumberFormat.xlsx")))
609 610
}

611
func TestSetCellStyleFill(t *testing.T) {
612
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
613 614
	if !assert.NoError(t, err) {
		t.FailNow()
615
	}
V
Veniamin Albaev 已提交
616

617
	var style int
618
	// Test set fill for cell with invalid parameter.
619
	style, err = f.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":6}}`)
V
Veniamin Albaev 已提交
620 621
	if !assert.NoError(t, err) {
		t.FailNow()
622
	}
623
	assert.NoError(t, f.SetCellStyle("Sheet1", "O23", "O23", style))
624

625
	style, err = f.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF"],"shading":1}}`)
V
Veniamin Albaev 已提交
626 627
	if !assert.NoError(t, err) {
		t.FailNow()
628
	}
629
	assert.NoError(t, f.SetCellStyle("Sheet1", "O23", "O23", style))
630

631
	style, err = f.NewStyle(`{"fill":{"type":"pattern","color":[],"pattern":1}}`)
V
Veniamin Albaev 已提交
632 633
	if !assert.NoError(t, err) {
		t.FailNow()
634
	}
635
	assert.NoError(t, f.SetCellStyle("Sheet1", "O23", "O23", style))
xurime's avatar
xurime 已提交
636

637
	style, err = f.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":19}}`)
V
Veniamin Albaev 已提交
638 639
	if !assert.NoError(t, err) {
		t.FailNow()
640
	}
641
	assert.NoError(t, f.SetCellStyle("Sheet1", "O23", "O23", style))
642

643
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleFill.xlsx")))
644 645 646
}

func TestSetCellStyleFont(t *testing.T) {
647
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
648 649
	if !assert.NoError(t, err) {
		t.FailNow()
650
	}
V
Veniamin Albaev 已提交
651

652
	var style int
653
	style, err = f.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}`)
V
Veniamin Albaev 已提交
654 655
	if !assert.NoError(t, err) {
		t.FailNow()
656
	}
V
Veniamin Albaev 已提交
657

658
	assert.NoError(t, f.SetCellStyle("Sheet2", "A1", "A1", style))
659

660
	style, err = f.NewStyle(`{"font":{"italic":true,"underline":"double"}}`)
V
Veniamin Albaev 已提交
661 662
	if !assert.NoError(t, err) {
		t.FailNow()
663
	}
V
Veniamin Albaev 已提交
664

665
	assert.NoError(t, f.SetCellStyle("Sheet2", "A2", "A2", style))
666

667
	style, err = f.NewStyle(`{"font":{"bold":true}}`)
V
Veniamin Albaev 已提交
668 669
	if !assert.NoError(t, err) {
		t.FailNow()
670
	}
V
Veniamin Albaev 已提交
671

672
	assert.NoError(t, f.SetCellStyle("Sheet2", "A3", "A3", style))
673

674
	style, err = f.NewStyle(`{"font":{"bold":true,"family":"","size":0,"color":"","underline":""}}`)
V
Veniamin Albaev 已提交
675 676
	if !assert.NoError(t, err) {
		t.FailNow()
677
	}
V
Veniamin Albaev 已提交
678

679
	assert.NoError(t, f.SetCellStyle("Sheet2", "A4", "A4", style))
680

681
	style, err = f.NewStyle(`{"font":{"color":"#777777"}}`)
V
Veniamin Albaev 已提交
682 683
	if !assert.NoError(t, err) {
		t.FailNow()
684
	}
V
Veniamin Albaev 已提交
685

686
	assert.NoError(t, f.SetCellStyle("Sheet2", "A5", "A5", style))
V
Veniamin Albaev 已提交
687

688
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetCellStyleFont.xlsx")))
689
}
690

691
func TestSetCellStyleProtection(t *testing.T) {
692
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
693 694
	if !assert.NoError(t, err) {
		t.FailNow()
695
	}
V
Veniamin Albaev 已提交
696

697
	var style int
698
	style, err = f.NewStyle(`{"protection":{"hidden":true, "locked":true}}`)
V
Veniamin Albaev 已提交
699 700
	if !assert.NoError(t, err) {
		t.FailNow()
701
	}
V
Veniamin Albaev 已提交
702

703 704
	assert.NoError(t, f.SetCellStyle("Sheet2", "A6", "A6", style))
	err = f.SaveAs(filepath.Join("test", "TestSetCellStyleProtection.xlsx"))
V
Veniamin Albaev 已提交
705 706
	if !assert.NoError(t, err) {
		t.FailNow()
707 708 709
	}
}

V
Veniamin Albaev 已提交
710 711
func TestSetDeleteSheet(t *testing.T) {
	t.Run("TestBook3", func(t *testing.T) {
712
		f, err := prepareTestBook3()
V
Veniamin Albaev 已提交
713 714 715 716
		if !assert.NoError(t, err) {
			t.FailNow()
		}

717 718
		f.DeleteSheet("XLSXSheet3")
		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook3.xlsx")))
V
Veniamin Albaev 已提交
719 720 721
	})

	t.Run("TestBook4", func(t *testing.T) {
722
		f, err := prepareTestBook4()
V
Veniamin Albaev 已提交
723 724 725
		if !assert.NoError(t, err) {
			t.FailNow()
		}
726 727 728 729
		f.DeleteSheet("Sheet1")
		f.AddComment("Sheet1", "A1", "")
		f.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook4.xlsx")))
V
Veniamin Albaev 已提交
730
	})
731
}
732

733
func TestSheetVisibility(t *testing.T) {
734
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
735 736
	if !assert.NoError(t, err) {
		t.FailNow()
737
	}
V
Veniamin Albaev 已提交
738

739 740 741 742
	f.SetSheetVisible("Sheet2", false)
	f.SetSheetVisible("Sheet1", false)
	f.SetSheetVisible("Sheet1", true)
	f.GetSheetVisible("Sheet1")
V
Veniamin Albaev 已提交
743

744
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSheetVisibility.xlsx")))
745 746
}

747
func TestColumnVisibility(t *testing.T) {
V
Veniamin Albaev 已提交
748
	t.Run("TestBook1", func(t *testing.T) {
749
		f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
750 751 752 753
		if !assert.NoError(t, err) {
			t.FailNow()
		}

754 755 756
		assert.NoError(t, f.SetColVisible("Sheet1", "F", false))
		assert.NoError(t, f.SetColVisible("Sheet1", "F", true))
		visible, err := f.GetColVisible("Sheet1", "F")
757 758 759
		assert.Equal(t, true, visible)
		assert.NoError(t, err)

xurime's avatar
xurime 已提交
760
		// Test get column visiable on not exists worksheet.
761
		_, err = f.GetColVisible("SheetN", "F")
xurime's avatar
xurime 已提交
762 763
		assert.EqualError(t, err, "sheet SheetN is not exist")

764
		// Test get column visiable with illegal cell coordinates.
765
		_, err = f.GetColVisible("Sheet1", "*")
766
		assert.EqualError(t, err, `invalid column name "*"`)
767
		assert.EqualError(t, f.SetColVisible("Sheet1", "*", false), `invalid column name "*"`)
768

769 770
		f.NewSheet("Sheet3")
		assert.NoError(t, f.SetColVisible("Sheet3", "E", false))
xurime's avatar
xurime 已提交
771

772 773
		assert.EqualError(t, f.SetColVisible("SheetN", "E", false), "sheet SheetN is not exist")
		assert.NoError(t, f.SaveAs(filepath.Join("test", "TestColumnVisibility.xlsx")))
V
Veniamin Albaev 已提交
774 775 776
	})

	t.Run("TestBook3", func(t *testing.T) {
777
		f, err := prepareTestBook3()
V
Veniamin Albaev 已提交
778 779 780
		if !assert.NoError(t, err) {
			t.FailNow()
		}
781
		f.GetColVisible("Sheet1", "B")
V
Veniamin Albaev 已提交
782
	})
783 784
}

785
func TestCopySheet(t *testing.T) {
786
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
787 788
	if !assert.NoError(t, err) {
		t.FailNow()
789
	}
V
Veniamin Albaev 已提交
790

791 792
	idx := f.NewSheet("CopySheet")
	assert.EqualError(t, f.CopySheet(1, idx), "sheet sheet1 is not exist")
V
Veniamin Albaev 已提交
793

794 795
	f.SetCellValue("Sheet4", "F1", "Hello")
	val, err := f.GetCellValue("Sheet1", "F1")
796 797
	assert.NoError(t, err)
	assert.NotEqual(t, "Hello", val)
V
Veniamin Albaev 已提交
798

799
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestCopySheet.xlsx")))
V
Veniamin Albaev 已提交
800 801 802
}

func TestCopySheetError(t *testing.T) {
803
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
804 805
	if !assert.NoError(t, err) {
		t.FailNow()
806
	}
V
Veniamin Albaev 已提交
807

808
	err = f.CopySheet(0, -1)
V
Veniamin Albaev 已提交
809 810
	if !assert.EqualError(t, err, "invalid worksheet index") {
		t.FailNow()
811
	}
V
Veniamin Albaev 已提交
812

813
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestCopySheetError.xlsx")))
814
}
815

xurime's avatar
xurime 已提交
816
func TestAddTable(t *testing.T) {
817
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
818 819
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
820
	}
V
Veniamin Albaev 已提交
821

822
	err = f.AddTable("Sheet1", "B26", "A21", `{}`)
V
Veniamin Albaev 已提交
823 824
	if !assert.NoError(t, err) {
		t.FailNow()
825
	}
V
Veniamin Albaev 已提交
826

827
	err = f.AddTable("Sheet2", "A2", "B5", `{"table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
V
Veniamin Albaev 已提交
828 829
	if !assert.NoError(t, err) {
		t.FailNow()
830
	}
V
Veniamin Albaev 已提交
831

832
	err = f.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
V
Veniamin Albaev 已提交
833 834
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
835
	}
V
Veniamin Albaev 已提交
836

837
	// Test add table with illegal formatset.
838
	assert.EqualError(t, f.AddTable("Sheet1", "B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
839
	// Test add table with illegal cell coordinates.
840 841
	assert.EqualError(t, f.AddTable("Sheet1", "A", "B1", `{}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
	assert.EqualError(t, f.AddTable("Sheet1", "A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
842

843
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddTable.xlsx")))
844 845

	// Test addTable with illegal cell coordinates.
846
	f = NewFile()
847 848
	assert.EqualError(t, f.addTable("sheet1", "", 0, 0, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
	assert.EqualError(t, f.addTable("sheet1", "", 1, 1, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
xurime's avatar
xurime 已提交
849 850
}

851
func TestAddShape(t *testing.T) {
852
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
853 854
	if !assert.NoError(t, err) {
		t.FailNow()
855
	}
V
Veniamin Albaev 已提交
856

857 858 859 860 861
	f.AddShape("Sheet1", "A30", `{"type":"rect","paragraph":[{"text":"Rectangle","font":{"color":"CD5C5C"}},{"text":"Shape","font":{"bold":true,"color":"2980B9"}}]}`)
	f.AddShape("Sheet1", "B30", `{"type":"rect","paragraph":[{"text":"Rectangle"},{}]}`)
	f.AddShape("Sheet1", "C30", `{"type":"rect","paragraph":[]}`)
	f.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}`)
	f.AddShape("Sheet3", "H1", "")
V
Veniamin Albaev 已提交
862

863
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape.xlsx")))
864 865
}

866
func TestAddComments(t *testing.T) {
867
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
868 869
	if !assert.NoError(t, err) {
		t.FailNow()
870
	}
V
Veniamin Albaev 已提交
871

xurime's avatar
xurime 已提交
872
	s := strings.Repeat("c", 32768)
873 874
	f.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
	f.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
R
Rad Cirskis 已提交
875

876 877
	if assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
		assert.Len(t, f.GetComments(), 2)
V
Veniamin Albaev 已提交
878
	}
879 880
}

881 882 883 884 885
func TestGetSheetComments(t *testing.T) {
	f := NewFile()
	assert.Equal(t, "", f.getSheetComments(0))
}

886
func TestAutoFilter(t *testing.T) {
887 888
	outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")

889
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
890 891
	if !assert.NoError(t, err) {
		t.FailNow()
892
	}
V
Veniamin Albaev 已提交
893 894 895

	formats := []string{
		``,
896 897 898 899 900 901 902
		`{"column":"B","expression":"x != blanks"}`,
		`{"column":"B","expression":"x == blanks"}`,
		`{"column":"B","expression":"x != nonblanks"}`,
		`{"column":"B","expression":"x == nonblanks"}`,
		`{"column":"B","expression":"x <= 1 and x >= 2"}`,
		`{"column":"B","expression":"x == 1 or x == 2"}`,
		`{"column":"B","expression":"x == 1 or x == 2*"}`,
V
Veniamin Albaev 已提交
903 904 905 906
	}

	for i, format := range formats {
		t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
907
			err = f.AutoFilter("Sheet1", "D4", "B1", format)
xurime's avatar
xurime 已提交
908
			assert.NoError(t, err)
909
			assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, i+1)))
V
Veniamin Albaev 已提交
910 911 912
		})
	}

913
	// testing AutoFilter with illegal cell coordinates.
914 915
	assert.EqualError(t, f.AutoFilter("Sheet1", "A", "B1", ""), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
	assert.EqualError(t, f.AutoFilter("Sheet1", "A1", "B", ""), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
V
Veniamin Albaev 已提交
916 917 918
}

func TestAutoFilterError(t *testing.T) {
919 920
	outFile := filepath.Join("test", "TestAutoFilterError%d.xlsx")

921
	f, err := prepareTestBook1()
V
Veniamin Albaev 已提交
922 923 924 925 926
	if !assert.NoError(t, err) {
		t.FailNow()
	}

	formats := []string{
927 928 929 930 931 932 933
		`{"column":"B","expression":"x <= 1 and x >= blanks"}`,
		`{"column":"B","expression":"x -- y or x == *2*"}`,
		`{"column":"B","expression":"x != y or x ? *2"}`,
		`{"column":"B","expression":"x -- y o r x == *2"}`,
		`{"column":"B","expression":"x -- y"}`,
		`{"column":"A","expression":"x -- y"}`,
	}
V
Veniamin Albaev 已提交
934 935
	for i, format := range formats {
		t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
936
			err = f.AutoFilter("Sheet3", "D4", "B1", format)
V
Veniamin Albaev 已提交
937
			if assert.Error(t, err) {
938
				assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, i+1)))
V
Veniamin Albaev 已提交
939 940
			}
		})
941 942 943
	}
}

944
func TestAddChart(t *testing.T) {
945
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
946 947
	if !assert.NoError(t, err) {
		t.FailNow()
948
	}
V
Veniamin Albaev 已提交
949

xurime's avatar
xurime 已提交
950 951 952
	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 {
953
		assert.NoError(t, f.SetCellValue("Sheet1", k, v))
xurime's avatar
xurime 已提交
954 955
	}
	for k, v := range values {
956
		assert.NoError(t, f.SetCellValue("Sheet1", k, v))
xurime's avatar
xurime 已提交
957
	}
958
	assert.EqualError(t, f.AddChart("Sheet1", "P1", ""), "unexpected end of JSON input")
xurime's avatar
xurime 已提交
959 960

	// Test add chart on not exists worksheet.
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
	assert.EqualError(t, f.AddChart("SheetN", "P1", "{}"), "sheet SheetN is not exist")

	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.AddChart("Sheet2", "P64", `{"type":"barPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Stacked 100% Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
	assert.NoError(t, f.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"}`))
	assert.NoError(t, f.AddChart("Sheet2", "P80", `{"type":"bar3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","y_axis":{"maximum":7.5,"minimum":0.5}}`))
	assert.NoError(t, f.AddChart("Sheet2", "X80", `{"type":"bar3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D 100% Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"reverse_order":true,"maximum":0,"minimum":0},"y_axis":{"reverse_order":true,"maximum":0,"minimum":0}}`))
982
	// area series charts
983 984 985 986 987 988 989 990
	assert.NoError(t, f.AddChart("Sheet2", "AF1", `{"type":"area","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
	assert.NoError(t, f.AddChart("Sheet2", "AN1", `{"type":"areaStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
	assert.NoError(t, f.AddChart("Sheet2", "AF16", `{"type":"areaPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D 100% Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
	assert.NoError(t, f.AddChart("Sheet2", "AN16", `{"type":"area3D","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
	assert.NoError(t, f.AddChart("Sheet2", "AF32", `{"type":"area3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
	assert.NoError(t, f.AddChart("Sheet2", "AN32", `{"type":"area3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D 100% Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))

	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddChart.xlsx")))
991 992 993
}

func TestInsertCol(t *testing.T) {
994 995
	f := NewFile()
	sheet1 := f.GetSheetName(1)
996

997
	fillCells(f, sheet1, 10, 10)
998

999 1000
	f.SetCellHyperLink(sheet1, "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
	f.MergeCell(sheet1, "A1", "C3")
1001

1002
	err := f.AutoFilter(sheet1, "A2", "B2", `{"column":"B","expression":"x != blanks"}`)
V
Veniamin Albaev 已提交
1003 1004
	if !assert.NoError(t, err) {
		t.FailNow()
1005
	}
V
Veniamin Albaev 已提交
1006

1007
	assert.NoError(t, f.InsertCol(sheet1, "A"))
V
Veniamin Albaev 已提交
1008

1009
	// Test insert column with illegal cell coordinates.
1010
	assert.EqualError(t, f.InsertCol("Sheet1", "*"), `invalid column name "*"`)
1011

1012
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertCol.xlsx")))
1013 1014 1015
}

func TestRemoveCol(t *testing.T) {
1016 1017
	f := NewFile()
	sheet1 := f.GetSheetName(1)
1018

1019
	fillCells(f, sheet1, 10, 15)
1020

1021 1022
	f.SetCellHyperLink(sheet1, "A5", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
	f.SetCellHyperLink(sheet1, "C5", "https://github.com", "External")
1023

1024 1025
	f.MergeCell(sheet1, "A1", "B1")
	f.MergeCell(sheet1, "A2", "B2")
1026

1027 1028
	assert.NoError(t, f.RemoveCol(sheet1, "A"))
	assert.NoError(t, f.RemoveCol(sheet1, "A"))
V
Veniamin Albaev 已提交
1029

1030
	// Test remove column with illegal cell coordinates.
1031
	assert.EqualError(t, f.RemoveCol("Sheet1", "*"), `invalid column name "*"`)
1032

xurime's avatar
xurime 已提交
1033
	// Test remove column on not exists worksheet.
1034
	assert.EqualError(t, f.RemoveCol("SheetN", "B"), "sheet SheetN is not exist")
xurime's avatar
xurime 已提交
1035

1036
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestRemoveCol.xlsx")))
1037 1038
}

xurime's avatar
xurime 已提交
1039
func TestSetPane(t *testing.T) {
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
	f := NewFile()
	f.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
	f.NewSheet("Panes 2")
	f.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"}]}`)
	f.NewSheet("Panes 3")
	f.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"}]}`)
	f.NewSheet("Panes 4")
	f.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"}]}`)
	f.SetPanes("Panes 4", "")

	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
xurime's avatar
xurime 已提交
1051 1052
}

1053
func TestConditionalFormat(t *testing.T) {
1054 1055
	f := NewFile()
	sheet1 := f.GetSheetName(1)
1056

1057
	fillCells(f, sheet1, 10, 15)
1058

1059 1060 1061
	var format1, format2, format3 int
	var err error
	// Rose format for bad conditional.
1062
	format1, err = f.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1063 1064 1065 1066
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1067
	// Light yellow format for neutral conditional.
1068
	format2, err = f.NewConditionalStyle(`{"fill":{"type":"pattern","color":["#FEEAA0"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1069 1070 1071 1072
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1073
	// Light green format for good conditional.
1074
	format3, err = f.NewConditionalStyle(`{"font":{"color":"#09600B"},"fill":{"type":"pattern","color":["#C7EECF"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1075 1076 1077 1078
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1079
	// Color scales: 2 color.
1080
	f.SetConditionalFormat(sheet1, "A1:A10", `[{"type":"2_color_scale","criteria":"=","min_type":"min","max_type":"max","min_color":"#F8696B","max_color":"#63BE7B"}]`)
1081
	// Color scales: 3 color.
1082
	f.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"}]`)
1083
	// Hightlight cells rules: between...
1084
	f.SetConditionalFormat(sheet1, "C1:C10", fmt.Sprintf(`[{"type":"cell","criteria":"between","format":%d,"minimum":"6","maximum":"8"}]`, format1))
1085
	// Hightlight cells rules: Greater Than...
1086
	f.SetConditionalFormat(sheet1, "D1:D10", fmt.Sprintf(`[{"type":"cell","criteria":">","format":%d,"value":"6"}]`, format3))
1087
	// Hightlight cells rules: Equal To...
1088
	f.SetConditionalFormat(sheet1, "E1:E10", fmt.Sprintf(`[{"type":"top","criteria":"=","format":%d}]`, format3))
1089
	// Hightlight cells rules: Not Equal To...
1090
	f.SetConditionalFormat(sheet1, "F1:F10", fmt.Sprintf(`[{"type":"unique","criteria":"=","format":%d}]`, format2))
1091
	// Hightlight cells rules: Duplicate Values...
1092
	f.SetConditionalFormat(sheet1, "G1:G10", fmt.Sprintf(`[{"type":"duplicate","criteria":"=","format":%d}]`, format2))
1093
	// Top/Bottom rules: Top 10%.
1094
	f.SetConditionalFormat(sheet1, "H1:H10", fmt.Sprintf(`[{"type":"top","criteria":"=","format":%d,"value":"6","percent":true}]`, format1))
1095
	// Top/Bottom rules: Above Average...
1096
	f.SetConditionalFormat(sheet1, "I1:I10", fmt.Sprintf(`[{"type":"average","criteria":"=","format":%d, "above_average": true}]`, format3))
1097
	// Top/Bottom rules: Below Average...
1098
	f.SetConditionalFormat(sheet1, "J1:J10", fmt.Sprintf(`[{"type":"average","criteria":"=","format":%d, "above_average": false}]`, format1))
1099
	// Data Bars: Gradient Fill.
1100
	f.SetConditionalFormat(sheet1, "K1:K10", `[{"type":"data_bar", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
1101
	// Use a formula to determine which cells to format.
1102
	f.SetConditionalFormat(sheet1, "L1:L10", fmt.Sprintf(`[{"type":"formula", "criteria":"L2<3", "format":%d}]`, format1))
1103
	// Test set invalid format set in conditional format
1104
	f.SetConditionalFormat(sheet1, "L1:L10", "")
V
Veniamin Albaev 已提交
1105

1106
	err = f.SaveAs(filepath.Join("test", "TestConditionalFormat.xlsx"))
V
Veniamin Albaev 已提交
1107 1108
	if !assert.NoError(t, err) {
		t.FailNow()
1109 1110 1111
	}

	// Set conditional format with illegal valid type.
1112
	f.SetConditionalFormat(sheet1, "K1:K10", `[{"type":"", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
1113
	// Set conditional format with illegal criteria type.
1114
	f.SetConditionalFormat(sheet1, "K1:K10", `[{"type":"data_bar", "criteria":"", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
V
Veniamin Albaev 已提交
1115 1116

	// Set conditional format with file without dxfs element shold not return error.
1117
	f, err = OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1118 1119 1120 1121
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1122
	_, err = f.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1123 1124 1125
	if !assert.NoError(t, err) {
		t.FailNow()
	}
1126
}
xurime's avatar
xurime 已提交
1127

V
Veniamin Albaev 已提交
1128
func TestConditionalFormatError(t *testing.T) {
1129 1130
	f := NewFile()
	sheet1 := f.GetSheetName(1)
1131

1132
	fillCells(f, sheet1, 10, 15)
V
Veniamin Albaev 已提交
1133 1134

	// Set conditional format with illegal JSON string should return error
1135
	_, err := f.NewConditionalStyle("")
V
Veniamin Albaev 已提交
1136 1137
	if !assert.EqualError(t, err, "unexpected end of JSON input") {
		t.FailNow()
xurime's avatar
xurime 已提交
1138 1139
	}
}
1140 1141

func TestSharedStrings(t *testing.T) {
1142
	f, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
V
Veniamin Albaev 已提交
1143 1144
	if !assert.NoError(t, err) {
		t.FailNow()
1145
	}
1146
	f.GetRows("Sheet1")
1147
}
1148 1149

func TestSetSheetRow(t *testing.T) {
1150
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1151 1152
	if !assert.NoError(t, err) {
		t.FailNow()
1153
	}
V
Veniamin Albaev 已提交
1154

1155
	f.SetSheetRow("Sheet1", "B27", &[]interface{}{"cell", nil, int32(42), float64(42), time.Now().UTC()})
1156

1157
	assert.EqualError(t, f.SetSheetRow("Sheet1", "", &[]interface{}{"cell", nil, 2}),
1158
		`cannot convert cell "" to coordinates: invalid cell name ""`)
V
Veniamin Albaev 已提交
1159

1160 1161 1162
	assert.EqualError(t, f.SetSheetRow("Sheet1", "B27", []interface{}{}), `pointer to slice expected`)
	assert.EqualError(t, f.SetSheetRow("Sheet1", "B27", &f), `pointer to slice expected`)
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetSheetRow.xlsx")))
1163
}
1164

1165
func TestOutlineLevel(t *testing.T) {
1166 1167 1168 1169 1170 1171 1172 1173
	f := NewFile()
	f.NewSheet("Sheet2")
	f.SetColOutlineLevel("Sheet1", "D", 4)
	f.GetColOutlineLevel("Sheet1", "D")
	f.GetColOutlineLevel("Shee2", "A")
	f.SetColWidth("Sheet2", "A", "D", 13)
	f.SetColOutlineLevel("Sheet2", "B", 2)
	f.SetRowOutlineLevel("Sheet1", 2, 250)
1174

1175
	// Test set and get column outline level with illegal cell coordinates.
1176 1177
	assert.EqualError(t, f.SetColOutlineLevel("Sheet1", "*", 1), `invalid column name "*"`)
	_, err := f.GetColOutlineLevel("Sheet1", "*")
1178 1179
	assert.EqualError(t, err, `invalid column name "*"`)

xurime's avatar
xurime 已提交
1180
	// Test set column outline level on not exists worksheet.
1181
	assert.EqualError(t, f.SetColOutlineLevel("SheetN", "E", 2), "sheet SheetN is not exist")
xurime's avatar
xurime 已提交
1182

1183 1184
	assert.EqualError(t, f.SetRowOutlineLevel("Sheet1", 0, 1), "invalid row number 0")
	level, err := f.GetRowOutlineLevel("Sheet1", 2)
1185 1186
	assert.NoError(t, err)
	assert.Equal(t, uint8(250), level)
1187

1188
	_, err = f.GetRowOutlineLevel("Sheet1", 0)
1189
	assert.EqualError(t, err, `invalid row number 0`)
1190

1191
	level, err = f.GetRowOutlineLevel("Sheet1", 10)
1192 1193 1194
	assert.NoError(t, err)
	assert.Equal(t, uint8(0), level)

1195
	err = f.SaveAs(filepath.Join("test", "TestOutlineLevel.xlsx"))
V
Veniamin Albaev 已提交
1196 1197
	if !assert.NoError(t, err) {
		t.FailNow()
1198
	}
V
Veniamin Albaev 已提交
1199

1200
	f, err = OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1201 1202
	if !assert.NoError(t, err) {
		t.FailNow()
1203
	}
1204
	f.SetColOutlineLevel("Sheet2", "B", 2)
1205 1206
}

xurime's avatar
xurime 已提交
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
func TestThemeColor(t *testing.T) {
	t.Log(ThemeColor("000000", -0.1))
	t.Log(ThemeColor("000000", 0))
	t.Log(ThemeColor("000000", 1))
}

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

1232
func TestSearchSheet(t *testing.T) {
1233
	f, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
V
Veniamin Albaev 已提交
1234 1235
	if !assert.NoError(t, err) {
		t.FailNow()
1236
	}
V
Veniamin Albaev 已提交
1237

1238
	// Test search in a not exists worksheet.
1239
	t.Log(f.SearchSheet("Sheet4", ""))
1240
	// Test search a not exists value.
1241 1242
	t.Log(f.SearchSheet("Sheet1", "X"))
	t.Log(f.SearchSheet("Sheet1", "A"))
1243 1244
	// Test search the coordinates where the numerical value in the range of
	// "0-9" of Sheet1 is described by regular expression:
1245
	t.Log(f.SearchSheet("Sheet1", "[0-9]", true))
R
r-uchino 已提交
1246 1247
}

1248
func TestProtectSheet(t *testing.T) {
1249 1250 1251
	f := NewFile()
	f.ProtectSheet("Sheet1", nil)
	f.ProtectSheet("Sheet1", &FormatSheetProtection{
1252 1253 1254
		Password:      "password",
		EditScenarios: false,
	})
V
Veniamin Albaev 已提交
1255

1256
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestProtectSheet.xlsx")))
xurime's avatar
xurime 已提交
1257
	// Test protect not exists worksheet.
1258
	assert.EqualError(t, f.ProtectSheet("SheetN", nil), "sheet SheetN is not exist")
1259 1260
}

1261
func TestUnprotectSheet(t *testing.T) {
1262
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1263 1264
	if !assert.NoError(t, err) {
		t.FailNow()
1265
	}
xurime's avatar
xurime 已提交
1266
	// Test unprotect not exists worksheet.
1267
	assert.EqualError(t, f.UnprotectSheet("SheetN"), "sheet SheetN is not exist")
V
Veniamin Albaev 已提交
1268

1269 1270
	f.UnprotectSheet("Sheet1")
	assert.NoError(t, f.SaveAs(filepath.Join("test", "TestUnprotectSheet.xlsx")))
1271
}
xurime's avatar
xurime 已提交
1272 1273 1274 1275 1276 1277

func TestSetDefaultTimeStyle(t *testing.T) {
	f := NewFile()
	// Test set default time style on not exists worksheet.
	assert.EqualError(t, f.setDefaultTimeStyle("SheetN", "", 0), "sheet SheetN is not exist")
}
1278

V
Veniamin Albaev 已提交
1279
func prepareTestBook1() (*File, error) {
1280
	f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1281 1282 1283 1284
	if err != nil {
		return nil, err
	}

1285
	err = f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
V
Veniamin Albaev 已提交
1286 1287 1288 1289 1290 1291
		`{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
	if err != nil {
		return nil, err
	}

	// Test add picture to worksheet with offset, external hyperlink and positioning.
1292
	err = f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.png"),
V
Veniamin Albaev 已提交
1293 1294 1295 1296 1297
		`{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
	if err != nil {
		return nil, err
	}

1298
	file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.jpg"))
V
Veniamin Albaev 已提交
1299 1300 1301 1302
	if err != nil {
		return nil, err
	}

1303
	err = f.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".jpg", file)
V
Veniamin Albaev 已提交
1304 1305 1306 1307
	if err != nil {
		return nil, err
	}

1308
	return f, nil
V
Veniamin Albaev 已提交
1309 1310 1311
}

func prepareTestBook3() (*File, error) {
1312 1313 1314 1315 1316 1317 1318 1319 1320
	f := NewFile()
	f.NewSheet("Sheet1")
	f.NewSheet("XLSXSheet2")
	f.NewSheet("XLSXSheet3")
	f.SetCellInt("XLSXSheet2", "A23", 56)
	f.SetCellStr("Sheet1", "B20", "42")
	f.SetActiveSheet(0)

	err := f.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
1321
		`{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
V
Veniamin Albaev 已提交
1322 1323 1324 1325
	if err != nil {
		return nil, err
	}

1326
	err = f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), "")
V
Veniamin Albaev 已提交
1327 1328 1329 1330
	if err != nil {
		return nil, err
	}

1331
	return f, nil
V
Veniamin Albaev 已提交
1332 1333 1334
}

func prepareTestBook4() (*File, error) {
1335 1336 1337 1338 1339
	f := NewFile()
	f.SetColWidth("Sheet1", "B", "A", 12)
	f.SetColWidth("Sheet1", "A", "B", 12)
	f.GetColWidth("Sheet1", "A")
	f.GetColWidth("Sheet1", "C")
V
Veniamin Albaev 已提交
1340

1341
	return f, nil
V
Veniamin Albaev 已提交
1342
}
1343

1344
func fillCells(f *File, sheet string, colCount, rowCount int) {
1345 1346
	for col := 1; col <= colCount; col++ {
		for row := 1; row <= rowCount; row++ {
1347
			cell, _ := CoordinatesToCellName(col, row)
1348
			f.SetCellStr(sheet, cell, cell)
1349 1350 1351
		}
	}
}