From 478b528af14840a3abf464a5128471d570f3eaaf Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 19 Mar 2023 20:23:33 +0800 Subject: [PATCH] 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> --- cell_test.go | 5 ++- excelize_test.go | 2 +- picture.go | 82 ++++++++++++++++++++++++++---------------------- picture_test.go | 72 +++++++++++++++++++++--------------------- xmlDrawing.go | 8 +++++ 5 files changed, 91 insertions(+), 78 deletions(-) diff --git a/cell_test.go b/cell_test.go index 210918cf..17ca800c 100644 --- a/cell_test.go +++ b/cell_test.go @@ -52,9 +52,8 @@ func TestConcurrency(t *testing.T) { }, )) // Concurrency get cell picture - name, raw, err := f.GetPicture("Sheet1", "A1") - assert.Equal(t, "", name) - assert.Nil(t, raw) + pics, err := f.GetPictures("Sheet1", "A1") + assert.Len(t, pics, 0) assert.NoError(t, err) // Concurrency iterate rows rows, err := f.Rows("Sheet1") diff --git a/excelize_test.go b/excelize_test.go index 8d9bbc8a..e09c4b81 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -1558,7 +1558,7 @@ func prepareTestBook1() (*File, error) { 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 { return nil, err } diff --git a/picture.go b/picture.go index 54b03f2a..fcc8d5fc 100644 --- a/picture.go +++ b/picture.go @@ -145,19 +145,18 @@ func parseGraphicOptions(opts *GraphicOptions) *GraphicOptions { // // The optional parameter "ScaleY" specifies the vertical scale of images, // 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 // Check picture exists first. - if _, err = os.Stat(picture); os.IsNotExist(err) { + if _, err = os.Stat(name); os.IsNotExist(err) { return err } - ext, ok := supportedImageTypes[path.Ext(picture)] + ext, ok := supportedImageTypes[path.Ext(name)] if !ok { return ErrImgExt } - file, _ := os.ReadFile(filepath.Clean(picture)) - _, name := filepath.Split(picture) - return f.AddPictureFromBytes(sheet, cell, name, ext, file, opts) + file, _ := os.ReadFile(filepath.Clean(name)) + return f.AddPictureFromBytes(sheet, cell, &Picture{Extension: ext, File: file, Format: opts}) } // 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) // 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) // return // } @@ -196,15 +199,15 @@ func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) 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 hyperlinkType string - ext, ok := supportedImageTypes[extension] + ext, ok := supportedImageTypes[pic.Extension] if !ok { return ErrImgExt } - options := parseGraphicOptions(opts) - img, _, err := image.DecodeConfig(bytes.NewReader(file)) + options := parseGraphicOptions(pic.Format) + img, _, err := image.DecodeConfig(bytes.NewReader(pic.File)) if err != nil { 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" drawingID, drawingXML = f.prepareDrawing(ws, drawingID, sheet, drawingXML) 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) // Add picture with hyperlink. 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) } 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 { return err } @@ -319,7 +322,7 @@ func (f *File) countDrawings() int { // addDrawingPicture provides a function to add picture by given sheet, // drawingXML, cell, file name, width, height relationship index and format // 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) if err != nil { return err @@ -358,7 +361,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID, pic := xlsxPic{} pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = opts.LockAspectRatio pic.NvPicPr.CNvPr.ID = cNvPrID - pic.NvPicPr.CNvPr.Descr = file + pic.NvPicPr.CNvPr.Descr = opts.AltText pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID) if hyperlinkRID != 0 { pic.NvPicPr.CNvPr.HlinkClick = &xlsxHlinkClick{ @@ -556,10 +559,10 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string { 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 -// returns the file name in spreadsheet and file contents as []byte data -// types. This function is concurrency safe. For example: +// returns the image contents as []byte data types. This function is +// concurrency safe. For example: // // f, err := excelize.OpenFile("Book1.xlsx") // if err != nil { @@ -571,27 +574,29 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string { // fmt.Println(err) // } // }() -// file, raw, err := f.GetPicture("Sheet1", "A2") +// pics, err := f.GetPictures("Sheet1", "A2") // if err != nil { -// fmt.Println(err) -// return +// fmt.Println(err) // } -// if err := os.WriteFile(file, raw, 0644); err != nil { -// fmt.Println(err) +// 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) +// } // } -func (f *File) GetPicture(sheet, cell string) (string, []byte, error) { +func (f *File) GetPictures(sheet, cell string) ([]Picture, error) { col, row, err := CellNameToCoordinates(cell) if err != nil { - return "", nil, err + return nil, err } col-- row-- ws, err := f.workSheetReader(sheet) if err != nil { - return "", nil, err + return nil, err } if ws.Drawing == nil { - return "", nil, err + return nil, err } target := f.getSheetRelationshipsTargetByID(sheet, ws.Drawing.RID) 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) } -// 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 // from the document currently. 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 // 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 ( wsDr *xlsxWsDr ok bool @@ -636,7 +641,7 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string) if wsDr, _, err = f.drawingParser(drawingXML); err != nil { 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 } 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 { drawRel = f.getDrawingRelationships(drawingRelationships, deTwoCellAnchor.Pic.BlipFill.Blip.Embed) 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 { - buf = buffer.([]byte) + pic.File = buffer.([]byte) + pic.Format.AltText = deTwoCellAnchor.Pic.NvPicPr.CNvPr.Descr + pics = append(pics, pic) } return } @@ -667,10 +674,10 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string) 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 // 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 ( ok bool anchor *xdrCellAnchor @@ -684,11 +691,12 @@ func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsD if drawRel = f.getDrawingRelationships(drawingRelationships, anchor.Pic.BlipFill.Blip.Embed); drawRel != nil { 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 { - buf = buffer.([]byte) + pic.File = buffer.([]byte) + pic.Format.AltText = anchor.Pic.NvPicPr.CNvPr.Descr + pics = append(pics, pic) } - return } } } diff --git a/picture_test.go b/picture_test.go index d6b91c7f..95bb39e9 100644 --- a/picture_test.go +++ b/picture_test.go @@ -26,7 +26,7 @@ func BenchmarkAddPictureFromBytes(b *testing.B) { } b.ResetTimer() 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) } } @@ -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})) // 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 - 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", "Q15", filepath.Join("test", "images", "excel.jpg"), nil)) @@ -75,7 +75,7 @@ func TestAddPicture(t *testing.T) { f = NewFile() f.ContentTypes = nil 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 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 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 - 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 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) { f := NewFile() 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.Equal(t, 13233, len(content)) - assert.Equal(t, "image1.png", name) + assert.Len(t, pics[0].File, 13233) + assert.Empty(t, pics[0].Format.AltText) f, err = prepareTestBook1() if !assert.NoError(t, err) { t.FailNow() } - file, raw, err := f.GetPicture("Sheet1", "F21") + pics, err = f.GetPictures("Sheet1", "F21") assert.NoError(t, err) - if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) || - !assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) { + 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", fmt.Sprintf("image1%s", pics[0].Extension)), pics[0].File, 0o644)) { t.FailNow() } // 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()) // 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.Empty(t, file) - assert.Empty(t, raw) + assert.Len(t, pics, 0) // 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.Empty(t, file) - assert.Empty(t, raw) + assert.Len(t, pics, 0) // 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()) 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")) assert.NoError(t, err) - file, raw, err = f.GetPicture("Sheet1", "F21") + pics, err = f.GetPictures("Sheet1", "F21") assert.NoError(t, err) - if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) || - !assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) { + 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", fmt.Sprintf("image1%s", pics[0].Extension)), pics[0].File, 0o644)) { t.FailNow() } // 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.Empty(t, file) - assert.Empty(t, raw) + assert.Len(t, pics, 0) assert.NoError(t, f.Close()) // Test get picture from none drawing worksheet f = NewFile() - file, raw, err = f.GetPicture("Sheet1", "F22") + pics, err = f.GetPictures("Sheet1", "F22") assert.NoError(t, err) - assert.Empty(t, file) - assert.Empty(t, raw) + assert.Len(t, pics, 0) f, err = prepareTestBook1() assert.NoError(t, err) // Test get pictures with unsupported charset path := "xl/drawings/drawing1.xml" 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") 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") } @@ -200,19 +197,20 @@ func TestAddDrawingPicture(t *testing.T) { // Test addDrawingPicture with illegal cell reference f := NewFile() 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" 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) { f := NewFile() imgFile, err := os.ReadFile("logo.png") 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 f.Pkg.Range(func(fileName, v interface{}) bool { if strings.Contains(fileName.(string), "media/image") { @@ -221,9 +219,9 @@ func TestAddPictureFromBytes(t *testing.T) { return true }) 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 - 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) { diff --git a/xmlDrawing.go b/xmlDrawing.go index 3130833f..caf9897a 100644 --- a/xmlDrawing.go +++ b/xmlDrawing.go @@ -581,8 +581,16 @@ type xdrTxBody struct { 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. type GraphicOptions struct { + AltText string PrintObject *bool Locked *bool LockAspectRatio bool