Selaa lähdekoodia

New function `AddPictureFromBytes()` has been added, this resolve #259 and close #271.

xuri 7 vuotta sitten
vanhempi
commit
6ced438f39
7 muutettua tiedostoa jossa 131 lisäystä ja 49 poistoa
  1. 16 3
      comment.go
  2. 1 3
      datavalidation_test.go
  3. 27 27
      date_test.go
  4. 24 1
      excelize_test.go
  5. 51 13
      picture.go
  6. 4 2
      sheet.go
  7. 8 0
      xmlComments.go

+ 16 - 3
comment.go

@@ -29,8 +29,8 @@ func parseFormatCommentsSet(formatSet string) (*formatComment, error) {
 
 // GetComments retrieves all comments and returns a map of worksheet name to
 // the worksheet comments.
-func (f *File) GetComments() (comments map[string]*xlsxComments) {
-	comments = map[string]*xlsxComments{}
+func (f *File) GetComments() (comments map[string][]Comment) {
+	comments = map[string][]Comment{}
 	for n := range f.sheetMap {
 		commentID := f.GetSheetIndex(n)
 		commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml"
@@ -38,7 +38,20 @@ func (f *File) GetComments() (comments map[string]*xlsxComments) {
 		if ok {
 			d := xlsxComments{}
 			xml.Unmarshal([]byte(c), &d)
-			comments[n] = &d
+			sheetComments := []Comment{}
+			for _, comment := range d.CommentList.Comment {
+				sheetComment := Comment{}
+				if comment.AuthorID < len(d.Authors) {
+					sheetComment.Author = d.Authors[comment.AuthorID].Author
+				}
+				sheetComment.Ref = comment.Ref
+				sheetComment.AuthorID = comment.AuthorID
+				for _, text := range comment.Text.R {
+					sheetComment.Text += text.T
+				}
+				sheetComments = append(sheetComments, sheetComment)
+			}
+			comments[n] = sheetComments
 		}
 	}
 	return

+ 1 - 3
datavalidation_test.go

@@ -8,9 +8,7 @@
 // the LICENSE file.
 package excelize
 
-import (
-	"testing"
-)
+import "testing"
 
 func TestDataValidation(t *testing.T) {
 	xlsx := NewFile()

+ 27 - 27
date_test.go

@@ -1,42 +1,42 @@
 package excelize
 
 import (
-    "testing"
-    "time"
+	"testing"
+	"time"
 )
 
 type dateTest struct {
-    ExcelValue float64
-    GoValue    time.Time
+	ExcelValue float64
+	GoValue    time.Time
 }
 
 func TestTimeToExcelTime(t *testing.T) {
-    trueExpectedInputList := []dateTest {
-        {0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)},
-        {25569.0, time.Unix(0, 0)},
-        {43269.0, time.Date(2018, 6, 18, 0, 0, 0, 0, time.UTC)},
-        {401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
-    }
+	trueExpectedInputList := []dateTest{
+		{0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)},
+		{25569.0, time.Unix(0, 0)},
+		{43269.0, time.Date(2018, 6, 18, 0, 0, 0, 0, time.UTC)},
+		{401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
+	}
 
-    for _, test := range trueExpectedInputList {
-        if test.ExcelValue != timeToExcelTime(test.GoValue) {
-            t.Fatalf("Expected %v from %v = true, got %v\n", test.ExcelValue, test.GoValue, timeToExcelTime(test.GoValue))
-        }
-    }
+	for _, test := range trueExpectedInputList {
+		if test.ExcelValue != timeToExcelTime(test.GoValue) {
+			t.Fatalf("Expected %v from %v = true, got %v\n", test.ExcelValue, test.GoValue, timeToExcelTime(test.GoValue))
+		}
+	}
 }
 
 func TestTimeFromExcelTime(t *testing.T) {
-    trueExpectedInputList := []dateTest {
-        {0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)},
-        {60.0, time.Date(1900, 2, 28, 0, 0, 0, 0, time.UTC)},
-        {61.0, time.Date(1900, 3, 1, 0, 0, 0, 0, time.UTC)},
-        {41275.0, time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)},
-        {401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
-    }
+	trueExpectedInputList := []dateTest{
+		{0.0, time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC)},
+		{60.0, time.Date(1900, 2, 28, 0, 0, 0, 0, time.UTC)},
+		{61.0, time.Date(1900, 3, 1, 0, 0, 0, 0, time.UTC)},
+		{41275.0, time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC)},
+		{401769.0, time.Date(3000, 1, 1, 0, 0, 0, 0, time.UTC)},
+	}
 
-    for _, test := range trueExpectedInputList {
-        if test.GoValue != timeFromExcelTime(test.ExcelValue, false) {
-            t.Fatalf("Expected %v from %v = true, got %v\n", test.GoValue, test.ExcelValue, timeFromExcelTime(test.ExcelValue, false))
-        }
-    }
+	for _, test := range trueExpectedInputList {
+		if test.GoValue != timeFromExcelTime(test.ExcelValue, false) {
+			t.Fatalf("Expected %v from %v = true, got %v\n", test.GoValue, test.ExcelValue, timeFromExcelTime(test.ExcelValue, false))
+		}
+	}
 }

+ 24 - 1
excelize_test.go

@@ -162,6 +162,24 @@ func TestAddPicture(t *testing.T) {
 	if err != nil {
 		t.Log(err)
 	}
+	err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", "jpg", make([]byte, 1))
+	if err != nil {
+		t.Log(err)
+	}
+	// Test add picture to worksheet with invalid file data.
+	err = xlsx.AddPictureFromBytes("Sheet1", "G21", "", "Excel Logo", ".jpg", make([]byte, 1))
+	if err != nil {
+		t.Log(err)
+	}
+	file, err := ioutil.ReadFile("./test/images/excel.jpg")
+	if err != nil {
+		t.Error(err)
+	}
+	// Test add picture to worksheet from bytes.
+	err = xlsx.AddPictureFromBytes("Sheet1", "Q1", "", "Excel Logo", ".jpg", file)
+	if err != nil {
+		t.Log(err)
+	}
 	// Test write file to given path.
 	err = xlsx.SaveAs("./test/Book2.xlsx")
 	if err != nil {
@@ -211,8 +229,13 @@ func TestNewFile(t *testing.T) {
 	if err != nil {
 		t.Error(err)
 	}
-	// Test add picture to worksheet with invalid formatset
+	// Test add picture to worksheet without formatset.
 	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "")
+	if err != nil {
+		t.Error(err)
+	}
+	// Test add picture to worksheet with invalid formatset.
+	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", `{`)
 	if err != nil {
 		t.Log(err)
 	}

+ 51 - 13
picture.go

@@ -86,8 +86,6 @@ func parseFormatPictureSet(formatSet string) (*formatPicture, error) {
 // positioning is move and size with cells.
 func (f *File) AddPicture(sheet, cell, picture, format string) error {
 	var err error
-	var drawingHyperlinkRID int
-	var hyperlinkType string
 	// Check picture exists first.
 	if _, err = os.Stat(picture); os.IsNotExist(err) {
 		return err
@@ -96,14 +94,55 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
 	if !ok {
 		return errors.New("unsupported image extension")
 	}
-	readFile, err := os.Open(picture)
+	file, _ := ioutil.ReadFile(picture)
+	_, name := filepath.Split(picture)
+	return f.AddPictureFromBytes(sheet, cell, format, name, ext, file)
+}
+
+// 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:
+//
+//    package main
+//
+//    import (
+//        "fmt"
+//        _ "image/jpeg"
+//        "io/ioutil"
+//
+//        "github.com/360EntSecGroup-Skylar/excelize"
+//    )
+//
+//    func main() {
+//        xlsx := excelize.NewFile()
+//
+//        file, err := ioutil.ReadFile("./image1.jpg")
+//        if err != nil {
+//            fmt.Println(err)
+//        }
+//        err = xlsx.AddPictureFromBytes("Sheet1", "A2", "", "Excel Logo", ".jpg", file)
+//        if err != nil {
+//            fmt.Println(err)
+//        }
+//        err = xlsx.SaveAs("./Book1.xlsx")
+//        if err != nil {
+//            fmt.Println(err)
+//        }
+//    }
+//
+func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string, file []byte) error {
+	var err error
+	var drawingHyperlinkRID int
+	var hyperlinkType string
+	ext, ok := supportImageTypes[extension]
+	if !ok {
+		return errors.New("unsupported image extension")
+	}
+	formatSet, err := parseFormatPictureSet(format)
 	if err != nil {
 		return err
 	}
-	defer readFile.Close()
-	image, _, _ := image.DecodeConfig(readFile)
-	_, file := filepath.Split(picture)
-	formatSet, err := parseFormatPictureSet(format)
+	image, _, err := image.DecodeConfig(bytes.NewReader(file))
 	if err != nil {
 		return err
 	}
@@ -122,8 +161,8 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
 		}
 		drawingHyperlinkRID = f.addDrawingRelationships(drawingID, SourceRelationshipHyperLink, formatSet.Hyperlink, hyperlinkType)
 	}
-	f.addDrawingPicture(sheet, drawingXML, cell, file, image.Width, image.Height, drawingRID, drawingHyperlinkRID, formatSet)
-	f.addMedia(picture, ext)
+	f.addDrawingPicture(sheet, drawingXML, cell, name, image.Width, image.Height, drawingRID, drawingHyperlinkRID, formatSet)
+	f.addMedia(file, ext)
 	f.addContentTypePart(drawingID, "drawings")
 	return err
 }
@@ -317,12 +356,11 @@ func (f *File) countMedia() int {
 }
 
 // addMedia provides a function to add picture into folder xl/media/image by
-// given file name and extension name.
-func (f *File) addMedia(file, ext string) {
+// given file and extension name.
+func (f *File) addMedia(file []byte, ext string) {
 	count := f.countMedia()
-	dat, _ := ioutil.ReadFile(file)
 	media := "xl/media/image" + strconv.Itoa(count+1) + ext
-	f.XLSX[media] = dat
+	f.XLSX[media] = file
 }
 
 // setContentTypePartImageExtensions provides a function to set the content

+ 4 - 2
sheet.go

@@ -13,6 +13,7 @@ import (
 	"encoding/json"
 	"encoding/xml"
 	"errors"
+	"io/ioutil"
 	"os"
 	"path"
 	"strconv"
@@ -370,7 +371,7 @@ func (f *File) getSheetMap() map[string]string {
 }
 
 // SetSheetBackground provides a function to set background picture by given
-// worksheet name.
+// worksheet name and file path.
 func (f *File) SetSheetBackground(sheet, picture string) error {
 	var err error
 	// Check picture exists first.
@@ -384,7 +385,8 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
 	pictureID := f.countMedia() + 1
 	rID := f.addSheetRelationships(sheet, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext, "")
 	f.addSheetPicture(sheet, rID)
-	f.addMedia(picture, ext)
+	file, _ := ioutil.ReadFile(picture)
+	f.addMedia(file, ext)
 	f.setContentTypePartImageExtensions()
 	return err
 }

+ 8 - 0
xmlComments.go

@@ -61,3 +61,11 @@ type formatComment struct {
 	Author string `json:"author"`
 	Text   string `json:"text"`
 }
+
+// Comment directly maps the comment information.
+type Comment struct {
+	Author   string `json:"author"`
+	AuthorID int    `json:"author_id"`
+	Ref      string `json:"ref"`
+	Text     string `json:"text"`
+}