picture_test.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package excelize
  2. import (
  3. _ "image/gif"
  4. _ "image/jpeg"
  5. _ "image/png"
  6. _ "golang.org/x/image/tiff"
  7. "fmt"
  8. "io/ioutil"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. "testing"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func BenchmarkAddPictureFromBytes(b *testing.B) {
  16. f := NewFile()
  17. imgFile, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.png"))
  18. if err != nil {
  19. b.Error("unable to load image for benchmark")
  20. }
  21. b.ResetTimer()
  22. for i := 1; i <= b.N; i++ {
  23. if err := f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", i), "", "excel", ".png", imgFile); err != nil {
  24. b.Error(err)
  25. }
  26. }
  27. }
  28. func TestAddPicture(t *testing.T) {
  29. f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  30. if !assert.NoError(t, err) {
  31. t.FailNow()
  32. }
  33. // Test add picture to worksheet with offset and location hyperlink.
  34. assert.NoError(t, f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
  35. `{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`))
  36. // Test add picture to worksheet with offset, external hyperlink and positioning.
  37. assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
  38. `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/xuri/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`))
  39. file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.png"))
  40. assert.NoError(t, err)
  41. // Test add picture to worksheet with autofit.
  42. assert.NoError(t, f.AddPicture("Sheet1", "A30", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`))
  43. assert.NoError(t, f.AddPicture("Sheet1", "B30", filepath.Join("test", "images", "excel.jpg"), `{"x_offset": 10, "y_offset": 10, "autofit": true}`))
  44. f.NewSheet("AddPicture")
  45. assert.NoError(t, f.SetRowHeight("AddPicture", 10, 30))
  46. assert.NoError(t, f.MergeCell("AddPicture", "B3", "D9"))
  47. assert.NoError(t, f.MergeCell("AddPicture", "B1", "D1"))
  48. assert.NoError(t, f.AddPicture("AddPicture", "C6", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`))
  49. assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`))
  50. // Test add picture to worksheet from bytes.
  51. assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".png", file))
  52. // Test add picture to worksheet from bytes with illegal cell coordinates.
  53. assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", "", "Excel Logo", ".png", file), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  54. assert.NoError(t, f.AddPicture("Sheet1", "Q8", filepath.Join("test", "images", "excel.gif"), ""))
  55. assert.NoError(t, f.AddPicture("Sheet1", "Q15", filepath.Join("test", "images", "excel.jpg"), ""))
  56. assert.NoError(t, f.AddPicture("Sheet1", "Q22", filepath.Join("test", "images", "excel.tif"), ""))
  57. // Test write file to given path.
  58. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPicture.xlsx")))
  59. }
  60. func TestAddPictureErrors(t *testing.T) {
  61. xlsx, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  62. assert.NoError(t, err)
  63. // Test add picture to worksheet with invalid file path.
  64. err = xlsx.AddPicture("Sheet1", "G21", filepath.Join("test", "not_exists_dir", "not_exists.icon"), "")
  65. if assert.Error(t, err) {
  66. assert.True(t, os.IsNotExist(err), "Expected os.IsNotExist(err) == true")
  67. }
  68. // Test add picture to worksheet with unsupported file type.
  69. err = xlsx.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), "")
  70. assert.EqualError(t, err, ErrImgExt.Error())
  71. err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1))
  72. assert.EqualError(t, err, ErrImgExt.Error())
  73. // Test add picture to worksheet with invalid file data.
  74. err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", ".jpg", make([]byte, 1))
  75. assert.EqualError(t, err, "image: unknown format")
  76. }
  77. func TestGetPicture(t *testing.T) {
  78. f, err := prepareTestBook1()
  79. if !assert.NoError(t, err) {
  80. t.FailNow()
  81. }
  82. file, raw, err := f.GetPicture("Sheet1", "F21")
  83. assert.NoError(t, err)
  84. if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
  85. !assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0644)) {
  86. t.FailNow()
  87. }
  88. // Try to get picture from a worksheet with illegal cell coordinates.
  89. _, _, err = f.GetPicture("Sheet1", "A")
  90. assert.EqualError(t, err, `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  91. // Try to get picture from a worksheet that doesn't contain any images.
  92. file, raw, err = f.GetPicture("Sheet3", "I9")
  93. assert.EqualError(t, err, "sheet Sheet3 is not exist")
  94. assert.Empty(t, file)
  95. assert.Empty(t, raw)
  96. // Try to get picture from a cell that doesn't contain an image.
  97. file, raw, err = f.GetPicture("Sheet2", "A2")
  98. assert.NoError(t, err)
  99. assert.Empty(t, file)
  100. assert.Empty(t, raw)
  101. f.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
  102. f.getDrawingRelationships("", "")
  103. f.getSheetRelationshipsTargetByID("", "")
  104. f.deleteSheetRelationships("", "")
  105. // Try to get picture from a local storage file.
  106. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestGetPicture.xlsx")))
  107. f, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
  108. assert.NoError(t, err)
  109. file, raw, err = f.GetPicture("Sheet1", "F21")
  110. assert.NoError(t, err)
  111. if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
  112. !assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0644)) {
  113. t.FailNow()
  114. }
  115. // Try to get picture from a local storage file that doesn't contain an image.
  116. file, raw, err = f.GetPicture("Sheet1", "F22")
  117. assert.NoError(t, err)
  118. assert.Empty(t, file)
  119. assert.Empty(t, raw)
  120. // Test get picture from none drawing worksheet.
  121. f = NewFile()
  122. file, raw, err = f.GetPicture("Sheet1", "F22")
  123. assert.NoError(t, err)
  124. assert.Empty(t, file)
  125. assert.Empty(t, raw)
  126. f, err = prepareTestBook1()
  127. assert.NoError(t, err)
  128. f.Pkg.Store("xl/drawings/drawing1.xml", MacintoshCyrillicCharset)
  129. _, _, err = f.getPicture(20, 5, "xl/drawings/drawing1.xml", "xl/drawings/_rels/drawing2.xml.rels")
  130. assert.EqualError(t, err, "xml decode error: XML syntax error on line 1: invalid UTF-8")
  131. }
  132. func TestAddDrawingPicture(t *testing.T) {
  133. // testing addDrawingPicture with illegal cell coordinates.
  134. f := NewFile()
  135. assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", 0, 0, 0, 0, nil), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  136. }
  137. func TestAddPictureFromBytes(t *testing.T) {
  138. f := NewFile()
  139. imgFile, err := ioutil.ReadFile("logo.png")
  140. assert.NoError(t, err, "Unable to load logo for test")
  141. assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "", "logo", ".png", imgFile))
  142. assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile))
  143. imageCount := 0
  144. f.Pkg.Range(func(fileName, v interface{}) bool {
  145. if strings.Contains(fileName.(string), "media/image") {
  146. imageCount++
  147. }
  148. return true
  149. })
  150. assert.Equal(t, 1, imageCount, "Duplicate image should only be stored once.")
  151. assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), "", "logo", ".png", imgFile), "sheet SheetN is not exist")
  152. }
  153. func TestDeletePicture(t *testing.T) {
  154. f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
  155. assert.NoError(t, err)
  156. assert.NoError(t, f.DeletePicture("Sheet1", "A1"))
  157. assert.NoError(t, f.AddPicture("Sheet1", "P1", filepath.Join("test", "images", "excel.jpg"), ""))
  158. assert.NoError(t, f.DeletePicture("Sheet1", "P1"))
  159. assert.NoError(t, f.SaveAs(filepath.Join("test", "TestDeletePicture.xlsx")))
  160. // Test delete picture on not exists worksheet.
  161. assert.EqualError(t, f.DeletePicture("SheetN", "A1"), "sheet SheetN is not exist")
  162. // Test delete picture with invalid coordinates.
  163. assert.EqualError(t, f.DeletePicture("Sheet1", ""), `cannot convert cell "" to coordinates: invalid cell name ""`)
  164. // Test delete picture on no chart worksheet.
  165. assert.NoError(t, NewFile().DeletePicture("Sheet1", "A1"))
  166. }
  167. func TestDrawingResize(t *testing.T) {
  168. f := NewFile()
  169. // Test calculate drawing resize on not exists worksheet.
  170. _, _, _, _, err := f.drawingResize("SheetN", "A1", 1, 1, nil)
  171. assert.EqualError(t, err, "sheet SheetN is not exist")
  172. // Test calculate drawing resize with invalid coordinates.
  173. _, _, _, _, err = f.drawingResize("Sheet1", "", 1, 1, nil)
  174. assert.EqualError(t, err, `cannot convert cell "" to coordinates: invalid cell name ""`)
  175. ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
  176. assert.True(t, ok)
  177. ws.(*xlsxWorksheet).MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
  178. assert.EqualError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), `{"autofit": true}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
  179. }