excelize_test.go 63.2 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
	xlsx, 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.
xurime's avatar
xurime 已提交
28
	xlsx.GetRows("Sheet4")
29
	// Test get all the rows in a worksheet.
30 31
	rows, err := xlsx.GetRows("Sheet2")
	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
	xlsx.UpdateLinkedValue()
39

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

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

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

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

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

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

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

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

xurime's avatar
xurime 已提交
83
	// Test read cell value with given illegal rows number.
84 85 86 87
	_, err = xlsx.GetCellValue("Sheet2", "a-1")
	assert.EqualError(t, err, `cannot convert cell "A-1" to coordinates: invalid cell name "A-1"`)
	_, err = xlsx.GetCellValue("Sheet2", "A")
	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
	xlsx.GetCellValue("Sheet2", "a5")
	xlsx.GetCellValue("Sheet2", "C11")
	xlsx.GetCellValue("Sheet2", "D11")
	xlsx.GetCellValue("Sheet2", "D12")
xurime's avatar
xurime 已提交
94
	// Test SetCellValue function.
95
	xlsx.SetCellValue("Sheet2", "F1", " Hello")
96 97
	xlsx.SetCellValue("Sheet2", "G1", []byte("World"))
	xlsx.SetCellValue("Sheet2", "F2", 42)
98 99 100 101 102 103 104 105 106 107 108 109 110 111
	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)
112
	xlsx.SetCellValue("Sheet2", "F17", complex64(5+10i))
113

114 115 116 117 118 119 120 121 122 123
	// Test boolean write
	booltest := []struct {
		value    bool
		expected string
	}{
		{false, "0"},
		{true, "1"},
	}
	for _, test := range booltest {
		xlsx.SetCellValue("Sheet2", "F16", test.value)
124 125 126
		val, err := xlsx.GetCellValue("Sheet2", "F16")
		assert.NoError(t, err)
		assert.Equal(t, test.expected, val)
127
	}
128

129
	xlsx.SetCellValue("Sheet2", "G2", nil)
130

131
	assert.EqualError(t, xlsx.SetCellValue("Sheet2", "G4", time.Now()), "only UTC time expected")
132 133

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

xurime's avatar
xurime 已提交
154
func TestSaveFile(t *testing.T) {
155
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
xurime's avatar
xurime 已提交
156 157 158
	if !assert.NoError(t, err) {
		t.FailNow()
	}
159 160
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSaveFile.xlsx")))
	xlsx, err = OpenFile(filepath.Join("test", "TestSaveFile.xlsx"))
xurime's avatar
xurime 已提交
161 162 163 164 165 166
	if !assert.NoError(t, err) {
		t.FailNow()
	}
	assert.NoError(t, xlsx.Save())
}

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

func TestAddPicture(t *testing.T) {
179
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
180 181
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
182
	}
V
Veniamin Albaev 已提交
183

184
	// Test add picture to worksheet with offset and location hyperlink.
185
	err = xlsx.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
V
Veniamin Albaev 已提交
186 187 188
		`{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
	if !assert.NoError(t, err) {
		t.FailNow()
189
	}
V
Veniamin Albaev 已提交
190

191
	// Test add picture to worksheet with offset, external hyperlink and positioning.
192
	err = xlsx.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
V
Veniamin Albaev 已提交
193 194 195
		`{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
	if !assert.NoError(t, err) {
		t.FailNow()
196
	}
V
Veniamin Albaev 已提交
197

198
	file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.jpg"))
V
Veniamin Albaev 已提交
199 200 201 202 203 204 205 206 207
	if !assert.NoError(t, err) {
		t.FailNow()
	}

	// Test add picture to worksheet from bytes.
	err = xlsx.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".jpg", file)
	assert.NoError(t, err)

	// Test write file to given path.
208
	err = xlsx.SaveAs(filepath.Join("test", "TestAddPicture.xlsx"))
V
Veniamin Albaev 已提交
209 210 211 212
	assert.NoError(t, err)
}

func TestAddPictureErrors(t *testing.T) {
213
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
214 215 216 217
	if !assert.NoError(t, err) {
		t.FailNow()
	}

218
	// Test add picture to worksheet with invalid file path.
219
	err = xlsx.AddPicture("Sheet1", "G21", filepath.Join("test", "not_exists_dir", "not_exists.icon"), "")
V
Veniamin Albaev 已提交
220 221
	if assert.Error(t, err) {
		assert.True(t, os.IsNotExist(err), "Expected os.IsNotExist(err) == true")
222
	}
V
Veniamin Albaev 已提交
223

224
	// Test add picture to worksheet with unsupport file type.
225
	err = xlsx.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), "")
V
Veniamin Albaev 已提交
226 227
	assert.EqualError(t, err, "unsupported image extension")

228
	err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1))
V
Veniamin Albaev 已提交
229 230
	assert.EqualError(t, err, "unsupported image extension")

231 232
	// Test add picture to worksheet with invalid file data.
	err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", ".jpg", make([]byte, 1))
V
Veniamin Albaev 已提交
233
	assert.EqualError(t, err, "image: unknown format")
234
}
xurime's avatar
xurime 已提交
235

236
func TestBrokenFile(t *testing.T) {
xurime's avatar
xurime 已提交
237
	// Test write file with broken file struct.
238
	xlsx := File{}
xurime's avatar
xurime 已提交
239

V
Veniamin Albaev 已提交
240 241 242
	t.Run("SaveWithoutName", func(t *testing.T) {
		assert.EqualError(t, xlsx.Save(), "no path defined for file, consider File.WriteTo or File.Write")
	})
243

V
Veniamin Albaev 已提交
244 245
	t.Run("SaveAsEmptyStruct", func(t *testing.T) {
		// Test write file with broken file struct with given path.
246
		assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestBrokenFile.SaveAsEmptyStruct.xlsx")))
V
Veniamin Albaev 已提交
247 248 249 250
	})

	t.Run("OpenBadWorkbook", func(t *testing.T) {
		// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
251
		f3, err := OpenFile(filepath.Join("test", "BadWorkbook.xlsx"))
V
Veniamin Albaev 已提交
252 253 254 255 256 257 258
		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.
259
		_, err := OpenFile(filepath.Join("test", "NotExistsFile.xlsx"))
V
Veniamin Albaev 已提交
260 261 262 263
		if assert.Error(t, err) {
			assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true")
		}
	})
264 265
}

