forked from p30928647/excelize
Breaking changes: changed the function signature for 2 exported functions
- Change `func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []byte, opts *GraphicOptions) error` to `func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error` - Change `func (f *File) GetPicture(sheet, cell string) (string, []byte, error)` to `func (f *File) GetPictures(sheet, cell string) ([]Picture, error)` Co-authored-by: huangsk <645636204@qq.com>
This commit is contained in:
parent
7631fd08e1
commit
478b528af1
|
@ -52,9 +52,8 @@ func TestConcurrency(t *testing.T) {
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
// Concurrency get cell picture
|
// Concurrency get cell picture
|
||||||
name, raw, err := f.GetPicture("Sheet1", "A1")
|
pics, err := f.GetPictures("Sheet1", "A1")
|
||||||
assert.Equal(t, "", name)
|
assert.Len(t, pics, 0)
|
||||||
assert.Nil(t, raw)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Concurrency iterate rows
|
// Concurrency iterate rows
|
||||||
rows, err := f.Rows("Sheet1")
|
rows, err := f.Rows("Sheet1")
|
||||||
|
|
|
@ -1558,7 +1558,7 @@ func prepareTestBook1() (*File, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".jpg", file, nil)
|
err = f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".jpg", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
78
picture.go
78
picture.go
|
@ -145,19 +145,18 @@ func parseGraphicOptions(opts *GraphicOptions) *GraphicOptions {
|
||||||
//
|
//
|
||||||
// The optional parameter "ScaleY" specifies the vertical scale of images,
|
// The optional parameter "ScaleY" specifies the vertical scale of images,
|
||||||
// the default value of that is 1.0 which presents 100%.
|
// the default value of that is 1.0 which presents 100%.
|
||||||
func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) error {
|
func (f *File) AddPicture(sheet, cell, name string, opts *GraphicOptions) error {
|
||||||
var err error
|
var err error
|
||||||
// Check picture exists first.
|
// Check picture exists first.
|
||||||
if _, err = os.Stat(picture); os.IsNotExist(err) {
|
if _, err = os.Stat(name); os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ext, ok := supportedImageTypes[path.Ext(picture)]
|
ext, ok := supportedImageTypes[path.Ext(name)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrImgExt
|
return ErrImgExt
|
||||||
}
|
}
|
||||||
file, _ := os.ReadFile(filepath.Clean(picture))
|
file, _ := os.ReadFile(filepath.Clean(name))
|
||||||
_, name := filepath.Split(picture)
|
return f.AddPictureFromBytes(sheet, cell, &Picture{Extension: ext, File: file, Format: opts})
|
||||||
return f.AddPictureFromBytes(sheet, cell, name, ext, file, opts)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddPictureFromBytes provides the method to add picture in a sheet by given
|
// AddPictureFromBytes provides the method to add picture in a sheet by given
|
||||||
|
@ -188,7 +187,11 @@ func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) err
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// if err := f.AddPictureFromBytes("Sheet1", "A2", "Excel Logo", ".jpg", file, nil); err != nil {
|
// if err := f.AddPictureFromBytes("Sheet1", "A2", &excelize.Picture{
|
||||||
|
// Extension: ".jpg",
|
||||||
|
// File: file,
|
||||||
|
// Format: &excelize.GraphicOptions{AltText: "Excel Logo"},
|
||||||
|
// }); err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
@ -196,15 +199,15 @@ func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) err
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []byte, opts *GraphicOptions) error {
|
func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
|
||||||
var drawingHyperlinkRID int
|
var drawingHyperlinkRID int
|
||||||
var hyperlinkType string
|
var hyperlinkType string
|
||||||
ext, ok := supportedImageTypes[extension]
|
ext, ok := supportedImageTypes[pic.Extension]
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrImgExt
|
return ErrImgExt
|
||||||
}
|
}
|
||||||
options := parseGraphicOptions(opts)
|
options := parseGraphicOptions(pic.Format)
|
||||||
img, _, err := image.DecodeConfig(bytes.NewReader(file))
|
img, _, err := image.DecodeConfig(bytes.NewReader(pic.File))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -219,7 +222,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []b
|
||||||
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||||
drawingID, drawingXML = f.prepareDrawing(ws, drawingID, sheet, drawingXML)
|
drawingID, drawingXML = f.prepareDrawing(ws, drawingID, sheet, drawingXML)
|
||||||
drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
|
drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
|
||||||
mediaStr := ".." + strings.TrimPrefix(f.addMedia(file, ext), "xl")
|
mediaStr := ".." + strings.TrimPrefix(f.addMedia(pic.File, ext), "xl")
|
||||||
drawingRID := f.addRels(drawingRels, SourceRelationshipImage, mediaStr, hyperlinkType)
|
drawingRID := f.addRels(drawingRels, SourceRelationshipImage, mediaStr, hyperlinkType)
|
||||||
// Add picture with hyperlink.
|
// Add picture with hyperlink.
|
||||||
if options.Hyperlink != "" && options.HyperlinkType != "" {
|
if options.Hyperlink != "" && options.HyperlinkType != "" {
|
||||||
|
@ -229,7 +232,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []b
|
||||||
drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType)
|
drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType)
|
||||||
}
|
}
|
||||||
ws.Unlock()
|
ws.Unlock()
|
||||||
err = f.addDrawingPicture(sheet, drawingXML, cell, name, ext, drawingRID, drawingHyperlinkRID, img, options)
|
err = f.addDrawingPicture(sheet, drawingXML, cell, ext, drawingRID, drawingHyperlinkRID, img, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -319,7 +322,7 @@ func (f *File) countDrawings() int {
|
||||||
// addDrawingPicture provides a function to add picture by given sheet,
|
// addDrawingPicture provides a function to add picture by given sheet,
|
||||||
// drawingXML, cell, file name, width, height relationship index and format
|
// drawingXML, cell, file name, width, height relationship index and format
|
||||||
// sets.
|
// sets.
|
||||||
func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID, hyperlinkRID int, img image.Config, opts *GraphicOptions) error {
|
func (f *File) addDrawingPicture(sheet, drawingXML, cell, ext string, rID, hyperlinkRID int, img image.Config, opts *GraphicOptions) error {
|
||||||
col, row, err := CellNameToCoordinates(cell)
|
col, row, err := CellNameToCoordinates(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -358,7 +361,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID,
|
||||||
pic := xlsxPic{}
|
pic := xlsxPic{}
|
||||||
pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = opts.LockAspectRatio
|
pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = opts.LockAspectRatio
|
||||||
pic.NvPicPr.CNvPr.ID = cNvPrID
|
pic.NvPicPr.CNvPr.ID = cNvPrID
|
||||||
pic.NvPicPr.CNvPr.Descr = file
|
pic.NvPicPr.CNvPr.Descr = opts.AltText
|
||||||
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
|
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
|
||||||
if hyperlinkRID != 0 {
|
if hyperlinkRID != 0 {
|
||||||
pic.NvPicPr.CNvPr.HlinkClick = &xlsxHlinkClick{
|
pic.NvPicPr.CNvPr.HlinkClick = &xlsxHlinkClick{
|
||||||
|
@ -556,10 +559,10 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPicture provides a function to get picture base name and raw content
|
// GetPictures provides a function to get picture meta info and raw content
|
||||||
// embed in spreadsheet by given worksheet and cell name. This function
|
// embed in spreadsheet by given worksheet and cell name. This function
|
||||||
// returns the file name in spreadsheet and file contents as []byte data
|
// returns the image contents as []byte data types. This function is
|
||||||
// types. This function is concurrency safe. For example:
|
// concurrency safe. For example:
|
||||||
//
|
//
|
||||||
// f, err := excelize.OpenFile("Book1.xlsx")
|
// f, err := excelize.OpenFile("Book1.xlsx")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
@ -571,27 +574,29 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// }
|
// }
|
||||||
// }()
|
// }()
|
||||||
// file, raw, err := f.GetPicture("Sheet1", "A2")
|
// pics, err := f.GetPictures("Sheet1", "A2")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// return
|
|
||||||
// }
|
// }
|
||||||
// if err := os.WriteFile(file, raw, 0644); err != nil {
|
// for idx, pic := range pics {
|
||||||
|
// name := fmt.Sprintf("image%d%s", idx+1, pic.Extension)
|
||||||
|
// if err := os.WriteFile(name, pic.File, 0644); err != nil {
|
||||||
// fmt.Println(err)
|
// fmt.Println(err)
|
||||||
// }
|
// }
|
||||||
func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {
|
// }
|
||||||
|
func (f *File) GetPictures(sheet, cell string) ([]Picture, error) {
|
||||||
col, row, err := CellNameToCoordinates(cell)
|
col, row, err := CellNameToCoordinates(cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
col--
|
col--
|
||||||
row--
|
row--
|
||||||
ws, err := f.workSheetReader(sheet)
|
ws, err := f.workSheetReader(sheet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if ws.Drawing == nil {
|
if ws.Drawing == nil {
|
||||||
return "", nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
target := f.getSheetRelationshipsTargetByID(sheet, ws.Drawing.RID)
|
target := f.getSheetRelationshipsTargetByID(sheet, ws.Drawing.RID)
|
||||||
drawingXML := strings.ReplaceAll(target, "..", "xl")
|
drawingXML := strings.ReplaceAll(target, "..", "xl")
|
||||||
|
@ -601,7 +606,7 @@ func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {
|
||||||
return f.getPicture(row, col, drawingXML, drawingRelationships)
|
return f.getPicture(row, col, drawingXML, drawingRelationships)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeletePicture provides a function to delete charts in spreadsheet by given
|
// DeletePicture provides a function to delete all pictures in a cell by given
|
||||||
// worksheet name and cell reference. Note that the image file won't be deleted
|
// worksheet name and cell reference. Note that the image file won't be deleted
|
||||||
// from the document currently.
|
// from the document currently.
|
||||||
func (f *File) DeletePicture(sheet, cell string) error {
|
func (f *File) DeletePicture(sheet, cell string) error {
|
||||||
|
@ -624,7 +629,7 @@ func (f *File) DeletePicture(sheet, cell string) error {
|
||||||
|
|
||||||
// getPicture provides a function to get picture base name and raw content
|
// getPicture provides a function to get picture base name and raw content
|
||||||
// embed in spreadsheet by given coordinates and drawing relationships.
|
// embed in spreadsheet by given coordinates and drawing relationships.
|
||||||
func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string) (ret string, buf []byte, err error) {
|
func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string) (pics []Picture, err error) {
|
||||||
var (
|
var (
|
||||||
wsDr *xlsxWsDr
|
wsDr *xlsxWsDr
|
||||||
ok bool
|
ok bool
|
||||||
|
@ -636,7 +641,7 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
|
||||||
if wsDr, _, err = f.drawingParser(drawingXML); err != nil {
|
if wsDr, _, err = f.drawingParser(drawingXML); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ret, buf = f.getPictureFromWsDr(row, col, drawingRelationships, wsDr); len(buf) > 0 {
|
if pics = f.getPicturesFromWsDr(row, col, drawingRelationships, wsDr); len(pics) > 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
deWsDr = new(decodeWsDr)
|
deWsDr = new(decodeWsDr)
|
||||||
|
@ -655,9 +660,11 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
|
||||||
if deTwoCellAnchor.From.Col == col && deTwoCellAnchor.From.Row == row {
|
if deTwoCellAnchor.From.Col == col && deTwoCellAnchor.From.Row == row {
|
||||||
drawRel = f.getDrawingRelationships(drawingRelationships, deTwoCellAnchor.Pic.BlipFill.Blip.Embed)
|
drawRel = f.getDrawingRelationships(drawingRelationships, deTwoCellAnchor.Pic.BlipFill.Blip.Embed)
|
||||||
if _, ok = supportedImageTypes[filepath.Ext(drawRel.Target)]; ok {
|
if _, ok = supportedImageTypes[filepath.Ext(drawRel.Target)]; ok {
|
||||||
ret = filepath.Base(drawRel.Target)
|
pic := Picture{Extension: filepath.Ext(drawRel.Target), Format: &GraphicOptions{}}
|
||||||
if buffer, _ := f.Pkg.Load(strings.ReplaceAll(drawRel.Target, "..", "xl")); buffer != nil {
|
if buffer, _ := f.Pkg.Load(strings.ReplaceAll(drawRel.Target, "..", "xl")); buffer != nil {
|
||||||
buf = buffer.([]byte)
|
pic.File = buffer.([]byte)
|
||||||
|
pic.Format.AltText = deTwoCellAnchor.Pic.NvPicPr.CNvPr.Descr
|
||||||
|
pics = append(pics, pic)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -667,10 +674,10 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// getPictureFromWsDr provides a function to get picture base name and raw
|
// getPicturesFromWsDr provides a function to get picture base name and raw
|
||||||
// content in worksheet drawing by given coordinates and drawing
|
// content in worksheet drawing by given coordinates and drawing
|
||||||
// relationships.
|
// relationships.
|
||||||
func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsDr *xlsxWsDr) (ret string, buf []byte) {
|
func (f *File) getPicturesFromWsDr(row, col int, drawingRelationships string, wsDr *xlsxWsDr) (pics []Picture) {
|
||||||
var (
|
var (
|
||||||
ok bool
|
ok bool
|
||||||
anchor *xdrCellAnchor
|
anchor *xdrCellAnchor
|
||||||
|
@ -684,11 +691,12 @@ func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsD
|
||||||
if drawRel = f.getDrawingRelationships(drawingRelationships,
|
if drawRel = f.getDrawingRelationships(drawingRelationships,
|
||||||
anchor.Pic.BlipFill.Blip.Embed); drawRel != nil {
|
anchor.Pic.BlipFill.Blip.Embed); drawRel != nil {
|
||||||
if _, ok = supportedImageTypes[filepath.Ext(drawRel.Target)]; ok {
|
if _, ok = supportedImageTypes[filepath.Ext(drawRel.Target)]; ok {
|
||||||
ret = filepath.Base(drawRel.Target)
|
pic := Picture{Extension: filepath.Ext(drawRel.Target), Format: &GraphicOptions{}}
|
||||||
if buffer, _ := f.Pkg.Load(strings.ReplaceAll(drawRel.Target, "..", "xl")); buffer != nil {
|
if buffer, _ := f.Pkg.Load(strings.ReplaceAll(drawRel.Target, "..", "xl")); buffer != nil {
|
||||||
buf = buffer.([]byte)
|
pic.File = buffer.([]byte)
|
||||||
|
pic.Format.AltText = anchor.Pic.NvPicPr.CNvPr.Descr
|
||||||
|
pics = append(pics, pic)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ func BenchmarkAddPictureFromBytes(b *testing.B) {
|
||||||
}
|
}
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 1; i <= b.N; i++ {
|
for i := 1; i <= b.N; i++ {
|
||||||
if err := f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", i), "excel", ".png", imgFile, nil); err != nil {
|
if err := f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", i), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "Excel"}}); err != nil {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,9 @@ func TestAddPicture(t *testing.T) {
|
||||||
assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
|
assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
|
||||||
|
|
||||||
// Test add picture to worksheet from bytes
|
// Test add picture to worksheet from bytes
|
||||||
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".png", file, nil))
|
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}))
|
||||||
// Test add picture to worksheet from bytes with illegal cell reference
|
// Test add picture to worksheet from bytes with illegal cell reference
|
||||||
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", "Excel Logo", ".png", file, nil), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
||||||
|
|
||||||
assert.NoError(t, f.AddPicture("Sheet1", "Q8", filepath.Join("test", "images", "excel.gif"), nil))
|
assert.NoError(t, f.AddPicture("Sheet1", "Q8", filepath.Join("test", "images", "excel.gif"), nil))
|
||||||
assert.NoError(t, f.AddPicture("Sheet1", "Q15", filepath.Join("test", "images", "excel.jpg"), nil))
|
assert.NoError(t, f.AddPicture("Sheet1", "Q15", filepath.Join("test", "images", "excel.jpg"), nil))
|
||||||
|
@ -75,7 +75,7 @@ func TestAddPicture(t *testing.T) {
|
||||||
f = NewFile()
|
f = NewFile()
|
||||||
f.ContentTypes = nil
|
f.ContentTypes = nil
|
||||||
f.Pkg.Store(defaultXMLPathContentTypes, MacintoshCyrillicCharset)
|
f.Pkg.Store(defaultXMLPathContentTypes, MacintoshCyrillicCharset)
|
||||||
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".png", file, nil), "XML syntax error on line 1: invalid UTF-8")
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}), "XML syntax error on line 1: invalid UTF-8")
|
||||||
|
|
||||||
// Test add picture with invalid sheet name
|
// Test add picture with invalid sheet name
|
||||||
assert.EqualError(t, f.AddPicture("Sheet:1", "A1", filepath.Join("test", "images", "excel.jpg"), nil), ErrSheetNameInvalid.Error())
|
assert.EqualError(t, f.AddPicture("Sheet:1", "A1", filepath.Join("test", "images", "excel.jpg"), nil), ErrSheetNameInvalid.Error())
|
||||||
|
@ -90,10 +90,11 @@ func TestAddPictureErrors(t *testing.T) {
|
||||||
|
|
||||||
// Test add picture to worksheet with unsupported file type
|
// Test add picture to worksheet with unsupported file type
|
||||||
assert.EqualError(t, f.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), nil), ErrImgExt.Error())
|
assert.EqualError(t, f.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), nil), ErrImgExt.Error())
|
||||||
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", "Excel Logo", "jpg", make([]byte, 1), nil), ErrImgExt.Error())
|
|
||||||
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", &Picture{Extension: "jpg", File: make([]byte, 1), Format: &GraphicOptions{AltText: "Excel Logo"}}), ErrImgExt.Error())
|
||||||
|
|
||||||
// Test add picture to worksheet with invalid file data
|
// Test add picture to worksheet with invalid file data
|
||||||
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", "Excel Logo", ".jpg", make([]byte, 1), nil), image.ErrFormat.Error())
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", &Picture{Extension: ".jpg", File: make([]byte, 1), Format: &GraphicOptions{AltText: "Excel Logo"}}), image.ErrFormat.Error())
|
||||||
|
|
||||||
// Test add picture with custom image decoder and encoder
|
// Test add picture with custom image decoder and encoder
|
||||||
decode := func(r io.Reader) (image.Image, error) { return nil, nil }
|
decode := func(r io.Reader) (image.Image, error) { return nil, nil }
|
||||||
|
@ -115,41 +116,39 @@ func TestAddPictureErrors(t *testing.T) {
|
||||||
func TestGetPicture(t *testing.T) {
|
func TestGetPicture(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.png"), nil))
|
assert.NoError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.png"), nil))
|
||||||
name, content, err := f.GetPicture("Sheet1", "A1")
|
pics, err := f.GetPictures("Sheet1", "A1")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 13233, len(content))
|
assert.Len(t, pics[0].File, 13233)
|
||||||
assert.Equal(t, "image1.png", name)
|
assert.Empty(t, pics[0].Format.AltText)
|
||||||
|
|
||||||
f, err = prepareTestBook1()
|
f, err = prepareTestBook1()
|
||||||
if !assert.NoError(t, err) {
|
if !assert.NoError(t, err) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
file, raw, err := f.GetPicture("Sheet1", "F21")
|
pics, err = f.GetPictures("Sheet1", "F21")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
|
if !assert.NotEmpty(t, filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension))) || !assert.NotEmpty(t, pics[0].File) ||
|
||||||
!assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) {
|
!assert.NoError(t, os.WriteFile(filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension)), pics[0].File, 0o644)) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get picture from a worksheet with illegal cell reference
|
// Try to get picture from a worksheet with illegal cell reference
|
||||||
_, _, err = f.GetPicture("Sheet1", "A")
|
_, err = f.GetPictures("Sheet1", "A")
|
||||||
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
||||||
|
|
||||||
// Try to get picture from a worksheet that doesn't contain any images
|
// Try to get picture from a worksheet that doesn't contain any images
|
||||||
file, raw, err = f.GetPicture("Sheet3", "I9")
|
pics, err = f.GetPictures("Sheet3", "I9")
|
||||||
assert.EqualError(t, err, "sheet Sheet3 does not exist")
|
assert.EqualError(t, err, "sheet Sheet3 does not exist")
|
||||||
assert.Empty(t, file)
|
assert.Len(t, pics, 0)
|
||||||
assert.Empty(t, raw)
|
|
||||||
|
|
||||||
// Try to get picture from a cell that doesn't contain an image
|
// Try to get picture from a cell that doesn't contain an image
|
||||||
file, raw, err = f.GetPicture("Sheet2", "A2")
|
pics, err = f.GetPictures("Sheet2", "A2")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Empty(t, file)
|
assert.Len(t, pics, 0)
|
||||||
assert.Empty(t, raw)
|
|
||||||
|
|
||||||
// Test get picture with invalid sheet name
|
// Test get picture with invalid sheet name
|
||||||
_, _, err = f.GetPicture("Sheet:1", "A2")
|
_, err = f.GetPictures("Sheet:1", "A2")
|
||||||
assert.EqualError(t, err, ErrSheetNameInvalid.Error())
|
assert.EqualError(t, err, ErrSheetNameInvalid.Error())
|
||||||
|
|
||||||
f.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
|
f.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
|
||||||
|
@ -163,36 +162,34 @@ func TestGetPicture(t *testing.T) {
|
||||||
f, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
|
f, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
file, raw, err = f.GetPicture("Sheet1", "F21")
|
pics, err = f.GetPictures("Sheet1", "F21")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
|
if !assert.NotEmpty(t, filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension))) || !assert.NotEmpty(t, pics[0].File) ||
|
||||||
!assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) {
|
!assert.NoError(t, os.WriteFile(filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension)), pics[0].File, 0o644)) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get picture from a local storage file that doesn't contain an image
|
// Try to get picture from a local storage file that doesn't contain an image
|
||||||
file, raw, err = f.GetPicture("Sheet1", "F22")
|
pics, err = f.GetPictures("Sheet1", "F22")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Empty(t, file)
|
assert.Len(t, pics, 0)
|
||||||
assert.Empty(t, raw)
|
|
||||||
assert.NoError(t, f.Close())
|
assert.NoError(t, f.Close())
|
||||||
|
|
||||||
// Test get picture from none drawing worksheet
|
// Test get picture from none drawing worksheet
|
||||||
f = NewFile()
|
f = NewFile()
|
||||||
file, raw, err = f.GetPicture("Sheet1", "F22")
|
pics, err = f.GetPictures("Sheet1", "F22")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Empty(t, file)
|
assert.Len(t, pics, 0)
|
||||||
assert.Empty(t, raw)
|
|
||||||
f, err = prepareTestBook1()
|
f, err = prepareTestBook1()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Test get pictures with unsupported charset
|
// Test get pictures with unsupported charset
|
||||||
path := "xl/drawings/drawing1.xml"
|
path := "xl/drawings/drawing1.xml"
|
||||||
f.Pkg.Store(path, MacintoshCyrillicCharset)
|
f.Pkg.Store(path, MacintoshCyrillicCharset)
|
||||||
_, _, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
|
_, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
|
||||||
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
||||||
f.Drawings.Delete(path)
|
f.Drawings.Delete(path)
|
||||||
_, _, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
|
_, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
|
||||||
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,19 +197,20 @@ func TestAddDrawingPicture(t *testing.T) {
|
||||||
// Test addDrawingPicture with illegal cell reference
|
// Test addDrawingPicture with illegal cell reference
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
opts := &GraphicOptions{PrintObject: boolPtr(true), Locked: boolPtr(false)}
|
opts := &GraphicOptions{PrintObject: boolPtr(true), Locked: boolPtr(false)}
|
||||||
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", "", 0, 0, image.Config{}, opts), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", 0, 0, image.Config{}, opts), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
|
||||||
|
|
||||||
path := "xl/drawings/drawing1.xml"
|
path := "xl/drawings/drawing1.xml"
|
||||||
f.Pkg.Store(path, MacintoshCyrillicCharset)
|
f.Pkg.Store(path, MacintoshCyrillicCharset)
|
||||||
assert.EqualError(t, f.addDrawingPicture("sheet1", path, "A1", "", "", 0, 0, image.Config{}, opts), "XML syntax error on line 1: invalid UTF-8")
|
assert.EqualError(t, f.addDrawingPicture("sheet1", path, "A1", "", 0, 0, image.Config{}, opts), "XML syntax error on line 1: invalid UTF-8")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAddPictureFromBytes(t *testing.T) {
|
func TestAddPictureFromBytes(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
imgFile, err := os.ReadFile("logo.png")
|
imgFile, err := os.ReadFile("logo.png")
|
||||||
assert.NoError(t, err, "Unable to load logo for test")
|
assert.NoError(t, err, "Unable to load logo for test")
|
||||||
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "logo", ".png", imgFile, nil))
|
|
||||||
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "logo", ".png", imgFile, nil))
|
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}))
|
||||||
|
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}))
|
||||||
imageCount := 0
|
imageCount := 0
|
||||||
f.Pkg.Range(func(fileName, v interface{}) bool {
|
f.Pkg.Range(func(fileName, v interface{}) bool {
|
||||||
if strings.Contains(fileName.(string), "media/image") {
|
if strings.Contains(fileName.(string), "media/image") {
|
||||||
|
@ -221,9 +219,9 @@ func TestAddPictureFromBytes(t *testing.T) {
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
assert.Equal(t, 1, imageCount, "Duplicate image should only be stored once.")
|
assert.Equal(t, 1, imageCount, "Duplicate image should only be stored once.")
|
||||||
assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), "logo", ".png", imgFile, nil), "sheet SheetN does not exist")
|
assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}), "sheet SheetN does not exist")
|
||||||
// Test add picture from bytes with invalid sheet name
|
// Test add picture from bytes with invalid sheet name
|
||||||
assert.EqualError(t, f.AddPictureFromBytes("Sheet:1", fmt.Sprint("A", 1), "logo", ".png", imgFile, nil), ErrSheetNameInvalid.Error())
|
assert.EqualError(t, f.AddPictureFromBytes("Sheet:1", fmt.Sprint("A", 1), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}), ErrSheetNameInvalid.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeletePicture(t *testing.T) {
|
func TestDeletePicture(t *testing.T) {
|
||||||
|
|
|
@ -581,8 +581,16 @@ type xdrTxBody struct {
|
||||||
P []*aP `xml:"a:p"`
|
P []*aP `xml:"a:p"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Picture maps the format settings of the picture.
|
||||||
|
type Picture struct {
|
||||||
|
Extension string
|
||||||
|
File []byte
|
||||||
|
Format *GraphicOptions
|
||||||
|
}
|
||||||
|
|
||||||
// GraphicOptions directly maps the format settings of the picture.
|
// GraphicOptions directly maps the format settings of the picture.
|
||||||
type GraphicOptions struct {
|
type GraphicOptions struct {
|
||||||
|
AltText string
|
||||||
PrintObject *bool
|
PrintObject *bool
|
||||||
Locked *bool
|
Locked *bool
|
||||||
LockAspectRatio bool
|
LockAspectRatio bool
|
||||||
|
|
Loading…
Reference in New Issue