diff --git a/adjust_test.go b/adjust_test.go index a35e609..7b708ab 100644 --- a/adjust_test.go +++ b/adjust_test.go @@ -12,7 +12,7 @@ func TestAdjustMergeCells(t *testing.T) { assert.EqualError(t, f.adjustMergeCells(&xlsxWorksheet{ MergeCells: &xlsxMergeCells{ Cells: []*xlsxMergeCell{ - &xlsxMergeCell{ + { Ref: "A:B1", }, }, @@ -21,7 +21,7 @@ func TestAdjustMergeCells(t *testing.T) { assert.EqualError(t, f.adjustMergeCells(&xlsxWorksheet{ MergeCells: &xlsxMergeCells{ Cells: []*xlsxMergeCell{ - &xlsxMergeCell{ + { Ref: "A1:B", }, }, @@ -50,7 +50,7 @@ func TestAdjustHelper(t *testing.T) { f.Sheet["xl/worksheets/sheet1.xml"] = &xlsxWorksheet{ MergeCells: &xlsxMergeCells{ Cells: []*xlsxMergeCell{ - &xlsxMergeCell{ + { Ref: "A:B1", }, }, @@ -64,4 +64,6 @@ func TestAdjustHelper(t *testing.T) { // testing adjustHelper with illegal cell coordinates. assert.EqualError(t, f.adjustHelper("Sheet1", rows, 0, 0), `cannot convert cell "A" to coordinates: invalid cell name "A"`) assert.EqualError(t, f.adjustHelper("Sheet2", rows, 0, 0), `cannot convert cell "B" to coordinates: invalid cell name "B"`) + // testing adjustHelper on not exists worksheet. + assert.EqualError(t, f.adjustHelper("SheetN", rows, 0, 0), "sheet SheetN is not exist") } diff --git a/cell.go b/cell.go index 6a8eebe..4d22842 100644 --- a/cell.go +++ b/cell.go @@ -69,6 +69,38 @@ func (f *File) GetCellValue(sheet, axis string) (string, error) { // Note that default date format is m/d/yy h:mm of time.Time type value. You can // set numbers format by SetCellStyle() method. func (f *File) SetCellValue(sheet, axis string, value interface{}) error { + var err error + switch v := value.(type) { + case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: + err = f.setCellIntFunc(sheet, axis, v) + case float32: + err = f.SetCellFloat(sheet, axis, float64(v), -1, 32) + case float64: + err = f.SetCellFloat(sheet, axis, v, -1, 64) + case string: + err = f.SetCellStr(sheet, axis, v) + case []byte: + err = f.SetCellStr(sheet, axis, string(v)) + case time.Duration: + err = f.SetCellDefault(sheet, axis, strconv.FormatFloat(v.Seconds()/86400.0, 'f', -1, 32)) + if err != nil { + return err + } + err = f.setDefaultTimeStyle(sheet, axis, 21) + case time.Time: + err = f.setCellTimeFunc(sheet, axis, v) + case bool: + err = f.SetCellBool(sheet, axis, v) + case nil: + err = f.SetCellStr(sheet, axis, "") + default: + err = f.SetCellStr(sheet, axis, fmt.Sprintf("%v", value)) + } + return err +} + +// setCellIntFunc is a wrapper of SetCellInt. +func (f *File) setCellIntFunc(sheet, axis string, value interface{}) error { var err error switch v := value.(type) { case int: @@ -91,34 +123,31 @@ func (f *File) SetCellValue(sheet, axis string, value interface{}) error { err = f.SetCellInt(sheet, axis, int(v)) case uint64: err = f.SetCellInt(sheet, axis, int(v)) - case float32: - err = f.SetCellFloat(sheet, axis, float64(v), -1, 32) - case float64: - err = f.SetCellFloat(sheet, axis, v, -1, 64) - case string: - err = f.SetCellStr(sheet, axis, v) - case []byte: - err = f.SetCellStr(sheet, axis, string(v)) - case time.Duration: - err = f.SetCellDefault(sheet, axis, strconv.FormatFloat(v.Seconds()/86400.0, 'f', -1, 32)) - err = f.setDefaultTimeStyle(sheet, axis, 21) - case time.Time: - excelTime, err := timeToExcelTime(v) + } + return err +} + +// setCellTimeFunc provides a method to process time type of value for +// SetCellValue. +func (f *File) setCellTimeFunc(sheet, axis string, value time.Time) error { + excelTime, err := timeToExcelTime(value) + if err != nil { + return err + } + if excelTime > 0 { + err = f.SetCellDefault(sheet, axis, strconv.FormatFloat(excelTime, 'f', -1, 64)) if err != nil { return err } - if excelTime > 0 { - err = f.SetCellDefault(sheet, axis, strconv.FormatFloat(excelTime, 'f', -1, 64)) - err = f.setDefaultTimeStyle(sheet, axis, 22) - } else { - err = f.SetCellStr(sheet, axis, v.Format(time.RFC3339Nano)) + err = f.setDefaultTimeStyle(sheet, axis, 22) + if err != nil { + return err + } + } else { + err = f.SetCellStr(sheet, axis, value.Format(time.RFC3339Nano)) + if err != nil { + return err } - case bool: - err = f.SetCellBool(sheet, axis, v) - case nil: - err = f.SetCellStr(sheet, axis, "") - default: - err = f.SetCellStr(sheet, axis, fmt.Sprintf("%v", value)) } return err } @@ -398,8 +427,6 @@ func (f *File) MergeCell(sheet, hcell, vcell string) error { } if xlsx.MergeCells != nil { ref := hcell + ":" + vcell - cells := make([]*xlsxMergeCell, 0, len(xlsx.MergeCells.Cells)) - // Delete the merged cells of the overlapping area. for _, cellData := range xlsx.MergeCells.Cells { cc := strings.Split(cellData.Ref, ":") @@ -413,10 +440,8 @@ func (f *File) MergeCell(sheet, hcell, vcell string) error { if !(!c1 && !c2 && !c3 && !c4) { return nil } - cells = append(cells, cellData) } - cells = append(xlsx.MergeCells.Cells, &xlsxMergeCell{Ref: ref}) - xlsx.MergeCells.Cells = cells + xlsx.MergeCells.Cells = append(xlsx.MergeCells.Cells, &xlsxMergeCell{Ref: ref}) } else { xlsx.MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: hcell + ":" + vcell}}} } diff --git a/chart_test.go b/chart_test.go index 1dfc468..98baedd 100644 --- a/chart_test.go +++ b/chart_test.go @@ -96,3 +96,8 @@ func TestChartSize(t *testing.T) { t.FailNow() } } + +func TestAddDrawingChart(t *testing.T) { + f := NewFile() + assert.EqualError(t, f.addDrawingChart("SheetN", "", "", 0, 0, 0, nil), `cannot convert cell "" to coordinates: invalid cell name ""`) +} diff --git a/date_test.go b/date_test.go index 63cb19e..2885af0 100644 --- a/date_test.go +++ b/date_test.go @@ -69,7 +69,7 @@ func TestTimeFromExcelTime(t *testing.T) { } func TestTimeFromExcelTime_1904(t *testing.T) { - shiftJulianToNoon(1, -0.6) + _, _ = shiftJulianToNoon(1, -0.6) timeFromExcelTime(61, true) timeFromExcelTime(62, true) } diff --git a/excelize.go b/excelize.go index 2f0db1e..6e93f8d 100644 --- a/excelize.go +++ b/excelize.go @@ -116,7 +116,7 @@ func (f *File) setDefaultTimeStyle(sheet, axis string, format int) error { func (f *File) workSheetReader(sheet string) (*xlsxWorksheet, error) { name, ok := f.sheetMap[trimSheetName(sheet)] if !ok { - return nil, fmt.Errorf("Sheet %s is not exist", sheet) + return nil, fmt.Errorf("sheet %s is not exist", sheet) } if f.Sheet[name] == nil { var xlsx xlsxWorksheet diff --git a/excelize_test.go b/excelize_test.go index 4bd5323..6192110 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -57,7 +57,7 @@ func TestOpenFile(t *testing.T) { xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.") xlsx.SetCellInt("Sheet3", "A23", 10) xlsx.SetCellStr("Sheet3", "b230", "10") - assert.EqualError(t, xlsx.SetCellStr("Sheet10", "b230", "10"), "Sheet Sheet10 is not exist") + assert.EqualError(t, xlsx.SetCellStr("Sheet10", "b230", "10"), "sheet Sheet10 is not exist") // Test set cell string value with illegal row number. assert.EqualError(t, xlsx.SetCellStr("Sheet1", "A", "10"), `cannot convert cell "A" to coordinates: invalid cell name "A"`) @@ -92,24 +92,31 @@ func TestOpenFile(t *testing.T) { xlsx.GetCellValue("Sheet2", "D11") xlsx.GetCellValue("Sheet2", "D12") // Test SetCellValue function. - xlsx.SetCellValue("Sheet2", "F1", " Hello") - xlsx.SetCellValue("Sheet2", "G1", []byte("World")) - xlsx.SetCellValue("Sheet2", "F2", 42) - 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) - xlsx.SetCellValue("Sheet2", "F17", complex64(5+10i)) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F1", " Hello")) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "G1", []byte("World"))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F2", 42)) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F3", int8(1<<8/2-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F4", int16(1<<16/2-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F5", int32(1<<32/2-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F6", int64(1<<32/2-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F7", float32(42.65418))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F8", float64(-42.65418))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F9", float32(42))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F10", float64(42))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F11", uint(1<<32-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F12", uint8(1<<8-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F13", uint16(1<<16-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F14", uint32(1<<32-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F15", uint64(1<<32-1))) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F16", true)) + assert.NoError(t, xlsx.SetCellValue("Sheet2", "F17", complex64(5+10i))) + + // Test on not exists worksheet. + assert.EqualError(t, xlsx.SetCellDefault("SheetN", "A1", ""), "sheet SheetN is not exist") + assert.EqualError(t, xlsx.SetCellFloat("SheetN", "A1", 42.65418, 2, 32), "sheet SheetN is not exist") + assert.EqualError(t, xlsx.SetCellBool("SheetN", "A1", true), "sheet SheetN is not exist") + assert.EqualError(t, xlsx.SetCellFormula("SheetN", "A1", ""), "sheet SheetN is not exist") + assert.EqualError(t, xlsx.SetCellHyperLink("SheetN", "A1", "Sheet1!A40", "Location"), "sheet SheetN is not exist") // Test boolean write booltest := []struct { @@ -250,6 +257,10 @@ func TestColWidth(t *testing.T) { assert.EqualError(t, xlsx.SetColWidth("Sheet1", "*", "B", 1), `invalid column name "*"`) assert.EqualError(t, xlsx.SetColWidth("Sheet1", "A", "*", 1), `invalid column name "*"`) + // Test get column width on not exists worksheet. + _, err = xlsx.GetColWidth("SheetN", "A") + assert.EqualError(t, err, "sheet SheetN is not exist") + err = xlsx.SaveAs(filepath.Join("test", "TestColWidth.xlsx")) if err != nil { t.Error(err) @@ -288,17 +299,17 @@ func TestGetCellHyperLink(t *testing.T) { t.FailNow() } - link, target, err := xlsx.GetCellHyperLink("Sheet1", "") + _, _, err = xlsx.GetCellHyperLink("Sheet1", "") assert.EqualError(t, err, `invalid cell name ""`) - link, target, err = xlsx.GetCellHyperLink("Sheet1", "A22") + link, target, err := xlsx.GetCellHyperLink("Sheet1", "A22") assert.NoError(t, err) t.Log(link, target) link, target, err = xlsx.GetCellHyperLink("Sheet2", "D6") assert.NoError(t, err) t.Log(link, target) link, target, err = xlsx.GetCellHyperLink("Sheet3", "H3") - assert.EqualError(t, err, "Sheet Sheet3 is not exist") + assert.EqualError(t, err, "sheet Sheet3 is not exist") t.Log(link, target) } @@ -421,12 +432,17 @@ func TestGetMergeCells(t *testing.T) { if !assert.Len(t, mergeCells, len(wants)) { t.FailNow() } + assert.NoError(t, err) for i, m := range mergeCells { assert.Equal(t, wants[i].value, m.GetCellValue()) assert.Equal(t, wants[i].start, m.GetStartAxis()) assert.Equal(t, wants[i].end, m.GetEndAxis()) } + + // Test get merged cells on not exists worksheet. + _, err = xlsx.GetMergeCells("SheetN") + assert.EqualError(t, err, "sheet SheetN is not exist") } func TestSetCellStyleAlignment(t *testing.T) { @@ -779,13 +795,19 @@ func TestColumnVisibility(t *testing.T) { assert.Equal(t, true, visible) assert.NoError(t, err) + // Test get column visiable on not exists worksheet. + _, err = xlsx.GetColVisible("SheetN", "F") + assert.EqualError(t, err, "sheet SheetN is not exist") + // Test get column visiable with illegal cell coordinates. _, err = xlsx.GetColVisible("Sheet1", "*") assert.EqualError(t, err, `invalid column name "*"`) assert.EqualError(t, xlsx.SetColVisible("Sheet1", "*", false), `invalid column name "*"`) - err = xlsx.SetColVisible("Sheet3", "E", false) - assert.EqualError(t, err, "Sheet Sheet3 is not exist") + xlsx.NewSheet("Sheet3") + assert.NoError(t, xlsx.SetColVisible("Sheet3", "E", false)) + + assert.EqualError(t, xlsx.SetColVisible("SheetN", "E", false), "sheet SheetN is not exist") assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestColumnVisibility.xlsx"))) }) @@ -805,7 +827,7 @@ func TestCopySheet(t *testing.T) { } idx := xlsx.NewSheet("CopySheet") - assert.EqualError(t, xlsx.CopySheet(1, idx), "Sheet sheet1 is not exist") + assert.EqualError(t, xlsx.CopySheet(1, idx), "sheet sheet1 is not exist") xlsx.SetCellValue("Sheet4", "F1", "Hello") val, err := xlsx.GetCellValue("Sheet1", "F1") @@ -920,8 +942,8 @@ func TestAutoFilter(t *testing.T) { for i, format := range formats { t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) { - err = xlsx.AutoFilter("Sheet3", "D4", "B1", format) - assert.EqualError(t, err, "Sheet Sheet3 is not exist") + err = xlsx.AutoFilter("Sheet1", "D4", "B1", format) + assert.NoError(t, err) assert.NoError(t, xlsx.SaveAs(fmt.Sprintf(outFile, i+1))) }) } @@ -966,38 +988,42 @@ func TestAddChart(t *testing.T) { 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) + assert.NoError(t, xlsx.SetCellValue("Sheet1", k, v)) } for k, v := range values { - xlsx.SetCellValue("Sheet1", k, v) - } - xlsx.AddChart("Sheet1", "P1", "") - 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"}`) - 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"}`) - xlsx.AddChart("Sheet2", "P16", `{"type":"doughnut","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut Chart"},"plotarea":{"show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`) - xlsx.AddChart("Sheet2", "X16", `{"type":"line","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top","show_legend_key":false},"title":{"name":"Fruit Line Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) - xlsx.AddChart("Sheet2", "P32", `{"type":"pie3D","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`) - xlsx.AddChart("Sheet2", "X32", `{"type":"pie","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"}`) - xlsx.AddChart("Sheet2", "P48", `{"type":"bar","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Clustered Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) - xlsx.AddChart("Sheet2", "X48", `{"type":"barStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) - xlsx.AddChart("Sheet2", "P64", `{"type":"barPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 2D Stacked 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"}`) - xlsx.AddChart("Sheet2", "X64", `{"type":"bar3DClustered","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Clustered Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) - xlsx.AddChart("Sheet2", "P80", `{"type":"bar3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit 3D Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","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}}`) + assert.NoError(t, xlsx.SetCellValue("Sheet1", k, v)) + } + assert.EqualError(t, xlsx.AddChart("Sheet1", "P1", ""), "unexpected end of JSON input") + + // Test add chart on not exists worksheet. + assert.EqualError(t, xlsx.AddChart("SheetN", "P1", "{}"), "sheet SheetN is not exist") + + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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}}`)) + assert.NoError(t, 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}}`)) // 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"}`) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) + assert.NoError(t, 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"}`)) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestAddChart.xlsx"))) } @@ -1042,6 +1068,9 @@ func TestRemoveCol(t *testing.T) { // Test remove column with illegal cell coordinates. assert.EqualError(t, xlsx.RemoveCol("Sheet1", "*"), `invalid column name "*"`) + // Test remove column on not exists worksheet. + assert.EqualError(t, xlsx.RemoveCol("SheetN", "B"), "sheet SheetN is not exist") + assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestRemoveCol.xlsx"))) } @@ -1183,11 +1212,14 @@ func TestOutlineLevel(t *testing.T) { // Test set and get column outline level with illegal cell coordinates. assert.EqualError(t, xlsx.SetColOutlineLevel("Sheet1", "*", 1), `invalid column name "*"`) - level, err := xlsx.GetColOutlineLevel("Sheet1", "*") + _, err := xlsx.GetColOutlineLevel("Sheet1", "*") assert.EqualError(t, err, `invalid column name "*"`) + // Test set column outline level on not exists worksheet. + assert.EqualError(t, xlsx.SetColOutlineLevel("SheetN", "E", 2), "sheet SheetN is not exist") + assert.EqualError(t, xlsx.SetRowOutlineLevel("Sheet1", 0, 1), "invalid row number 0") - level, err = xlsx.GetRowOutlineLevel("Sheet1", 2) + level, err := xlsx.GetRowOutlineLevel("Sheet1", 2) assert.NoError(t, err) assert.Equal(t, uint8(250), level) @@ -1260,6 +1292,8 @@ func TestProtectSheet(t *testing.T) { }) assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestProtectSheet.xlsx"))) + // Test protect not exists worksheet. + assert.EqualError(t, xlsx.ProtectSheet("SheetN", nil), "sheet SheetN is not exist") } func TestUnprotectSheet(t *testing.T) { @@ -1267,11 +1301,19 @@ func TestUnprotectSheet(t *testing.T) { if !assert.NoError(t, err) { t.FailNow() } + // Test unprotect not exists worksheet. + assert.EqualError(t, xlsx.UnprotectSheet("SheetN"), "sheet SheetN is not exist") xlsx.UnprotectSheet("Sheet1") assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestUnprotectSheet.xlsx"))) } +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") +} + func prepareTestBook1() (*File, error) { xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx")) if err != nil { diff --git a/picture_test.go b/picture_test.go index 5b1a9e3..890092e 100644 --- a/picture_test.go +++ b/picture_test.go @@ -97,12 +97,12 @@ func TestGetPicture(t *testing.T) { } // Try to get picture from a worksheet with illegal cell coordinates. - file, raw, err = xlsx.GetPicture("Sheet1", "A") + _, _, err = xlsx.GetPicture("Sheet1", "A") assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`) // Try to get picture from a worksheet that doesn't contain any images. file, raw, err = xlsx.GetPicture("Sheet3", "I9") - assert.EqualError(t, err, "Sheet Sheet3 is not exist") + assert.EqualError(t, err, "sheet Sheet3 is not exist") assert.Empty(t, file) assert.Empty(t, raw) diff --git a/rows_test.go b/rows_test.go index 6a107ad..f7d49b4 100644 --- a/rows_test.go +++ b/rows_test.go @@ -50,7 +50,7 @@ func TestRowsError(t *testing.T) { t.FailNow() } _, err = xlsx.Rows("SheetN") - assert.EqualError(t, err, "Sheet SheetN is not exist") + assert.EqualError(t, err, "sheet SheetN is not exist") } func TestRowHeight(t *testing.T) { @@ -59,11 +59,11 @@ func TestRowHeight(t *testing.T) { assert.EqualError(t, xlsx.SetRowHeight(sheet1, 0, defaultRowHeightPixels+1.0), "invalid row number 0") - height, err := xlsx.GetRowHeight("Sheet1", 0) + _, err := xlsx.GetRowHeight("Sheet1", 0) assert.EqualError(t, err, "invalid row number 0") assert.NoError(t, xlsx.SetRowHeight(sheet1, 1, 111.0)) - height, err = xlsx.GetRowHeight(sheet1, 1) + height, err := xlsx.GetRowHeight(sheet1, 1) assert.NoError(t, err) assert.Equal(t, 111.0, height) @@ -82,6 +82,11 @@ func TestRowHeight(t *testing.T) { assert.NoError(t, err) assert.Equal(t, defaultRowHeightPixels, height) + // Test set and get row height on not exists worksheet. + assert.EqualError(t, xlsx.SetRowHeight("SheetN", 1, 111.0), "sheet SheetN is not exist") + _, err = xlsx.GetRowHeight("SheetN", 3) + assert.EqualError(t, err, "sheet SheetN is not exist") + err = xlsx.SaveAs(filepath.Join("test", "TestRowHeight.xlsx")) if !assert.NoError(t, err) { t.FailNow() @@ -95,9 +100,9 @@ func TestRowVisibility(t *testing.T) { if !assert.NoError(t, err) { t.FailNow() } - - assert.EqualError(t, xlsx.SetRowVisible("Sheet3", 2, false), "Sheet Sheet3 is not exist") - assert.EqualError(t, xlsx.SetRowVisible("Sheet3", 2, true), "Sheet Sheet3 is not exist") + xlsx.NewSheet("Sheet3") + assert.NoError(t, xlsx.SetRowVisible("Sheet3", 2, false)) + assert.NoError(t, xlsx.SetRowVisible("Sheet3", 2, true)) xlsx.GetRowVisible("Sheet3", 2) xlsx.GetRowVisible("Sheet3", 25) assert.EqualError(t, xlsx.SetRowVisible("Sheet3", 0, true), "invalid row number 0") @@ -213,7 +218,7 @@ func TestInsertRowInEmptyFile(t *testing.T) { assert.NoError(t, xlsx.SaveAs(filepath.Join("test", "TestInsertRowInEmptyFile.xlsx"))) } -func TestDuplicateRow(t *testing.T) { +func TestDuplicateRowFromSingleRow(t *testing.T) { const sheet = "Sheet1" outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") @@ -226,15 +231,6 @@ func TestDuplicateRow(t *testing.T) { "B3": "B3 Value", } - newFileWithDefaults := func() *File { - f := NewFile() - for cell, val := range cells { - f.SetCellStr(sheet, cell, val) - - } - return f - } - t.Run("FromSingleRow", func(t *testing.T) { xlsx := NewFile() xlsx.SetCellStr(sheet, "A1", cells["A1"]) @@ -273,6 +269,20 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowUpdateDuplicatedRows(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") + + cells := map[string]string{ + "A1": "A1 Value", + "A2": "A2 Value", + "A3": "A3 Value", + "B1": "B1 Value", + "B2": "B2 Value", + "B3": "B3 Value", + } t.Run("UpdateDuplicatedRows", func(t *testing.T) { xlsx := NewFile() @@ -299,6 +309,29 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowFirstOfMultipleRows(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") + + cells := map[string]string{ + "A1": "A1 Value", + "A2": "A2 Value", + "A3": "A3 Value", + "B1": "B1 Value", + "B2": "B2 Value", + "B3": "B3 Value", + } + + newFileWithDefaults := func() *File { + f := NewFile() + for cell, val := range cells { + f.SetCellStr(sheet, cell, val) + + } + return f + } t.Run("FirstOfMultipleRows", func(t *testing.T) { xlsx := newFileWithDefaults() @@ -322,6 +355,11 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowZeroWithNoRows(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") t.Run("ZeroWithNoRows", func(t *testing.T) { xlsx := NewFile() @@ -359,6 +397,11 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowMiddleRowOfEmptyFile(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") t.Run("MiddleRowOfEmptyFile", func(t *testing.T) { xlsx := NewFile() @@ -381,6 +424,29 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowWithLargeOffsetToMiddleOfData(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") + + cells := map[string]string{ + "A1": "A1 Value", + "A2": "A2 Value", + "A3": "A3 Value", + "B1": "B1 Value", + "B2": "B2 Value", + "B3": "B3 Value", + } + + newFileWithDefaults := func() *File { + f := NewFile() + for cell, val := range cells { + f.SetCellStr(sheet, cell, val) + + } + return f + } t.Run("WithLargeOffsetToMiddleOfData", func(t *testing.T) { xlsx := newFileWithDefaults() @@ -404,6 +470,29 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowWithLargeOffsetToEmptyRows(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") + + cells := map[string]string{ + "A1": "A1 Value", + "A2": "A2 Value", + "A3": "A3 Value", + "B1": "B1 Value", + "B2": "B2 Value", + "B3": "B3 Value", + } + + newFileWithDefaults := func() *File { + f := NewFile() + for cell, val := range cells { + f.SetCellStr(sheet, cell, val) + + } + return f + } t.Run("WithLargeOffsetToEmptyRows", func(t *testing.T) { xlsx := newFileWithDefaults() @@ -427,6 +516,29 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowInsertBefore(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") + + cells := map[string]string{ + "A1": "A1 Value", + "A2": "A2 Value", + "A3": "A3 Value", + "B1": "B1 Value", + "B2": "B2 Value", + "B3": "B3 Value", + } + + newFileWithDefaults := func() *File { + f := NewFile() + for cell, val := range cells { + f.SetCellStr(sheet, cell, val) + + } + return f + } t.Run("InsertBefore", func(t *testing.T) { xlsx := newFileWithDefaults() @@ -451,6 +563,29 @@ func TestDuplicateRow(t *testing.T) { } } }) +} + +func TestDuplicateRowInsertBeforeWithLargeOffset(t *testing.T) { + const sheet = "Sheet1" + outFile := filepath.Join("test", "TestDuplicateRow.%s.xlsx") + + cells := map[string]string{ + "A1": "A1 Value", + "A2": "A2 Value", + "A3": "A3 Value", + "B1": "B1 Value", + "B2": "B2 Value", + "B3": "B3 Value", + } + + newFileWithDefaults := func() *File { + f := NewFile() + for cell, val := range cells { + f.SetCellStr(sheet, cell, val) + + } + return f + } t.Run("InsertBeforeWithLargeOffset", func(t *testing.T) { xlsx := newFileWithDefaults() diff --git a/sheet.go b/sheet.go index f1f89ba..72d8921 100644 --- a/sheet.go +++ b/sheet.go @@ -684,15 +684,16 @@ func (f *File) GetSheetVisible(name string) bool { // result, err := xlsx.SearchSheet("Sheet1", "[0-9]", true) // func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) { - var regSearch bool + var ( + regSearch bool + result []string + inElement string + r xlsxRow + ) for _, r := range reg { regSearch = r } - var ( - result []string - ) - xlsx, err := f.workSheetReader(sheet) if err != nil { return result, err @@ -708,8 +709,7 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) { } xml.NewDecoder(bytes.NewReader(f.readXML(name))) d := f.sharedStringsReader() - var inElement string - var r xlsxRow + decoder := xml.NewDecoder(bytes.NewReader(f.readXML(name))) for { token, _ := decoder.Token() diff --git a/sheet_test.go b/sheet_test.go index 1307dc5..7db982a 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -11,7 +11,6 @@ import ( func ExampleFile_SetPageLayout() { xl := excelize.NewFile() - const sheet = "Sheet1" if err := xl.SetPageLayout( "Sheet1", @@ -30,7 +29,6 @@ func ExampleFile_SetPageLayout() { func ExampleFile_GetPageLayout() { xl := excelize.NewFile() - const sheet = "Sheet1" var ( orientation excelize.PageLayoutOrientation paperSize excelize.PageLayoutPaperSize @@ -73,38 +71,24 @@ func TestPageLayoutOption(t *testing.T) { xl := excelize.NewFile() // Get the default value - if !assert.NoError(t, xl.GetPageLayout(sheet, def), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetPageLayout(sheet, def), opt) // Get again and check - if !assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) if !assert.Equal(t, val1, def, opt) { t.FailNow() } // Set the same value - if !assert.NoError(t, xl.SetPageLayout(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.SetPageLayout(sheet, val1), opt) // Get again and check - if !assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) { t.FailNow() } // Set a different value - if !assert.NoError(t, xl.SetPageLayout(sheet, test.nonDefault), opt) { - t.FailNow() - } - if !assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.SetPageLayout(sheet, test.nonDefault), opt) + assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) // Get again and compare - if !assert.NoError(t, xl.GetPageLayout(sheet, val2), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetPageLayout(sheet, val2), opt) if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) { t.FailNow() } @@ -113,15 +97,23 @@ func TestPageLayoutOption(t *testing.T) { t.FailNow() } // Restore the default value - if !assert.NoError(t, xl.SetPageLayout(sheet, def), opt) { - t.FailNow() - } - if !assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.SetPageLayout(sheet, def), opt) + assert.NoError(t, xl.GetPageLayout(sheet, val1), opt) if !assert.Equal(t, def, val1) { t.FailNow() } }) } } + +func TestSetPageLayout(t *testing.T) { + f := excelize.NewFile() + // Test set page layout on not exists worksheet. + assert.EqualError(t, f.SetPageLayout("SheetN"), "sheet SheetN is not exist") +} + +func TestGetPageLayout(t *testing.T) { + f := excelize.NewFile() + // Test get page layout on not exists worksheet. + assert.EqualError(t, f.GetPageLayout("SheetN"), "sheet SheetN is not exist") +} diff --git a/sheetpr_test.go b/sheetpr_test.go index 22dbd42..48d330e 100644 --- a/sheetpr_test.go +++ b/sheetpr_test.go @@ -112,38 +112,24 @@ func TestSheetPrOptions(t *testing.T) { xl := excelize.NewFile() // Get the default value - if !assert.NoError(t, xl.GetSheetPrOptions(sheet, def), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetSheetPrOptions(sheet, def), opt) // Get again and check - if !assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) if !assert.Equal(t, val1, def, opt) { t.FailNow() } // Set the same value - if !assert.NoError(t, xl.SetSheetPrOptions(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.SetSheetPrOptions(sheet, val1), opt) // Get again and check - if !assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) if !assert.Equal(t, val1, def, "%T: value should not have changed", opt) { t.FailNow() } // Set a different value - if !assert.NoError(t, xl.SetSheetPrOptions(sheet, test.nonDefault), opt) { - t.FailNow() - } - if !assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.SetSheetPrOptions(sheet, test.nonDefault), opt) + assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) // Get again and compare - if !assert.NoError(t, xl.GetSheetPrOptions(sheet, val2), opt) { - t.FailNow() - } + assert.NoError(t, xl.GetSheetPrOptions(sheet, val2), opt) if !assert.Equal(t, val1, val2, "%T: value should not have changed", opt) { t.FailNow() } @@ -152,12 +138,8 @@ func TestSheetPrOptions(t *testing.T) { t.FailNow() } // Restore the default value - if !assert.NoError(t, xl.SetSheetPrOptions(sheet, def), opt) { - t.FailNow() - } - if !assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) { - t.FailNow() - } + assert.NoError(t, xl.SetSheetPrOptions(sheet, def), opt) + assert.NoError(t, xl.GetSheetPrOptions(sheet, val1), opt) if !assert.Equal(t, def, val1) { t.FailNow() } diff --git a/styles_test.go b/styles_test.go index b6f6042..54321bb 100644 --- a/styles_test.go +++ b/styles_test.go @@ -23,8 +23,6 @@ func TestStyleFill(t *testing.T) { for _, testCase := range cases { xl := NewFile() - const sheet = "Sheet1" - styleID, err := xl.NewStyle(testCase.format) if err != nil { t.Fatalf("%v", err)