266
func TestNewFile(t *testing.T) {
267
	// Test create a XLSX file.
268
	xlsx := NewFile()
269
	xlsx.NewSheet("Sheet1")
270 271 272 273
	xlsx.NewSheet("XLSXSheet2")
	xlsx.NewSheet("XLSXSheet3")
	xlsx.SetCellInt("XLSXSheet2", "A23", 56)
	xlsx.SetCellStr("Sheet1", "B20", "42")
274
	xlsx.SetActiveSheet(0)
V
Veniamin Albaev 已提交
275

276
	// Test add picture to sheet with scaling and positioning.
277 278
	err := xlsx.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
		`{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
V
Veniamin Albaev 已提交
279 280
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
281
	}
V
Veniamin Albaev 已提交
282

283
	// Test add picture to worksheet without formatset.
284
	err = xlsx.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), "")
V
Veniamin Albaev 已提交
285 286
	if !assert.NoError(t, err) {
		t.FailNow()
287
	}
V
Veniamin Albaev 已提交
288

289
	// Test add picture to worksheet with invalid formatset.
290
	err = xlsx.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), `{`)
V
Veniamin Albaev 已提交
291 292
	if !assert.Error(t, err) {
		t.FailNow()
293
	}
V
Veniamin Albaev 已提交
294

295
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestNewFile.xlsx")))
xurime's avatar
xurime 已提交
296
}
297

298
func TestColWidth(t *testing.T) {
299
	xlsx := NewFile()
300 301 302 303
	xlsx.SetColWidth("Sheet1", "B", "A", 12)
	xlsx.SetColWidth("Sheet1", "A", "B", 12)
	xlsx.GetColWidth("Sheet1", "A")
	xlsx.GetColWidth("Sheet1", "C")
304
	err := xlsx.SaveAs(filepath.Join("test", "TestColWidth.xlsx"))
305
	if err != nil {
306
		t.Error(err)
307
	}
308 309 310
	convertRowHeightToPixels(0)
}

311
func TestSetCellHyperLink(t *testing.T) {
312
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
313 314 315 316
	if err != nil {
		t.Log(err)
	}
	// Test set cell hyperlink in a work sheet already have hyperlinks.
317
	assert.NoError(t, xlsx.SetCellHyperLink("Sheet1", "B19", "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
318
	// Test add first hyperlink in a work sheet.
319
	assert.NoError(t, xlsx.SetCellHyperLink("Sheet2", "C1", "https://github.com/360EntSecGroup-Skylar/excelize", "External"))
320
	// Test add Location hyperlink in a work sheet.
321
	assert.NoError(t, xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location"))
322

323
	assert.EqualError(t, xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", ""), `invalid link type ""`)
324

325
	assert.EqualError(t, xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location"), `invalid cell name ""`)
326

327
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellHyperLink.xlsx")))
328 329
}

330
func TestGetCellHyperLink(t *testing.T) {
331
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
332 333
	if !assert.NoError(t, err) {
		t.FailNow()
334
	}
V
Veniamin Albaev 已提交
335

336 337
	link, target, err := xlsx.GetCellHyperLink("Sheet1", "")
	assert.EqualError(t, err, `invalid cell name ""`)
338

339 340
	link, target, err = xlsx.GetCellHyperLink("Sheet1", "A22")
	assert.NoError(t, err)
341
	t.Log(link, target)
342 343
	link, target, err = xlsx.GetCellHyperLink("Sheet2", "D6")
	assert.NoError(t, err)
344
	t.Log(link, target)
345 346
	link, target, err = xlsx.GetCellHyperLink("Sheet3", "H3")
	assert.NoError(t, err)
347 348 349
	t.Log(link, target)
}

350
func TestSetCellFormula(t *testing.T) {
351
	xlsx, 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 357
	xlsx.SetCellFormula("Sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)")
	xlsx.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)")
358

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

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

364 365 366 367 368 369 370 371 372 373
	xlsx, err = OpenFile(filepath.Join("test", "CalcChain.xlsx"))
	if !assert.NoError(t, err) {
		t.FailNow()
	}
	// Test remove cell formula.
	xlsx.SetCellFormula("Sheet1", "A1", "")
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellFormula2.xlsx")))
	// Test remove all cell formula.
	xlsx.SetCellFormula("Sheet1", "B1", "")
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellFormula3.xlsx")))
374
}
375 376

func TestSetSheetBackground(t *testing.T) {
377
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
378 379
	if !assert.NoError(t, err) {
		t.FailNow()
380
	}
V
Veniamin Albaev 已提交
381

382
	err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "images", "background.jpg"))
V
Veniamin Albaev 已提交
383 384
	if !assert.NoError(t, err) {
		t.FailNow()
385
	}
V
Veniamin Albaev 已提交
386

387
	err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "images", "background.jpg"))
V
Veniamin Albaev 已提交
388 389
	if !assert.NoError(t, err) {
		t.FailNow()
390
	}
V
Veniamin Albaev 已提交
391

392
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetSheetBackground.xlsx")))
V
Veniamin Albaev 已提交
393 394 395
}

func TestSetSheetBackgroundErrors(t *testing.T) {
396
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
397 398
	if !assert.NoError(t, err) {
		t.FailNow()
399
	}
V
Veniamin Albaev 已提交
400

401
	err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "not_exists", "not_exists.png"))
V
Veniamin Albaev 已提交
402 403 404 405
	if assert.Error(t, err) {
		assert.True(t, os.IsNotExist(err), "Expected os.IsNotExists(err) == true")
	}

406
	err = xlsx.SetSheetBackground("Sheet2", filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
407
	assert.EqualError(t, err, "unsupported image extension")
408
}
xurime's avatar
xurime 已提交
409

410
func TestMergeCell(t *testing.T) {
411
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
412 413
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
414
	}
V
Veniamin Albaev 已提交
415

416 417 418 419 420 421 422 423 424 425 426
	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))
427
	xlsx.SetCellHyperLink("Sheet1", "J11", "https://github.com/360EntSecGroup-Skylar/excelize", "External")
428 429
	xlsx.SetCellFormula("Sheet1", "G12", "SUM(Sheet1!B19,Sheet1!C19)")
	xlsx.GetCellValue("Sheet1", "H11")
430
	xlsx.GetCellValue("Sheet2", "A6") // Merged cell ref is single coordinate.
431
	xlsx.GetCellFormula("Sheet1", "G12")
V
Veniamin Albaev 已提交
432

433
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestMergeCell.xlsx")))
xurime's avatar
xurime 已提交
434
}
N
Nikolas Silva 已提交
435

S
sairoutine 已提交
436 437 438 439 440
func TestGetMergeCells(t *testing.T) {
	wants := []struct {
		value string
		start string
		end   string
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
	}{{
		value: "A1",
		start: "A1",
		end:   "B1",
	}, {
		value: "A2",
		start: "A2",
		end:   "A3",
	}, {
		value: "A4",
		start: "A4",
		end:   "B5",
	}, {
		value: "A7",
		start: "A7",
		end:   "C10",
	}}
S
sairoutine 已提交
458

459
	xlsx, err := OpenFile(filepath.Join("test", "MergeCell.xlsx"))
V
Veniamin Albaev 已提交
460 461
	if !assert.NoError(t, err) {
		t.FailNow()
S
sairoutine 已提交
462
	}
463
	sheet1 := xlsx.GetSheetName(1)
S
sairoutine 已提交
464

465 466 467
	mergeCells := xlsx.GetMergeCells(sheet1)
	if !assert.Len(t, mergeCells, len(wants)) {
		t.FailNow()
S
sairoutine 已提交
468 469 470
	}

	for i, m := range mergeCells {
471 472 473
		assert.Equal(t, wants[i].value, m.GetCellValue())
		assert.Equal(t, wants[i].start, m.GetStartAxis())
		assert.Equal(t, wants[i].end, m.GetEndAxis())
S
sairoutine 已提交
474 475 476
	}
}

477
func TestSetCellStyleAlignment(t *testing.T) {
V
Veniamin Albaev 已提交
478 479 480
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
481
	}
V
Veniamin Albaev 已提交
482

483 484
	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}}`)
V
Veniamin Albaev 已提交
485 486
	if !assert.NoError(t, err) {
		t.FailNow()
487
	}
V
Veniamin Albaev 已提交
488

489
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A22", "A22", style))
490

491
	// Test set cell style with given illegal rows number.
492 493
	assert.EqualError(t, xlsx.SetCellStyle("Sheet1", "A", "A22", style), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
	assert.EqualError(t, xlsx.SetCellStyle("Sheet1", "A22", "A", style), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
494

495
	// Test get cell style with given illegal rows number.
496 497 498
	index, err := xlsx.GetCellStyle("Sheet1", "A")
	assert.Equal(t, 0, index)
	assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
V
Veniamin Albaev 已提交
499

500
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleAlignment.xlsx")))
501 502 503
}

func TestSetCellStyleBorder(t *testing.T) {
V
Veniamin Albaev 已提交
504 505 506
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
507
	}
508

V
Veniamin Albaev 已提交
509
	var style int
510

511
	// Test set border on overlapping area with vertical variants shading styles gradient fill.
512
	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}]}`)
V
Veniamin Albaev 已提交
513 514
	if !assert.NoError(t, err) {
		t.FailNow()
515
	}
516
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "J21", "L25", style))
517 518

	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}}`)
