2019-03-23 16:09:48 +08:00
|
|
|
package excelize
|
|
|
|
|
|
|
|
import (
|
2022-01-23 00:32:34 +08:00
|
|
|
"fmt"
|
2022-05-13 01:03:40 +08:00
|
|
|
"image"
|
2019-06-27 21:58:14 +08:00
|
|
|
_ "image/gif"
|
|
|
|
_ "image/jpeg"
|
2019-03-23 16:09:48 +08:00
|
|
|
_ "image/png"
|
2022-05-13 01:03:40 +08:00
|
|
|
"io"
|
2019-03-23 16:09:48 +08:00
|
|
|
"io/ioutil"
|
2019-03-23 20:08:06 +08:00
|
|
|
"path/filepath"
|
2019-03-24 09:07:57 +08:00
|
|
|
"strings"
|
2019-03-23 16:09:48 +08:00
|
|
|
"testing"
|
2019-03-24 13:08:32 +08:00
|
|
|
|
2022-01-23 00:32:34 +08:00
|
|
|
_ "golang.org/x/image/tiff"
|
|
|
|
|
2019-03-24 13:08:32 +08:00
|
|
|
"github.com/stretchr/testify/assert"
|
2019-03-23 16:09:48 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func BenchmarkAddPictureFromBytes(b *testing.B) {
|
|
|
|
f := NewFile()
|
2019-03-23 20:08:06 +08:00
|
|
|
imgFile, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.png"))
|
2019-03-23 16:09:48 +08:00
|
|
|
if err != nil {
|
2019-03-23 20:08:06 +08:00
|
|
|
b.Error("unable to load image for benchmark")
|
2019-03-23 16:09:48 +08:00
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 1; i <= b.N; i++ {
|
2019-12-24 01:09:28 +08:00
|
|
|
if err := f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", i), "", "excel", ".png", imgFile); err != nil {
|
|
|
|
b.Error(err)
|
|
|
|
}
|
2019-03-23 16:09:48 +08:00
|
|
|
}
|
|
|
|
}
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
func TestAddPicture(t *testing.T) {
|
2019-06-27 21:58:14 +08:00
|
|
|
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
2022-09-06 14:38:09 +08:00
|
|
|
assert.NoError(t, err)
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
// Test add picture to worksheet with offset and location hyperlink.
|
2019-12-24 01:09:28 +08:00
|
|
|
assert.NoError(t, f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
|
|
|
|
`{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`))
|
2019-03-24 13:08:32 +08:00
|
|
|
// Test add picture to worksheet with offset, external hyperlink and positioning.
|
2019-12-24 01:09:28 +08:00
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
|
2021-07-28 00:38:09 +08:00
|
|
|
`{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/xuri/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`))
|
2019-03-24 13:08:32 +08:00
|
|
|
|
2019-06-27 21:58:14 +08:00
|
|
|
file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.png"))
|
2019-12-24 01:09:28 +08:00
|
|
|
assert.NoError(t, err)
|
2019-03-24 13:08:32 +08:00
|
|
|
|
2020-05-17 17:36:53 +08:00
|
|
|
// Test add picture to worksheet with autofit.
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "A30", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`))
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "B30", filepath.Join("test", "images", "excel.jpg"), `{"x_offset": 10, "y_offset": 10, "autofit": true}`))
|
|
|
|
f.NewSheet("AddPicture")
|
|
|
|
assert.NoError(t, f.SetRowHeight("AddPicture", 10, 30))
|
|
|
|
assert.NoError(t, f.MergeCell("AddPicture", "B3", "D9"))
|
2020-12-14 20:56:51 +08:00
|
|
|
assert.NoError(t, f.MergeCell("AddPicture", "B1", "D1"))
|
2020-05-17 17:36:53 +08:00
|
|
|
assert.NoError(t, f.AddPicture("AddPicture", "C6", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`))
|
|
|
|
assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`))
|
|
|
|
|
2019-03-24 13:08:32 +08:00
|
|
|
// Test add picture to worksheet from bytes.
|
2019-06-27 21:58:14 +08:00
|
|
|
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".png", file))
|
2019-03-24 13:08:32 +08:00
|
|
|
// Test add picture to worksheet from bytes with illegal cell coordinates.
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", "", "Excel Logo", ".png", file), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
2019-06-27 21:58:14 +08:00
|
|
|
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q8", filepath.Join("test", "images", "excel.gif"), ""))
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q15", filepath.Join("test", "images", "excel.jpg"), ""))
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q22", filepath.Join("test", "images", "excel.tif"), ""))
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
// Test write file to given path.
|
2022-05-13 01:03:40 +08:00
|
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPicture1.xlsx")))
|
2021-09-18 23:20:24 +08:00
|
|
|
assert.NoError(t, f.Close())
|
2019-03-24 13:08:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddPictureErrors(t *testing.T) {
|
2021-08-15 00:06:40 +08:00
|
|
|
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
2019-12-24 01:09:28 +08:00
|
|
|
assert.NoError(t, err)
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
// Test add picture to worksheet with invalid file path.
|
2022-09-06 14:38:09 +08:00
|
|
|
assert.Error(t, f.AddPicture("Sheet1", "G21", filepath.Join("test", "not_exists_dir", "not_exists.icon"), ""))
|
2019-03-24 13:08:32 +08:00
|
|
|
|
2021-03-30 23:02:22 +08:00
|
|
|
// Test add picture to worksheet with unsupported file type.
|
2022-09-06 14:38:09 +08:00
|
|
|
assert.EqualError(t, f.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), ""), ErrImgExt.Error())
|
|
|
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1)), ErrImgExt.Error())
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
// Test add picture to worksheet with invalid file data.
|
2022-09-06 14:38:09 +08:00
|
|
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", ".jpg", make([]byte, 1)), image.ErrFormat.Error())
|
2022-05-13 01:03:40 +08:00
|
|
|
|
|
|
|
// Test add picture with custom image decoder and encoder.
|
|
|
|
decode := func(r io.Reader) (image.Image, error) { return nil, nil }
|
|
|
|
decodeConfig := func(r io.Reader) (image.Config, error) { return image.Config{Height: 100, Width: 90}, nil }
|
|
|
|
image.RegisterFormat("emf", "", decode, decodeConfig)
|
2022-05-14 00:54:36 +08:00
|
|
|
image.RegisterFormat("wmf", "", decode, decodeConfig)
|
2022-08-21 01:09:32 +08:00
|
|
|
image.RegisterFormat("emz", "", decode, decodeConfig)
|
|
|
|
image.RegisterFormat("wmz", "", decode, decodeConfig)
|
2022-05-13 01:03:40 +08:00
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q1", filepath.Join("test", "images", "excel.emf"), ""))
|
2022-05-14 00:54:36 +08:00
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q7", filepath.Join("test", "images", "excel.wmf"), ""))
|
2022-08-21 01:09:32 +08:00
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q13", filepath.Join("test", "images", "excel.emz"), ""))
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "Q19", filepath.Join("test", "images", "excel.wmz"), ""))
|
2022-05-13 01:03:40 +08:00
|
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPicture2.xlsx")))
|
2021-09-18 23:20:24 +08:00
|
|
|
assert.NoError(t, f.Close())
|
2019-03-24 13:08:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetPicture(t *testing.T) {
|
2022-09-06 14:38:09 +08:00
|
|
|
f := NewFile()
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.png"), ""))
|
|
|
|
name, content, err := f.GetPicture("Sheet1", "A1")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 13233, len(content))
|
|
|
|
assert.Equal(t, "image1.png", name)
|
|
|
|
|
|
|
|
f, err = prepareTestBook1()
|
2019-03-24 13:08:32 +08:00
|
|
|
if !assert.NoError(t, err) {
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
2019-12-22 00:02:09 +08:00
|
|
|
file, raw, err := f.GetPicture("Sheet1", "F21")
|
2019-03-24 13:08:32 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
|
2022-03-19 00:05:47 +08:00
|
|
|
!assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0o644)) {
|
2019-03-24 13:08:32 +08:00
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to get picture from a worksheet with illegal cell coordinates.
|
2019-12-22 00:02:09 +08:00
|
|
|
_, _, err = f.GetPicture("Sheet1", "A")
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
// Try to get picture from a worksheet that doesn't contain any images.
|
2019-12-22 00:02:09 +08:00
|
|
|
file, raw, err = f.GetPicture("Sheet3", "I9")
|
2022-08-28 00:16:41 +08:00
|
|
|
assert.EqualError(t, err, "sheet Sheet3 does not exist")
|
2019-03-24 13:08:32 +08:00
|
|
|
assert.Empty(t, file)
|
|
|
|
assert.Empty(t, raw)
|
|
|
|
|
|
|
|
// Try to get picture from a cell that doesn't contain an image.
|
2019-12-22 00:02:09 +08:00
|
|
|
file, raw, err = f.GetPicture("Sheet2", "A2")
|
2019-03-24 13:08:32 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Empty(t, file)
|
|
|
|
assert.Empty(t, raw)
|
|
|
|
|
2019-12-22 00:02:09 +08:00
|
|
|
f.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
|
|
|
|
f.getDrawingRelationships("", "")
|
|
|
|
f.getSheetRelationshipsTargetByID("", "")
|
|
|
|
f.deleteSheetRelationships("", "")
|
2019-03-24 13:08:32 +08:00
|
|
|
|
|
|
|
// Try to get picture from a local storage file.
|
2019-12-24 01:09:28 +08:00
|
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestGetPicture.xlsx")))
|
2019-03-24 13:08:32 +08:00
|
|
|
|
2019-12-22 00:02:09 +08:00
|
|
|
f, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
|
2019-12-24 01:09:28 +08:00
|
|
|
assert.NoError(t, err)
|
2019-03-24 13:08:32 +08:00
|
|
|
|
2019-12-22 00:02:09 +08:00
|
|
|
file, raw, err = f.GetPicture("Sheet1", "F21")
|
2019-03-24 13:08:32 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
|
2022-03-19 00:05:47 +08:00
|
|
|
!assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0o644)) {
|
2019-03-24 13:08:32 +08:00
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to get picture from a local storage file that doesn't contain an image.
|
2019-12-22 00:02:09 +08:00
|
|
|
file, raw, err = f.GetPicture("Sheet1", "F22")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Empty(t, file)
|
|
|
|
assert.Empty(t, raw)
|
2021-09-18 23:20:24 +08:00
|
|
|
assert.NoError(t, f.Close())
|
2019-12-22 00:02:09 +08:00
|
|
|
|
|
|
|
// Test get picture from none drawing worksheet.
|
|
|
|
f = NewFile()
|
|
|
|
file, raw, err = f.GetPicture("Sheet1", "F22")
|
2019-03-24 13:08:32 +08:00
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Empty(t, file)
|
|
|
|
assert.Empty(t, raw)
|
2020-07-11 02:31:02 +08:00
|
|
|
f, err = prepareTestBook1()
|
|
|
|
assert.NoError(t, err)
|
2021-07-05 00:03:56 +08:00
|
|
|
f.Pkg.Store("xl/drawings/drawing1.xml", MacintoshCyrillicCharset)
|
2020-07-11 02:31:02 +08:00
|
|
|
_, _, err = f.getPicture(20, 5, "xl/drawings/drawing1.xml", "xl/drawings/_rels/drawing2.xml.rels")
|
|
|
|
assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
|
2019-03-24 13:08:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddDrawingPicture(t *testing.T) {
|
2022-07-16 12:50:13 +08:00
|
|
|
// Test addDrawingPicture with illegal cell coordinates.
|
2019-03-24 13:08:32 +08:00
|
|
|
f := NewFile()
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", 0, 0, 0, 0, nil), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
2019-03-24 13:08:32 +08:00
|
|
|
}
|
2019-03-24 09:07:57 +08:00
|
|
|
|
|
|
|
func TestAddPictureFromBytes(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
imgFile, err := ioutil.ReadFile("logo.png")
|
2019-12-22 00:02:09 +08:00
|
|
|
assert.NoError(t, err, "Unable to load logo for test")
|
|
|
|
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "", "logo", ".png", imgFile))
|
|
|
|
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile))
|
2019-03-24 09:07:57 +08:00
|
|
|
imageCount := 0
|
2021-07-05 00:03:56 +08:00
|
|
|
f.Pkg.Range(func(fileName, v interface{}) bool {
|
|
|
|
if strings.Contains(fileName.(string), "media/image") {
|
2019-03-24 09:07:57 +08:00
|
|
|
imageCount++
|
|
|
|
}
|
2021-07-05 00:03:56 +08:00
|
|
|
return true
|
|
|
|
})
|
2019-03-24 09:07:57 +08:00
|
|
|
assert.Equal(t, 1, imageCount, "Duplicate image should only be stored once.")
|
2022-08-28 00:16:41 +08:00
|
|
|
assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), "", "logo", ".png", imgFile), "sheet SheetN does not exist")
|
2019-03-24 09:07:57 +08:00
|
|
|
}
|
2020-01-22 01:08:18 +08:00
|
|
|
|
|
|
|
func TestDeletePicture(t *testing.T) {
|
|
|
|
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.NoError(t, f.DeletePicture("Sheet1", "A1"))
|
|
|
|
assert.NoError(t, f.AddPicture("Sheet1", "P1", filepath.Join("test", "images", "excel.jpg"), ""))
|
|
|
|
assert.NoError(t, f.DeletePicture("Sheet1", "P1"))
|
|
|
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestDeletePicture.xlsx")))
|
|
|
|
// Test delete picture on not exists worksheet.
|
2022-08-28 00:16:41 +08:00
|
|
|
assert.EqualError(t, f.DeletePicture("SheetN", "A1"), "sheet SheetN does not exist")
|
2020-01-22 01:08:18 +08:00
|
|
|
// Test delete picture with invalid coordinates.
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, f.DeletePicture("Sheet1", ""), newCellNameToCoordinatesError("", newInvalidCellNameError("")).Error())
|
2021-09-18 23:20:24 +08:00
|
|
|
assert.NoError(t, f.Close())
|
2020-01-22 01:08:18 +08:00
|
|
|
// Test delete picture on no chart worksheet.
|
|
|
|
assert.NoError(t, NewFile().DeletePicture("Sheet1", "A1"))
|
|
|
|
}
|
2020-05-17 17:36:53 +08:00
|
|
|
|
|
|
|
func TestDrawingResize(t *testing.T) {
|
|
|
|
f := NewFile()
|
|
|
|
// Test calculate drawing resize on not exists worksheet.
|
|
|
|
_, _, _, _, err := f.drawingResize("SheetN", "A1", 1, 1, nil)
|
2022-08-28 00:16:41 +08:00
|
|
|
assert.EqualError(t, err, "sheet SheetN does not exist")
|
2020-05-17 17:36:53 +08:00
|
|
|
// Test calculate drawing resize with invalid coordinates.
|
|
|
|
_, _, _, _, err = f.drawingResize("Sheet1", "", 1, 1, nil)
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, err, newCellNameToCoordinatesError("", newInvalidCellNameError("")).Error())
|
2021-07-05 00:03:56 +08:00
|
|
|
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
|
|
|
|
assert.True(t, ok)
|
|
|
|
ws.(*xlsxWorksheet).MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
|
2021-12-07 00:26:53 +08:00
|
|
|
assert.EqualError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
2020-05-17 17:36:53 +08:00
|
|
|
}
|