From 422fd125020d1d90c96861e5545d0c62d811b504 Mon Sep 17 00:00:00 2001 From: "houjianxin.rupert" Date: Mon, 28 Nov 2022 16:49:00 +0800 Subject: [PATCH 1/4] This closes #1405, add new function SetSheetBackgroundFromBytes used for setting background image by given image data Change-Id: I83baac1107f66dfa5d9d2eebfa7e40f9f49b79d5 --- picture.go | 154 ++++++++++++++++++++++++++++++++++++++++ sheet.go | 20 +++++- sheet_test.go | 20 ++++++ test/EmptyWorkbook.xlsx | Bin 0 -> 8476 bytes xmlDrawing.go | 13 ++++ 5 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 test/EmptyWorkbook.xlsx diff --git a/picture.go b/picture.go index 4e8a652a25..03bc1bfe3a 100644 --- a/picture.go +++ b/picture.go @@ -13,10 +13,12 @@ package excelize import ( "bytes" + "compress/gzip" "encoding/json" "encoding/xml" "image" "io" + "io/ioutil" "os" "path" "path/filepath" @@ -721,3 +723,155 @@ func (f *File) drawingResize(sheet, cell string, width, height float64, opts *pi w, h = int(width*opts.XScale), int(height*opts.YScale) return } + +// getImageDataFormat provides a function to query format of image data +// by given data. +func getImageDataFormat(data []byte) string { + if len(data) == 0 { + return "" + } + for ext, cmpFunc := range supportedImageHeaderFormat { + if cmpFunc(data) { + return ext + } + } + return "" +} + +// isGIF provides a function to determine whether the format of given image data is gif +func isGIF(data []byte) bool { + pattern := []byte{0x47, 0x49, 0x46, 0x38} + if len(data) < len(pattern) { + return false + } + return bytes.Equal(data[0:len(pattern)], pattern) +} + +func isJPEG(data []byte) bool { + pattern := []byte{0xFF, 0xD8, 0xFF} + if len(data) < len(pattern) { + return false + } + return bytes.Equal(data[0:len(pattern)], pattern) +} + +// isPNG provides a function to determine whether the format of given image data is png +func isPNG(data []byte) bool { + pattern := []byte{0x89, 0x50, 0x4E} + if len(data) < len(pattern) { + return false + } + return bytes.Equal(data[0:len(pattern)], pattern) +} + +// isTIFF provides a function to determine whether the format of given image data is tiff +func isTIFF(data []byte) bool { + patterns := [][]byte{ + {0x4D, 0x4D}, + {0x49, 0x49}, + } + for _, pattern := range patterns { + if len(data) < len(pattern) { + continue + } + if bytes.Equal(data[0:len(pattern)], pattern) { + return true + } + } + return false +} + +// isEMF provides a function to determine whether the format of given image data is emf +func isEMF(data []byte) bool { + patterns := [][]byte{ + {0x01, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00}, + {0x01, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00}, + } + for _, pattern := range patterns { + if len(data) < len(pattern) { + continue + } + if bytes.Equal(data[0:len(pattern)], pattern) { + return true + } + } + return false +} + +// isWMF provides a function to determine whether the format of given image data is wmf +func isWMF(data []byte) bool { + patterns := [][]byte{ + {0x01, 0x00, 0x09, 0x00}, + {0x02, 0x00, 0x09, 0x00}, + {0xD7, 0xCD, 0xC6, 0x9A}, + } + for _, pattern := range patterns { + if len(data) < len(pattern) { + continue + } + if bytes.Equal(data[0:len(pattern)], pattern) { + return true + } + } + return false +} + +// isEMZ provides a function to determine whether the format of given image data is emz +func isEMZ(data []byte) bool { + pattern := []byte{0x1F, 0x8B} + if len(data) < len(pattern) { + return false + } + isEqual := bytes.Equal(data[0:len(pattern)], pattern) + if !isEqual { + return false + } + b := bytes.NewBuffer(data) + reader, err := gzip.NewReader(b) + if err != nil { + return false + } + res, err := ioutil.ReadAll(reader) + if err != nil { + return false + } + return isEMF(res) +} + +// isWMZ provides a function to determine whether the format of given image data is wmz +func isWMZ(data []byte) bool { + pattern := []byte{0x1F, 0x8B} + if len(data) < len(pattern) { + return false + } + isEqual := bytes.Equal(data[0:len(pattern)], pattern) + if !isEqual { + return false + } + b := bytes.NewBuffer(data) + reader, err := gzip.NewReader(b) + if err != nil { + return false + } + res, err := ioutil.ReadAll(reader) + if err != nil { + return false + } + return isWMF(res) +} + +// isSVG provides a function to determine whether the format of given image data is svg +func isSVG(data []byte) bool { + type Result struct { + XMLName xml.Name `xml:"svg"` + } + var res Result + err := xml.Unmarshal(data, &res) + if err != nil { + return false + } + if res.XMLName.Local == "svg" { + return true + } + return false +} diff --git a/sheet.go b/sheet.go index 3ac933bc21..c569315552 100644 --- a/sheet.go +++ b/sheet.go @@ -497,11 +497,27 @@ func (f *File) SetSheetBackground(sheet, picture string) error { return ErrImgExt } file, _ := os.ReadFile(filepath.Clean(picture)) - name := f.addMedia(file, ext) + return f.setSheetBackground(sheet, ext, file) +} + +// SetSheetBackgroundFromBytes provides a function to set background picture +// by given worksheet name and image data +func (f *File) SetSheetBackgroundFromBytes(sheet string, picture []byte) error { + ext, ok := supportedImageTypes[getImageDataFormat(picture)] + if !ok { + return ErrImgExt + } + return f.setSheetBackground(sheet, ext, picture) +} + +// setSheetBackground provides a function to set background picture by given +// worksheet name, file name extension and image data. +func (f *File) setSheetBackground(sheet, ext string, imageData []byte) error { + name := f.addMedia(imageData, ext) sheetXMLPath, _ := f.getSheetXMLPath(sheet) sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetXMLPath, "xl/worksheets/") + ".rels" rID := f.addRels(sheetRels, SourceRelationshipImage, strings.Replace(name, "xl", "..", 1), "") - if err = f.addSheetPicture(sheet, rID); err != nil { + if err := f.addSheetPicture(sheet, rID); err != nil { return err } f.addSheetNameSpace(sheet, SourceRelationship) diff --git a/sheet_test.go b/sheet_test.go index 08c7c1a9ea..8d7b53dfc6 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -3,6 +3,8 @@ package excelize import ( "encoding/xml" "fmt" + "io/ioutil" + "os" "path/filepath" "strconv" "strings" @@ -463,3 +465,21 @@ func TestAttrValToFloat(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 42.1, got) } + +func TestSetSheetBackgroundFromBytes(t *testing.T) { + files := []string{"../../excelize.svg", "excel.emf", "excel.emz", "excel.gif", "excel.jpg", "excel.png", "excel.tif", "excel.wmf", "excel.wmz"} + f, err := OpenFile("./test/EmptyWorkbook.xlsx") + assert.NoError(t, err) + for i, file := range files { + img, err := os.Open(filepath.Join("test/images", file)) + assert.NoError(t, err) + content, err := ioutil.ReadAll(img) + assert.NoError(t, err) + assert.NoError(t, img.Close()) + assert.NoError(t, f.SetSheetBackgroundFromBytes("sheet1", content)) + assert.NoError(t, f.SaveAs(fmt.Sprintf("test/TestSetSheetBackgroundFromBytes%d.xlsx", i))) + } + assert.Error(t, f.SetSheetBackgroundFromBytes("sheet1", nil), ErrImgExt) + assert.Error(t, f.SetSheetBackgroundFromBytes("sheet1", []byte{123, 243, 235, 34, 6, 56, 134, 87, 36, 255, 23, 52}), ErrImgExt) + assert.NoError(t, f.Close()) +} diff --git a/test/EmptyWorkbook.xlsx b/test/EmptyWorkbook.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a4810cd824537c0401ad3d83ba0e0edf005e0e9d GIT binary patch literal 8476 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 J8l?Go_kV&6mNNhV literal 0 HcmV?d00001 diff --git a/xmlDrawing.go b/xmlDrawing.go index 56ddc0e780..83435ccc21 100644 --- a/xmlDrawing.go +++ b/xmlDrawing.go @@ -171,6 +171,19 @@ var supportedImageTypes = map[string]string{ ".tiff": ".tiff", ".wmf": ".wmf", ".wmz": ".wmz", } +// supportedImageHeaderFormat defined supported image data format. +var supportedImageHeaderFormat = map[string]func([]byte) bool{ + ".gif": isGIF, + ".jpeg": isJPEG, + ".png": isPNG, + ".tiff": isTIFF, + ".emf": isEMF, + ".wmf": isWMF, + ".emz": isEMZ, + ".wmz": isWMZ, + ".svg": isSVG, +} + // supportedContentTypes defined supported file format types. var supportedContentTypes = map[string]string{ ".xlam": ContentTypeAddinMacro, From 1f71610b1a9942019c6bef4949e4faa56d30078b Mon Sep 17 00:00:00 2001 From: "houjianxin.rupert" Date: Tue, 29 Nov 2022 11:08:59 +0800 Subject: [PATCH 2/4] remove ioutil and add a new test/EmptyWorkbook.xlsx Change-Id: I04479f92c559e4bbfa5e81d5698389122c90743c --- picture.go | 5 ++--- sheet_test.go | 4 ++-- test/EmptyWorkbook.xlsx | Bin 8476 -> 8454 bytes 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/picture.go b/picture.go index 03bc1bfe3a..8e298c847c 100644 --- a/picture.go +++ b/picture.go @@ -18,7 +18,6 @@ import ( "encoding/xml" "image" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -831,7 +830,7 @@ func isEMZ(data []byte) bool { if err != nil { return false } - res, err := ioutil.ReadAll(reader) + res, err := io.ReadAll(reader) if err != nil { return false } @@ -853,7 +852,7 @@ func isWMZ(data []byte) bool { if err != nil { return false } - res, err := ioutil.ReadAll(reader) + res, err := io.ReadAll(reader) if err != nil { return false } diff --git a/sheet_test.go b/sheet_test.go index 8d7b53dfc6..ee6d84921c 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -3,7 +3,7 @@ package excelize import ( "encoding/xml" "fmt" - "io/ioutil" + "io" "os" "path/filepath" "strconv" @@ -473,7 +473,7 @@ func TestSetSheetBackgroundFromBytes(t *testing.T) { for i, file := range files { img, err := os.Open(filepath.Join("test/images", file)) assert.NoError(t, err) - content, err := ioutil.ReadAll(img) + content, err := io.ReadAll(img) assert.NoError(t, err) assert.NoError(t, img.Close()) assert.NoError(t, f.SetSheetBackgroundFromBytes("sheet1", content)) diff --git a/test/EmptyWorkbook.xlsx b/test/EmptyWorkbook.xlsx index a4810cd824537c0401ad3d83ba0e0edf005e0e9d..fa454788bc7a23f540663387511471e1d5cffbdf 100644 GIT binary patch delta 1805 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 Date: Wed, 30 Nov 2022 11:43:05 +0800 Subject: [PATCH 3/4] Remove the logic to identify the image data type Change-Id: If259d00c12f2b30ebd8dba20845ddf92dc9bc717 --- picture.go | 153 ---------------------------------------- sheet.go | 9 ++- sheet_test.go | 27 ++++--- test/EmptyWorkbook.xlsx | Bin 8454 -> 0 bytes xmlDrawing.go | 13 ---- 5 files changed, 24 insertions(+), 178 deletions(-) delete mode 100644 test/EmptyWorkbook.xlsx diff --git a/picture.go b/picture.go index 8e298c847c..4e8a652a25 100644 --- a/picture.go +++ b/picture.go @@ -13,7 +13,6 @@ package excelize import ( "bytes" - "compress/gzip" "encoding/json" "encoding/xml" "image" @@ -722,155 +721,3 @@ func (f *File) drawingResize(sheet, cell string, width, height float64, opts *pi w, h = int(width*opts.XScale), int(height*opts.YScale) return } - -// getImageDataFormat provides a function to query format of image data -// by given data. -func getImageDataFormat(data []byte) string { - if len(data) == 0 { - return "" - } - for ext, cmpFunc := range supportedImageHeaderFormat { - if cmpFunc(data) { - return ext - } - } - return "" -} - -// isGIF provides a function to determine whether the format of given image data is gif -func isGIF(data []byte) bool { - pattern := []byte{0x47, 0x49, 0x46, 0x38} - if len(data) < len(pattern) { - return false - } - return bytes.Equal(data[0:len(pattern)], pattern) -} - -func isJPEG(data []byte) bool { - pattern := []byte{0xFF, 0xD8, 0xFF} - if len(data) < len(pattern) { - return false - } - return bytes.Equal(data[0:len(pattern)], pattern) -} - -// isPNG provides a function to determine whether the format of given image data is png -func isPNG(data []byte) bool { - pattern := []byte{0x89, 0x50, 0x4E} - if len(data) < len(pattern) { - return false - } - return bytes.Equal(data[0:len(pattern)], pattern) -} - -// isTIFF provides a function to determine whether the format of given image data is tiff -func isTIFF(data []byte) bool { - patterns := [][]byte{ - {0x4D, 0x4D}, - {0x49, 0x49}, - } - for _, pattern := range patterns { - if len(data) < len(pattern) { - continue - } - if bytes.Equal(data[0:len(pattern)], pattern) { - return true - } - } - return false -} - -// isEMF provides a function to determine whether the format of given image data is emf -func isEMF(data []byte) bool { - patterns := [][]byte{ - {0x01, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00}, - {0x01, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00}, - } - for _, pattern := range patterns { - if len(data) < len(pattern) { - continue - } - if bytes.Equal(data[0:len(pattern)], pattern) { - return true - } - } - return false -} - -// isWMF provides a function to determine whether the format of given image data is wmf -func isWMF(data []byte) bool { - patterns := [][]byte{ - {0x01, 0x00, 0x09, 0x00}, - {0x02, 0x00, 0x09, 0x00}, - {0xD7, 0xCD, 0xC6, 0x9A}, - } - for _, pattern := range patterns { - if len(data) < len(pattern) { - continue - } - if bytes.Equal(data[0:len(pattern)], pattern) { - return true - } - } - return false -} - -// isEMZ provides a function to determine whether the format of given image data is emz -func isEMZ(data []byte) bool { - pattern := []byte{0x1F, 0x8B} - if len(data) < len(pattern) { - return false - } - isEqual := bytes.Equal(data[0:len(pattern)], pattern) - if !isEqual { - return false - } - b := bytes.NewBuffer(data) - reader, err := gzip.NewReader(b) - if err != nil { - return false - } - res, err := io.ReadAll(reader) - if err != nil { - return false - } - return isEMF(res) -} - -// isWMZ provides a function to determine whether the format of given image data is wmz -func isWMZ(data []byte) bool { - pattern := []byte{0x1F, 0x8B} - if len(data) < len(pattern) { - return false - } - isEqual := bytes.Equal(data[0:len(pattern)], pattern) - if !isEqual { - return false - } - b := bytes.NewBuffer(data) - reader, err := gzip.NewReader(b) - if err != nil { - return false - } - res, err := io.ReadAll(reader) - if err != nil { - return false - } - return isWMF(res) -} - -// isSVG provides a function to determine whether the format of given image data is svg -func isSVG(data []byte) bool { - type Result struct { - XMLName xml.Name `xml:"svg"` - } - var res Result - err := xml.Unmarshal(data, &res) - if err != nil { - return false - } - if res.XMLName.Local == "svg" { - return true - } - return false -} diff --git a/sheet.go b/sheet.go index c569315552..2b3ce1f44a 100644 --- a/sheet.go +++ b/sheet.go @@ -501,9 +501,12 @@ func (f *File) SetSheetBackground(sheet, picture string) error { } // SetSheetBackgroundFromBytes provides a function to set background picture -// by given worksheet name and image data -func (f *File) SetSheetBackgroundFromBytes(sheet string, picture []byte) error { - ext, ok := supportedImageTypes[getImageDataFormat(picture)] +// by given worksheet name, extension name and image data +func (f *File) SetSheetBackgroundFromBytes(sheet, extension string, picture []byte) error { + if len(picture) == 0 { + return ErrImgExt + } + ext, ok := supportedImageTypes[extension] if !ok { return ErrImgExt } diff --git a/sheet_test.go b/sheet_test.go index ee6d84921c..b6e267a932 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -467,19 +467,28 @@ func TestAttrValToFloat(t *testing.T) { } func TestSetSheetBackgroundFromBytes(t *testing.T) { - files := []string{"../../excelize.svg", "excel.emf", "excel.emz", "excel.gif", "excel.jpg", "excel.png", "excel.tif", "excel.wmf", "excel.wmz"} - f, err := OpenFile("./test/EmptyWorkbook.xlsx") - assert.NoError(t, err) - for i, file := range files { - img, err := os.Open(filepath.Join("test/images", file)) + files := map[string]string{ + "excelize.svg": ".svg", + "test/images/excel.emf": ".emf", + "test/images/excel.emz": ".emz", + "test/images/excel.gif": ".gif", + "test/images/excel.jpg": ".jpg", + "test/images/excel.png": ".png", + "test/images/excel.tif": ".tif", + "test/images/excel.wmf": ".wmf", + "test/images/excel.wmz": ".wmz", + } + f := NewFile() + index := f.NewSheet("sheet1") + assert.Equal(t, index, 0) + for name, ext := range files { + img, err := os.Open(name) assert.NoError(t, err) content, err := io.ReadAll(img) assert.NoError(t, err) assert.NoError(t, img.Close()) - assert.NoError(t, f.SetSheetBackgroundFromBytes("sheet1", content)) - assert.NoError(t, f.SaveAs(fmt.Sprintf("test/TestSetSheetBackgroundFromBytes%d.xlsx", i))) + assert.NoError(t, f.SetSheetBackgroundFromBytes("sheet1", ext, content)) + assert.NoError(t, f.SaveAs(fmt.Sprintf("test/TestSetSheetBackgroundFromBytes%s.xlsx", strings.ToUpper(ext[1:])))) } - assert.Error(t, f.SetSheetBackgroundFromBytes("sheet1", nil), ErrImgExt) - assert.Error(t, f.SetSheetBackgroundFromBytes("sheet1", []byte{123, 243, 235, 34, 6, 56, 134, 87, 36, 255, 23, 52}), ErrImgExt) assert.NoError(t, f.Close()) } diff --git a/test/EmptyWorkbook.xlsx b/test/EmptyWorkbook.xlsx deleted file mode 100644 index fa454788bc7a23f540663387511471e1d5cffbdf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8454 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 diff --git a/xmlDrawing.go b/xmlDrawing.go index 83435ccc21..56ddc0e780 100644 --- a/xmlDrawing.go +++ b/xmlDrawing.go @@ -171,19 +171,6 @@ var supportedImageTypes = map[string]string{ ".tiff": ".tiff", ".wmf": ".wmf", ".wmz": ".wmz", } -// supportedImageHeaderFormat defined supported image data format. -var supportedImageHeaderFormat = map[string]func([]byte) bool{ - ".gif": isGIF, - ".jpeg": isJPEG, - ".png": isPNG, - ".tiff": isTIFF, - ".emf": isEMF, - ".wmf": isWMF, - ".emz": isEMZ, - ".wmz": isWMZ, - ".svg": isSVG, -} - // supportedContentTypes defined supported file format types. var supportedContentTypes = map[string]string{ ".xlam": ContentTypeAddinMacro, From 85d8a88dc114aa2fdfa19958ed2067a33847776b Mon Sep 17 00:00:00 2001 From: xuri Date: Thu, 1 Dec 2022 10:06:29 +0800 Subject: [PATCH 4/4] This fix code review issue and update the documentation --- picture.go | 7 +++++-- sheet.go | 32 +++++++++++++++----------------- sheet_test.go | 29 ++++++++++++----------------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/picture.go b/picture.go index 4e8a652a25..002eb04696 100644 --- a/picture.go +++ b/picture.go @@ -38,7 +38,8 @@ func parsePictureOptions(opts string) (*pictureOptions, error) { // AddPicture provides the method to add picture in a sheet by given picture // format set (such as offset, scale, aspect ratio setting and print settings) -// and file path. This function is concurrency safe. For example: +// and file path, supported image types: EMF, EMZ, GIF, JPEG, JPG, PNG, SVG, +// TIF, TIFF, WMF, and WMZ. This function is concurrency safe. For example: // // package main // @@ -121,7 +122,9 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error { // AddPictureFromBytes provides the method to add picture in a sheet by given // picture format set (such as offset, scale, aspect ratio setting and print -// settings), file base name, extension name and file bytes. For example: +// settings), file base name, extension name and file bytes, supported image +// types: EMF, EMZ, GIF, JPEG, JPG, PNG, SVG, TIF, TIFF, WMF, and WMZ. For +// example: // // package main // diff --git a/sheet.go b/sheet.go index 2b3ce1f44a..c301df286f 100644 --- a/sheet.go +++ b/sheet.go @@ -485,38 +485,36 @@ func (f *File) getSheetXMLPath(sheet string) (string, bool) { } // SetSheetBackground provides a function to set background picture by given -// worksheet name and file path. +// worksheet name and file path. Supported image types: EMF, EMZ, GIF, JPEG, +// JPG, PNG, SVG, TIF, TIFF, WMF, and WMZ. func (f *File) SetSheetBackground(sheet, picture string) error { var err error // Check picture exists first. if _, err = os.Stat(picture); os.IsNotExist(err) { return err } - ext, ok := supportedImageTypes[path.Ext(picture)] - if !ok { - return ErrImgExt - } file, _ := os.ReadFile(filepath.Clean(picture)) - return f.setSheetBackground(sheet, ext, file) + return f.setSheetBackground(sheet, path.Ext(picture), file) } -// SetSheetBackgroundFromBytes provides a function to set background picture -// by given worksheet name, extension name and image data +// SetSheetBackgroundFromBytes provides a function to set background picture by +// given worksheet name, extension name and image data. Supported image types: +// EMF, EMZ, GIF, JPEG, JPG, PNG, SVG, TIF, TIFF, WMF, and WMZ. func (f *File) SetSheetBackgroundFromBytes(sheet, extension string, picture []byte) error { if len(picture) == 0 { - return ErrImgExt - } - ext, ok := supportedImageTypes[extension] - if !ok { - return ErrImgExt + return ErrParameterInvalid } - return f.setSheetBackground(sheet, ext, picture) + return f.setSheetBackground(sheet, extension, picture) } // setSheetBackground provides a function to set background picture by given -// worksheet name, file name extension and image data. -func (f *File) setSheetBackground(sheet, ext string, imageData []byte) error { - name := f.addMedia(imageData, ext) +// worksheet name, file name extension and image data. +func (f *File) setSheetBackground(sheet, extension string, file []byte) error { + imageType, ok := supportedImageTypes[extension] + if !ok { + return ErrImgExt + } + name := f.addMedia(file, imageType) sheetXMLPath, _ := f.getSheetXMLPath(sheet) sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetXMLPath, "xl/worksheets/") + ".rels" rID := f.addRels(sheetRels, SourceRelationshipImage, strings.Replace(name, "xl", "..", 1), "") diff --git a/sheet_test.go b/sheet_test.go index b6e267a932..2494cfba1c 100644 --- a/sheet_test.go +++ b/sheet_test.go @@ -467,28 +467,23 @@ func TestAttrValToFloat(t *testing.T) { } func TestSetSheetBackgroundFromBytes(t *testing.T) { - files := map[string]string{ - "excelize.svg": ".svg", - "test/images/excel.emf": ".emf", - "test/images/excel.emz": ".emz", - "test/images/excel.gif": ".gif", - "test/images/excel.jpg": ".jpg", - "test/images/excel.png": ".png", - "test/images/excel.tif": ".tif", - "test/images/excel.wmf": ".wmf", - "test/images/excel.wmz": ".wmz", - } f := NewFile() - index := f.NewSheet("sheet1") - assert.Equal(t, index, 0) - for name, ext := range files { - img, err := os.Open(name) + f.SetSheetName("Sheet1", ".svg") + for i, imageTypes := range []string{".svg", ".emf", ".emz", ".gif", ".jpg", ".png", ".tif", ".wmf", ".wmz"} { + file := fmt.Sprintf("excelize%s", imageTypes) + if i > 0 { + file = filepath.Join("test", "images", fmt.Sprintf("excel%s", imageTypes)) + f.NewSheet(imageTypes) + } + img, err := os.Open(file) assert.NoError(t, err) content, err := io.ReadAll(img) assert.NoError(t, err) assert.NoError(t, img.Close()) - assert.NoError(t, f.SetSheetBackgroundFromBytes("sheet1", ext, content)) - assert.NoError(t, f.SaveAs(fmt.Sprintf("test/TestSetSheetBackgroundFromBytes%s.xlsx", strings.ToUpper(ext[1:])))) + assert.NoError(t, f.SetSheetBackgroundFromBytes(imageTypes, imageTypes, content)) } + assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetSheetBackgroundFromBytes.xlsx"))) assert.NoError(t, f.Close()) + + assert.EqualError(t, f.SetSheetBackgroundFromBytes("Sheet1", ".svg", nil), ErrParameterInvalid.Error()) }