V
Veniamin Albaev 已提交
519 520
	if !assert.NoError(t, err) {
		t.FailNow()
521
	}
522
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "M28", "K24", style))
523 524

	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}}`)
V
Veniamin Albaev 已提交
525 526
	if !assert.NoError(t, err) {
		t.FailNow()
527
	}
528
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "M28", "K24", style))
529

530
	// Test set border and solid style pattern fill for a single cell.
531
	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}}`)
V
Veniamin Albaev 已提交
532 533
	if !assert.NoError(t, err) {
		t.FailNow()
534
	}
535

536
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "O22", "O22", style))
V
Veniamin Albaev 已提交
537

538
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleBorder.xlsx")))
V
Veniamin Albaev 已提交
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
}

func TestSetCellStyleBorderErrors(t *testing.T) {
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
	}

	// Set border with invalid style parameter.
	_, err = xlsx.NewStyle("")
	if !assert.EqualError(t, err, "unexpected end of JSON input") {
		t.FailNow()
	}

	// Set border with invalid style index number.
	_, 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}]}`)
	if !assert.NoError(t, err) {
		t.FailNow()
557 558 559
	}
}

560
func TestSetCellStyleNumberFormat(t *testing.T) {
V
Veniamin Albaev 已提交
561 562 563
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
564
	}
V
Veniamin Albaev 已提交
565

xurime's avatar
xurime 已提交
566
	// Test only set fill and number format for a cell.
567 568 569 570 571 572 573 574 575 576 577 578 579
	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)
			}
580
			style, err := xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":5},"number_format": ` + strconv.Itoa(d) + `}`)
V
Veniamin Albaev 已提交
581 582
			if !assert.NoError(t, err) {
				t.FailNow()
583
			}
584
			assert.NoError(t, xlsx.SetCellStyle("Sheet2", c, c, style))
585 586 587
			t.Log(xlsx.GetCellValue("Sheet2", c))
		}
	}
588 589
	var style int
	style, err = xlsx.NewStyle(`{"number_format":-1}`)
V
Veniamin Albaev 已提交
590 591
	if !assert.NoError(t, err) {
		t.FailNow()
592
	}
593
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "L33", "L33", style))
V
Veniamin Albaev 已提交
594

595
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleNumberFormat.xlsx")))
596 597
}

598
func TestSetCellStyleCurrencyNumberFormat(t *testing.T) {
V
Veniamin Albaev 已提交
599 600 601 602 603
	t.Run("TestBook3", func(t *testing.T) {
		xlsx, err := prepareTestBook3()
		if !assert.NoError(t, err) {
			t.FailNow()
		}
604

V
Veniamin Albaev 已提交
605 606 607 608 609 610 611
		xlsx.SetCellValue("Sheet1", "A1", 56)
		xlsx.SetCellValue("Sheet1", "A2", -32.3)
		var style int
		style, err = xlsx.NewStyle(`{"number_format": 188, "decimal_places": -1}`)
		if !assert.NoError(t, err) {
			t.FailNow()
		}
612

613
		assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A1", "A1", style))
V
Veniamin Albaev 已提交
614 615 616 617
		style, err = xlsx.NewStyle(`{"number_format": 188, "decimal_places": 31, "negred": true}`)
		if !assert.NoError(t, err) {
			t.FailNow()
		}
618

619
		assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A2", "A2", style))
620

621
		assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleCurrencyNumberFormat.TestBook3.xlsx")))
V
Veniamin Albaev 已提交
622
	})
623

V
Veniamin Albaev 已提交
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
	t.Run("TestBook4", func(t *testing.T) {
		xlsx, err := prepareTestBook4()
		if !assert.NoError(t, err) {
			t.FailNow()
		}
		xlsx.SetCellValue("Sheet1", "A1", 42920.5)
		xlsx.SetCellValue("Sheet1", "A2", 42920.5)

		_, err = xlsx.NewStyle(`{"number_format": 26, "lang": "zh-tw"}`)
		if !assert.NoError(t, err) {
			t.FailNow()
		}

		style, err := xlsx.NewStyle(`{"number_format": 27}`)
		if !assert.NoError(t, err) {
			t.FailNow()
		}

642
		assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A1", "A1", style))
V
Veniamin Albaev 已提交
643 644 645 646 647
		style, err = xlsx.NewStyle(`{"number_format": 31, "lang": "ko-kr"}`)
		if !assert.NoError(t, err) {
			t.FailNow()
		}

648
		assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A2", "A2", style))
V
Veniamin Albaev 已提交
649 650 651 652 653

		style, err = xlsx.NewStyle(`{"number_format": 71, "lang": "th-th"}`)
		if !assert.NoError(t, err) {
			t.FailNow()
		}
654
		assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A2", "A2", style))
V
Veniamin Albaev 已提交
655

656
		assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleCurrencyNumberFormat.TestBook4.xlsx")))
V
Veniamin Albaev 已提交
657
	})
658 659
}

660 661 662 663 664 665 666 667
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)
	}
668
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A1", "A1", style))
669 670 671 672
	style, err = xlsx.NewStyle(`{"custom_number_format": "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"}`)
	if err != nil {
		t.Log(err)
	}
673
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "A2", "A2", style))
V
Veniamin Albaev 已提交
674

675
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleCustomNumberFormat.xlsx")))
676 677
}

678
func TestSetCellStyleFill(t *testing.T) {
V
Veniamin Albaev 已提交
679 680 681
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
682
	}
V
Veniamin Albaev 已提交
683

684
	var style int
685
	// Test set fill for cell with invalid parameter.
686
	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF","#E0EBF5"],"shading":6}}`)
V
Veniamin Albaev 已提交
687 688
	if !assert.NoError(t, err) {
		t.FailNow()
689
	}
690
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "O23", "O23", style))
691 692

	style, err = xlsx.NewStyle(`{"fill":{"type":"gradient","color":["#FFFFFF"],"shading":1}}`)
V
Veniamin Albaev 已提交
693 694
	if !assert.NoError(t, err) {
		t.FailNow()
695
	}
696
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "O23", "O23", style))
697 698

	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":[],"pattern":1}}`)
V
Veniamin Albaev 已提交
699 700
	if !assert.NoError(t, err) {
		t.FailNow()
701
	}
702
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "O23", "O23", style))
xurime's avatar
xurime 已提交
703

704
	style, err = xlsx.NewStyle(`{"fill":{"type":"pattern","color":["#E0EBF5"],"pattern":19}}`)
V
Veniamin Albaev 已提交
705 706
	if !assert.NoError(t, err) {
		t.FailNow()
707
	}
708
	assert.NoError(t, xlsx.SetCellStyle("Sheet1", "O23", "O23", style))
709

710
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleFill.xlsx")))
711 712 713
}

func TestSetCellStyleFont(t *testing.T) {
V
Veniamin Albaev 已提交
714 715 716
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
717
	}
V
Veniamin Albaev 已提交
718

719 720
	var style int
	style, err = xlsx.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"single"}}`)
V
Veniamin Albaev 已提交
721 722
	if !assert.NoError(t, err) {
		t.FailNow()
723
	}
V
Veniamin Albaev 已提交
724

725
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "A1", "A1", style))
726 727

	style, err = xlsx.NewStyle(`{"font":{"italic":true,"underline":"double"}}`)
V
Veniamin Albaev 已提交
728 729
	if !assert.NoError(t, err) {
		t.FailNow()
730
	}
V
Veniamin Albaev 已提交
731

732
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "A2", "A2", style))
733 734

	style, err = xlsx.NewStyle(`{"font":{"bold":true}}`)
V
Veniamin Albaev 已提交
735 736
	if !assert.NoError(t, err) {
		t.FailNow()
737
	}
V
Veniamin Albaev 已提交
738

739
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "A3", "A3", style))
740 741

	style, err = xlsx.NewStyle(`{"font":{"bold":true,"family":"","size":0,"color":"","underline":""}}`)
V
Veniamin Albaev 已提交
742 743
	if !assert.NoError(t, err) {
		t.FailNow()
744
	}
V
Veniamin Albaev 已提交
745

746
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "A4", "A4", style))
747 748

	style, err = xlsx.NewStyle(`{"font":{"color":"#777777"}}`)
V
Veniamin Albaev 已提交
749 750
	if !assert.NoError(t, err) {
		t.FailNow()
751
	}
V
Veniamin Albaev 已提交
752

753
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "A5", "A5", style))
V
Veniamin Albaev 已提交
754

755
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleFont.xlsx")))
756
}
757

758
func TestSetCellStyleProtection(t *testing.T) {
V
Veniamin Albaev 已提交
759 760 761
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
762
	}
V
Veniamin Albaev 已提交
763

764 765
	var style int
	style, err = xlsx.NewStyle(`{"protection":{"hidden":true, "locked":true}}`)
V
Veniamin Albaev 已提交
766 767
	if !assert.NoError(t, err) {
		t.FailNow()
768
	}
V
Veniamin Albaev 已提交
769

770
	assert.NoError(t, xlsx.SetCellStyle("Sheet2", "A6", "A6", style))
771
	err = xlsx.SaveAs(filepath.Join("test", "TestSetCellStyleProtection.xlsx"))
V
Veniamin Albaev 已提交
772 773
	if !assert.NoError(t, err) {
		t.FailNow()
774 775 776
	}
}

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

		xlsx.DeleteSheet("XLSXSheet3")
785
		assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook3.xlsx")))
V
Veniamin Albaev 已提交
786 787 788 789 790 791 792 793 794 795
	})

	t.Run("TestBook4", func(t *testing.T) {
		xlsx, err := prepareTestBook4()
		if !assert.NoError(t, err) {
			t.FailNow()
		}
		xlsx.DeleteSheet("Sheet1")
		xlsx.AddComment("Sheet1", "A1", "")
		xlsx.AddComment("Sheet1", "A1", `{"author":"Excelize: ","text":"This is a comment."}`)
796
		assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetDeleteSheet.TestBook4.xlsx")))
V
Veniamin Albaev 已提交
797
	})
798
}
799 800

func TestGetPicture(t *testing.T) {
V
Veniamin Albaev 已提交
801 802 803
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
804
	}
V
Veniamin Albaev 已提交
805

806 807
	file, raw, err := xlsx.GetPicture("Sheet1", "F21")
	assert.NoError(t, err)
808 809
	if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
		!assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0644)) {
810 811

		t.FailNow()
812
	}
V
Veniamin Albaev 已提交
813

814
	// Try to get picture from a worksheet that doesn't contain any images.
815 816
	file, raw, err = xlsx.GetPicture("Sheet3", "I9")
	assert.NoError(t, err)
817 818 819
	assert.Empty(t, file)
	assert.Empty(t, raw)

820
	// Try to get picture from a cell that doesn't contain an image.
821 822
	file, raw, err = xlsx.GetPicture("Sheet2", "A2")
	assert.NoError(t, err)
823 824 825
	assert.Empty(t, file)
	assert.Empty(t, raw)

xurime's avatar
xurime 已提交
826 827 828
	xlsx.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
	xlsx.getDrawingRelationships("", "")
	xlsx.getSheetRelationshipsTargetByID("", "")
829
	xlsx.deleteSheetRelationships("", "")
830 831

	// Try to get picture from a local storage file.
832 833 834 835
	if !assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestGetPicture.xlsx"))) {
		t.FailNow()
	}

836 837 838 839
	xlsx, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
	if !assert.NoError(t, err) {
		t.FailNow()
	}
840

841 842
	file, raw, err = xlsx.GetPicture("Sheet1", "F21")
	assert.NoError(t, err)
843 844
	if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
		!assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0644)) {
845 846

		t.FailNow()
847 848 849
	}

	// Try to get picture from a local storage file that doesn't contain an image.
850 851
	file, raw, err = xlsx.GetPicture("Sheet1", "F22")
	assert.NoError(t, err)
852 853
	assert.Empty(t, file)
	assert.Empty(t, raw)
854
}
855

856
func TestSheetVisibility(t *testing.T) {
V
Veniamin Albaev 已提交
857 858 859
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
860
	}
V
Veniamin Albaev 已提交
861

862 863 864 865
	xlsx.SetSheetVisible("Sheet2", false)
	xlsx.SetSheetVisible("Sheet1", false)
	xlsx.SetSheetVisible("Sheet1", true)
	xlsx.GetSheetVisible("Sheet1")
V
Veniamin Albaev 已提交
866

867
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSheetVisibility.xlsx")))
868 869
}

870
func TestColumnVisibility(t *testing.T) {
V
Veniamin Albaev 已提交
871 872 873 874 875 876 877 878 879 880
	t.Run("TestBook1", func(t *testing.T) {
		xlsx, err := prepareTestBook1()
		if !assert.NoError(t, err) {
			t.FailNow()
		}

		xlsx.SetColVisible("Sheet1", "F", false)
		xlsx.SetColVisible("Sheet1", "F", true)
		xlsx.GetColVisible("Sheet1", "F")
		xlsx.SetColVisible("Sheet3", "E", false)
881
		assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestColumnVisibility.xlsx")))
V
Veniamin Albaev 已提交
882 883 884 885 886 887 888 889 890
	})

	t.Run("TestBook3", func(t *testing.T) {
		xlsx, err := prepareTestBook3()
		if !assert.NoError(t, err) {
			t.FailNow()
		}
		xlsx.GetColVisible("Sheet1", "B")
	})
891 892
}

893
func TestCopySheet(t *testing.T) {
V
Veniamin Albaev 已提交
894 895 896
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
897
	}
V
Veniamin Albaev 已提交
898

899 900
	idx := xlsx.NewSheet("CopySheet")
	err = xlsx.CopySheet(1, idx)
V
Veniamin Albaev 已提交
901 902
	if !assert.NoError(t, err) {
		t.FailNow()
903
	}
V
Veniamin Albaev 已提交
904

905
	xlsx.SetCellValue("Sheet4", "F1", "Hello")
906 907 908
	val, err := xlsx.GetCellValue("Sheet1", "F1")
	assert.NoError(t, err)
	assert.NotEqual(t, "Hello", val)
V
Veniamin Albaev 已提交
909

910
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestCopySheet.xlsx")))
V
Veniamin Albaev 已提交
911 912 913 914 915 916
}

func TestCopySheetError(t *testing.T) {
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
917
	}
V
Veniamin Albaev 已提交
918 919 920 921

	err = xlsx.CopySheet(0, -1)
	if !assert.EqualError(t, err, "invalid worksheet index") {
		t.FailNow()
922
	}
V
Veniamin Albaev 已提交
923

924
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestCopySheetError.xlsx")))
925
}
926

xurime's avatar
xurime 已提交
927
func TestAddTable(t *testing.T) {
V
Veniamin Albaev 已提交
928 929 930
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
931
	}
V
Veniamin Albaev 已提交
932

933
	err = xlsx.AddTable("Sheet1", "B26", "A21", `{}`)
V
Veniamin Albaev 已提交
934 935
	if !assert.NoError(t, err) {
		t.FailNow()
936
	}
V
Veniamin Albaev 已提交
937

938
	err = xlsx.AddTable("Sheet2", "A2", "B5", `{"table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
V
Veniamin Albaev 已提交
939 940
	if !assert.NoError(t, err) {
		t.FailNow()
941
	}
V
Veniamin Albaev 已提交
942

943
	err = xlsx.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
V
Veniamin Albaev 已提交
944 945
	if !assert.NoError(t, err) {
		t.FailNow()
xurime's avatar
xurime 已提交
946
	}
V
Veniamin Albaev 已提交
947

948
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddTable.xlsx")))
xurime's avatar
xurime 已提交
949 950
}

951
func TestAddShape(t *testing.T) {
V
Veniamin Albaev 已提交
952 953 954
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
955
	}
V
Veniamin Albaev 已提交
956

957 958 959 960
	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}`)
961
	xlsx.AddShape("Sheet3", "H1", "")
V
Veniamin Albaev 已提交
962

963
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddShape.xlsx")))
964 965
}

966
func TestAddComments(t *testing.T) {
V
Veniamin Albaev 已提交
967 968 969
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
970
	}
V
Veniamin Albaev 已提交
971

xurime's avatar
xurime 已提交
972
	s := strings.Repeat("c", 32768)
973 974
	xlsx.AddComment("Sheet1", "A30", `{"author":"`+s+`","text":"`+s+`"}`)
	xlsx.AddComment("Sheet2", "B7", `{"author":"Excelize: ","text":"This is a comment."}`)
R
Rad Cirskis 已提交
975

976
	if assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddComments.xlsx"))) {
V
Veniamin Albaev 已提交
977 978
		assert.Len(t, xlsx.GetComments(), 2)
	}
979 980
}

981
func TestAutoFilter(t *testing.T) {
982 983
	outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")

V
Veniamin Albaev 已提交
984 985 986
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
987
	}
V
Veniamin Albaev 已提交
988 989 990

	formats := []string{
		``,
991 992 993 994 995 996 997
		`{"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 已提交
998 999 1000 1001 1002 1003
	}

	for i, format := range formats {
		t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
			err = xlsx.AutoFilter("Sheet3", "D4", "B1", format)
			if assert.NoError(t, err) {
1004
				assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, i+1)))
V
Veniamin Albaev 已提交
1005 1006 1007 1008 1009 1010 1011
			}
		})
	}

}

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

V
Veniamin Albaev 已提交
1014 1015 1016 1017 1018 1019
	xlsx, err := prepareTestBook1()
	if !assert.NoError(t, err) {
		t.FailNow()
	}

	formats := []string{
1020 1021 1022 1023 1024 1025 1026
		`{"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 已提交
1027 1028 1029 1030
	for i, format := range formats {
		t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
			err = xlsx.AutoFilter("Sheet3", "D4", "B1", format)
			if assert.Error(t, err) {
1031
				assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, i+1)))
V
Veniamin Albaev 已提交
1032 1033
			}
		})
1034 1035 1036
	}
}

1037
func TestAddChart(t *testing.T) {
1038
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1039 1040
	if !assert.NoError(t, err) {
		t.FailNow()
1041
	}
V
Veniamin Albaev 已提交
1042

xurime's avatar
xurime 已提交
1043 1044 1045 1046 1047 1048 1049 1050
	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)
	}
1051
	xlsx.AddChart("Sheet1", "P1", "")
1052 1053 1054 1055 1056 1057 1058
	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"}`)
1059 1060
	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"}`)
1061 1062 1063 1064 1065 1066
	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"}`)
1067
	xlsx.AddChart("Sheet2", "P64", `{"type":"barPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Stacked 100% Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
1068
	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"}`)
1069 1070
	xlsx.AddChart("Sheet2", "P80", `{"type":"bar3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","y_axis":{"maximum":7.5,"minimum":0.5}}`)
	xlsx.AddChart("Sheet2", "X80", `{"type":"bar3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D 100% Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"reverse_order":true,"maximum":0,"minimum":0},"y_axis":{"reverse_order":true,"maximum":0,"minimum":0}}`)
1071 1072 1073 1074 1075 1076 1077
	// area series charts
	xlsx.AddChart("Sheet2", "AF1", `{"type":"area","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	xlsx.AddChart("Sheet2", "AN1", `{"type":"areaStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	xlsx.AddChart("Sheet2", "AF16", `{"type":"areaPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D 100% Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	xlsx.AddChart("Sheet2", "AN16", `{"type":"area3D","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	xlsx.AddChart("Sheet2", "AF32", `{"type":"area3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
	xlsx.AddChart("Sheet2", "AN32", `{"type":"area3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D 100% Stacked Area Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
V
Veniamin Albaev 已提交
1078

1079
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddChart.xlsx")))
1080 1081 1082 1083
}

func TestInsertCol(t *testing.T) {
	xlsx := NewFile()
1084 1085 1086 1087 1088 1089 1090 1091
	sheet1 := xlsx.GetSheetName(1)

	fillCells(xlsx, sheet1, 10, 10)

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

	err := xlsx.AutoFilter(sheet1, "A2", "B2", `{"column":"B","expression":"x != blanks"}`)
V
Veniamin Albaev 已提交
1092 1093
	if !assert.NoError(t, err) {
		t.FailNow()
1094
	}
V
Veniamin Albaev 已提交
1095

1096
	assert.NoError(t, xlsx.InsertCol(sheet1, "A"))
V
Veniamin Albaev 已提交
1097

1098
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestInsertCol.xlsx")))
1099 1100 1101 1102
}

func TestRemoveCol(t *testing.T) {
	xlsx := NewFile()
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
	sheet1 := xlsx.GetSheetName(1)

	fillCells(xlsx, sheet1, 10, 15)

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

	xlsx.MergeCell(sheet1, "A1", "B1")
	xlsx.MergeCell(sheet1, "A2", "B2")

1113 1114
	assert.NoError(t, xlsx.RemoveCol(sheet1, "A"))
	assert.NoError(t, xlsx.RemoveCol(sheet1, "A"))
V
Veniamin Albaev 已提交
1115

1116
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestRemoveCol.xlsx")))
1117 1118
}

xurime's avatar
xurime 已提交
1119 1120 1121
func TestSetPane(t *testing.T) {
	xlsx := NewFile()
	xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
1122 1123 1124 1125 1126 1127
	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"}]}`)
1128
	xlsx.SetPanes("Panes 4", "")
V
Veniamin Albaev 已提交
1129

1130
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetPane.xlsx")))
xurime's avatar
xurime 已提交
1131 1132
}

1133 1134
func TestConditionalFormat(t *testing.T) {
	xlsx := NewFile()
1135 1136 1137 1138
	sheet1 := xlsx.GetSheetName(1)

	fillCells(xlsx, sheet1, 10, 15)

1139 1140 1141 1142
	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}}`)
V
Veniamin Albaev 已提交
1143 1144 1145 1146
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1147 1148
	// Light yellow format for neutral conditional.
	format2, err = xlsx.NewConditionalStyle(`{"fill":{"type":"pattern","color":["#FEEAA0"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1149 1150 1151 1152
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1153 1154
	// Light green format for good conditional.
	format3, err = xlsx.NewConditionalStyle(`{"font":{"color":"#09600B"},"fill":{"type":"pattern","color":["#C7EECF"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1155 1156 1157 1158
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1159
	// Color scales: 2 color.
1160
	xlsx.SetConditionalFormat(sheet1, "A1:A10", `[{"type":"2_color_scale","criteria":"=","min_type":"min","max_type":"max","min_color":"#F8696B","max_color":"#63BE7B"}]`)
1161
	// Color scales: 3 color.
1162
	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"}]`)
1163
	// Hightlight cells rules: between...
1164
	xlsx.SetConditionalFormat(sheet1, "C1:C10", fmt.Sprintf(`[{"type":"cell","criteria":"between","format":%d,"minimum":"6","maximum":"8"}]`, format1))
1165
	// Hightlight cells rules: Greater Than...
1166
	xlsx.SetConditionalFormat(sheet1, "D1:D10", fmt.Sprintf(`[{"type":"cell","criteria":">","format":%d,"value":"6"}]`, format3))
1167
	// Hightlight cells rules: Equal To...
1168
	xlsx.SetConditionalFormat(sheet1, "E1:E10", fmt.Sprintf(`[{"type":"top","criteria":"=","format":%d}]`, format3))
1169
	// Hightlight cells rules: Not Equal To...
1170
	xlsx.SetConditionalFormat(sheet1, "F1:F10", fmt.Sprintf(`[{"type":"unique","criteria":"=","format":%d}]`, format2))
1171
	// Hightlight cells rules: Duplicate Values...
1172
	xlsx.SetConditionalFormat(sheet1, "G1:G10", fmt.Sprintf(`[{"type":"duplicate","criteria":"=","format":%d}]`, format2))
1173
	// Top/Bottom rules: Top 10%.
1174
	xlsx.SetConditionalFormat(sheet1, "H1:H10", fmt.Sprintf(`[{"type":"top","criteria":"=","format":%d,"value":"6","percent":true}]`, format1))
1175
	// Top/Bottom rules: Above Average...
1176
	xlsx.SetConditionalFormat(sheet1, "I1:I10", fmt.Sprintf(`[{"type":"average","criteria":"=","format":%d, "above_average": true}]`, format3))
1177
	// Top/Bottom rules: Below Average...
1178
	xlsx.SetConditionalFormat(sheet1, "J1:J10", fmt.Sprintf(`[{"type":"average","criteria":"=","format":%d, "above_average": false}]`, format1))
1179
	// Data Bars: Gradient Fill.
1180
	xlsx.SetConditionalFormat(sheet1, "K1:K10", `[{"type":"data_bar", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
1181
	// Use a formula to determine which cells to format.
1182
	xlsx.SetConditionalFormat(sheet1, "L1:L10", fmt.Sprintf(`[{"type":"formula", "criteria":"L2<3", "format":%d}]`, format1))
1183
	// Test set invalid format set in conditional format
1184
	xlsx.SetConditionalFormat(sheet1, "L1:L10", "")
V
Veniamin Albaev 已提交
1185

1186
	err = xlsx.SaveAs(filepath.Join("test", "TestConditionalFormat.xlsx"))
V
Veniamin Albaev 已提交
1187 1188
	if !assert.NoError(t, err) {
		t.FailNow()
1189 1190 1191
	}

	// Set conditional format with illegal valid type.
1192
	xlsx.SetConditionalFormat(sheet1, "K1:K10", `[{"type":"", "criteria":"=", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
1193
	// Set conditional format with illegal criteria type.
1194
	xlsx.SetConditionalFormat(sheet1, "K1:K10", `[{"type":"data_bar", "criteria":"", "min_type":"min","max_type":"max","bar_color":"#638EC6"}]`)
V
Veniamin Albaev 已提交
1195 1196

	// Set conditional format with file without dxfs element shold not return error.
1197
	xlsx, err = OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1198 1199 1200 1201
	if !assert.NoError(t, err) {
		t.FailNow()
	}

1202
	_, err = xlsx.NewConditionalStyle(`{"font":{"color":"#9A0511"},"fill":{"type":"pattern","color":["#FEC7CE"],"pattern":1}}`)
V
Veniamin Albaev 已提交
1203 1204 1205
	if !assert.NoError(t, err) {
		t.FailNow()
	}
1206
}
xurime's avatar
xurime 已提交
1207

V
Veniamin Albaev 已提交
1208 1209
func TestConditionalFormatError(t *testing.T) {
	xlsx := NewFile()
1210 1211 1212
	sheet1 := xlsx.GetSheetName(1)

	fillCells(xlsx, sheet1, 10, 15)
V
Veniamin Albaev 已提交
1213 1214 1215 1216 1217

	// Set conditional format with illegal JSON string should return error
	_, err := xlsx.NewConditionalStyle("")
	if !assert.EqualError(t, err, "unexpected end of JSON input") {
		t.FailNow()
xurime's avatar
xurime 已提交
1218 1219
	}
}
1220 1221

func TestSharedStrings(t *testing.T) {
1222
	xlsx, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
V
Veniamin Albaev 已提交
1223 1224
	if !assert.NoError(t, err) {
		t.FailNow()
1225 1226 1227
	}
	xlsx.GetRows("Sheet1")
}
1228 1229

func TestSetSheetRow(t *testing.T) {
1230
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1231 1232
	if !assert.NoError(t, err) {
		t.FailNow()
1233
	}
V
Veniamin Albaev 已提交
1234

1235 1236
	xlsx.SetSheetRow("Sheet1", "B27", &[]interface{}{"cell", nil, int32(42), float64(42), time.Now().UTC()})

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

1240 1241
	assert.EqualError(t, xlsx.SetSheetRow("Sheet1", "B27", []interface{}{}), `pointer to slice expected`)
	assert.EqualError(t, xlsx.SetSheetRow("Sheet1", "B27", &xlsx), `pointer to slice expected`)
1242
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestSetSheetRow.xlsx")))
1243
}
1244

1245 1246 1247 1248 1249 1250 1251 1252
func TestOutlineLevel(t *testing.T) {
	xlsx := NewFile()
	xlsx.NewSheet("Sheet2")
	xlsx.SetColOutlineLevel("Sheet1", "D", 4)
	xlsx.GetColOutlineLevel("Sheet1", "D")
	xlsx.GetColOutlineLevel("Shee2", "A")
	xlsx.SetColWidth("Sheet2", "A", "D", 13)
	xlsx.SetColOutlineLevel("Sheet2", "B", 2)
1253 1254
	xlsx.SetRowOutlineLevel("Sheet1", 2, 250)

1255 1256 1257 1258
	assert.EqualError(t, xlsx.SetRowOutlineLevel("Sheet1", 0, 1), "invalid row number 0")
	level, err := xlsx.GetRowOutlineLevel("Sheet1", 2)
	assert.NoError(t, err)
	assert.Equal(t, uint8(250), level)
1259

1260 1261
	_, err = xlsx.GetRowOutlineLevel("Sheet1", 0)
	assert.EqualError(t, err, `invalid row number 0`)
1262

1263
	err = xlsx.SaveAs(filepath.Join("test", "TestOutlineLevel.xlsx"))
V
Veniamin Albaev 已提交
1264 1265
	if !assert.NoError(t, err) {
		t.FailNow()
1266
	}
V
Veniamin Albaev 已提交
1267

1268
	xlsx, err = OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1269 1270
	if !assert.NoError(t, err) {
		t.FailNow()
1271 1272 1273 1274
	}
	xlsx.SetColOutlineLevel("Sheet2", "B", 2)
}

xurime's avatar
xurime 已提交
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
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))
}

1300
func TestSearchSheet(t *testing.T) {
1301
	xlsx, err := OpenFile(filepath.Join("test", "SharedStrings.xlsx"))
V
Veniamin Albaev 已提交
1302 1303
	if !assert.NoError(t, err) {
		t.FailNow()
1304
	}
V
Veniamin Albaev 已提交
1305

1306 1307 1308 1309 1310
	// Test search in a not exists worksheet.
	t.Log(xlsx.SearchSheet("Sheet4", ""))
	// Test search a not exists value.
	t.Log(xlsx.SearchSheet("Sheet1", "X"))
	t.Log(xlsx.SearchSheet("Sheet1", "A"))
1311 1312 1313
	// Test search the coordinates where the numerical value in the range of
	// "0-9" of Sheet1 is described by regular expression:
	t.Log(xlsx.SearchSheet("Sheet1", "[0-9]", true))
R
r-uchino 已提交
1314 1315
}

1316 1317 1318 1319 1320 1321 1322
func TestProtectSheet(t *testing.T) {
	xlsx := NewFile()
	xlsx.ProtectSheet("Sheet1", nil)
	xlsx.ProtectSheet("Sheet1", &FormatSheetProtection{
		Password:      "password",
		EditScenarios: false,
	})
V
Veniamin Albaev 已提交
1323

1324
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestProtectSheet.xlsx")))
1325 1326
}

1327
func TestUnprotectSheet(t *testing.T) {
1328
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1329 1330
	if !assert.NoError(t, err) {
		t.FailNow()
1331
	}
V
Veniamin Albaev 已提交
1332

1333
	xlsx.UnprotectSheet("Sheet1")
1334
	assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestUnprotectSheet.xlsx")))
1335 1336
}

V
Veniamin Albaev 已提交
1337
func prepareTestBook1() (*File, error) {
1338
	xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
V
Veniamin Albaev 已提交
1339 1340 1341 1342
	if err != nil {
		return nil, err
	}

1343
	err = xlsx.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
V
Veniamin Albaev 已提交
1344 1345 1346 1347 1348 1349
		`{"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.
1350
	err = xlsx.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.png"),
V
Veniamin Albaev 已提交
1351 1352 1353 1354 1355
		`{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
	if err != nil {
		return nil, err
	}

1356
	file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.jpg"))
V
Veniamin Albaev 已提交
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377
	if err != nil {
		return nil, err
	}

	err = xlsx.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".jpg", file)
	if err != nil {
		return nil, err
	}

	return xlsx, nil
}

func prepareTestBook3() (*File, error) {
	xlsx := NewFile()
	xlsx.NewSheet("Sheet1")
	xlsx.NewSheet("XLSXSheet2")
	xlsx.NewSheet("XLSXSheet3")
	xlsx.SetCellInt("XLSXSheet2", "A23", 56)
	xlsx.SetCellStr("Sheet1", "B20", "42")
	xlsx.SetActiveSheet(0)

1378 1379
	err := xlsx.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
		`{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
V
Veniamin Albaev 已提交
1380 1381 1382 1383
	if err != nil {
		return nil, err
	}

1384
	err = xlsx.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), "")
V
Veniamin Albaev 已提交
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400
	if err != nil {
		return nil, err
	}

	return xlsx, nil
}

func prepareTestBook4() (*File, error) {
	xlsx := NewFile()
	xlsx.SetColWidth("Sheet1", "B", "A", 12)
	xlsx.SetColWidth("Sheet1", "A", "B", 12)
	xlsx.GetColWidth("Sheet1", "A")
	xlsx.GetColWidth("Sheet1", "C")

	return xlsx, nil
}
1401 1402 1403 1404

func fillCells(xlsx *File, sheet string, colCount, rowCount int) {
	for col := 1; col <= colCount; col++ {
		for row := 1; row <= rowCount; row++ {
1405
			cell, _ := CoordinatesToCellName(col, row)
1406 1407 1408 1409
			xlsx.SetCellStr(sheet, cell, cell)
		}
	}
}