Browse Source

Change function `AddPicture()` parameters to add add printing settings support. Related issue #27.

Ri Xu 8 years ago
parent
commit
1e340aea40
4 changed files with 59 additions and 27 deletions
  1. 4 4
      README.md
  2. 6 6
      excelize_test.go
  3. 38 17
      picture.go
  4. 11 0
      xmlDrawing.go

+ 4 - 4
README.md

@@ -109,17 +109,17 @@ func main() {
         os.Exit(1)
     }
     // Insert a picture.
-    err = xlsx.AddPicture("Sheet1", "A2", "/tmp/image1.gif", 0, 0, 1, 1)
+    err = xlsx.AddPicture("Sheet1", "A2", "/tmp/image1.gif", "")
     if err != nil {
         fmt.Println(err)
     }
     // Insert a picture to sheet with scaling.
-    err = xlsx.AddPicture("Sheet1", "D2", "/tmp/image2.jpg", 0, 0, 0.5, 0.5)
+    err = xlsx.AddPicture("Sheet1", "D2", "/tmp/image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`)
     if err != nil {
         fmt.Println(err)
     }
-    // Insert a picture offset in the cell.
-    err = xlsx.AddPicture("Sheet1", "H2", "/tmp/image3.png", 15, 10, 1, 1)
+    // Insert a picture offset in the cell with printing support.
+    err = xlsx.AddPicture("Sheet1", "H2", "/tmp/image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
     if err != nil {
         fmt.Println(err)
     }

+ 6 - 6
excelize_test.go

@@ -95,22 +95,22 @@ func TestAddPicture(t *testing.T) {
 		t.Log(err)
 	}
 	// Test add picture to sheet.
-	err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", 140, 120, 1, 1)
+	err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", `{"x_offset": 140, "y_offset": 120}`)
 	if err != nil {
 		t.Log(err)
 	}
 	// Test add picture to sheet with offset.
-	err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", 10, 10, 1, 1)
+	err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10}`)
 	if err != nil {
 		t.Log(err)
 	}
 	// Test add picture to sheet with invalid file path.
-	err = xlsx.AddPicture("Sheet1", "G21", "./test/images/excel.icon", 0, 0, 1, 1)
+	err = xlsx.AddPicture("Sheet1", "G21", "./test/images/excel.icon", "")
 	if err != nil {
 		t.Log(err)
 	}
 	// Test add picture to sheet with unsupport file type.
-	err = xlsx.AddPicture("Sheet1", "G21", "./test/Workbook1.xlsx", 0, 0, 1, 1)
+	err = xlsx.AddPicture("Sheet1", "G21", "./test/Workbook1.xlsx", "")
 	if err != nil {
 		t.Log(err)
 	}
@@ -157,11 +157,11 @@ func TestCreateFile(t *testing.T) {
 	xlsx.SetCellStr("SHEET1", "B20", "42")
 	xlsx.SetActiveSheet(0)
 	// Test add picture to sheet with scaling.
-	err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", 0, 0, 0.5, 0.5)
+	err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5}`)
 	if err != nil {
 		t.Log(err)
 	}
-	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", 0, 0, 1, 1)
+	err = xlsx.AddPicture("Sheet1", "C2", "./test/images/excel.png", "")
 	if err != nil {
 		t.Log(err)
 	}

+ 38 - 17
picture.go

@@ -2,6 +2,7 @@ package excelize
 
 import (
 	"bytes"
+	"encoding/json"
 	"encoding/xml"
 	"errors"
 	"fmt"
@@ -14,8 +15,25 @@ import (
 	"strings"
 )
 
-// AddPicture provides the method to add picture in a sheet by given offset
-// (xAxis, yAxis), scale (xScale, yScale) and file path. For example:
+// parseFormatPictureSet provides function to parse the format settings of the
+// picture with default value.
+func parseFormatPictureSet(formatSet string) *xlsxFormatPicture {
+	format := xlsxFormatPicture{
+		FPrintsWithSheet: true,
+		FLocksWithSheet:  false,
+		NoChangeAspect:   false,
+		OffsetX:          0,
+		OffsetY:          0,
+		XScale:           1.0,
+		YScale:           1.0,
+	}
+	json.Unmarshal([]byte(formatSet), &format)
+	return &format
+}
+
+// AddPicture provides the method to add picture in a sheet by given picture
+// format set (such as offset, scale, aspect ratio setting and print settings)
+// and file path. For example:
 //
 //    package main
 //
@@ -32,17 +50,17 @@ import (
 //    func main() {
 //        xlsx := excelize.CreateFile()
 //        // Insert a picture.
-//        err := xlsx.AddPicture("Sheet1", "A2", "/tmp/image1.jpg", 0, 0, 1, 1)
+//        err := xlsx.AddPicture("Sheet1", "A2", "/tmp/image1.jpg", "")
 //        if err != nil {
 //            fmt.Println(err)
 //        }
 //        // Insert a picture to sheet with scaling.
-//        err = xlsx.AddPicture("Sheet1", "D2", "/tmp/image1.png", 0, 0, 0.5, 0.5)
+//        err = xlsx.AddPicture("Sheet1", "D2", "/tmp/image1.png", `{"x_scale": 0.5, "y_scale": 0.5}`)
 //        if err != nil {
 //            fmt.Println(err)
 //        }
-//        // Insert a picture offset in the cell.
-//        err = xlsx.AddPicture("Sheet1", "H2", "/tmp/image3.gif", 15, 10, 1, 1)
+//        // Insert a picture offset in the cell with printing support.
+//        err = xlsx.AddPicture("Sheet1", "H2", "/tmp/image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
 //        if err != nil {
 //            fmt.Println(err)
 //        }
@@ -53,7 +71,7 @@ import (
 //        }
 //    }
 //
-func (f *File) AddPicture(sheet, cell, picture string, offsetX, offsetY int, xScale, yScale float64) error {
+func (f *File) AddPicture(sheet, cell, picture, format string) error {
 	var supportTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png"}
 	var err error
 	// Check picture exists first.
@@ -67,6 +85,7 @@ func (f *File) AddPicture(sheet, cell, picture string, offsetX, offsetY int, xSc
 	readFile, _ := os.Open(picture)
 	image, _, err := image.DecodeConfig(readFile)
 	_, file := filepath.Split(picture)
+	formatSet := parseFormatPictureSet(format)
 	// Read sheet data.
 	var xlsx xlsxWorksheet
 	name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
@@ -89,7 +108,7 @@ func (f *File) AddPicture(sheet, cell, picture string, offsetX, offsetY int, xSc
 		f.addSheetDrawing(sheet, rID)
 	}
 	drawingRID = f.addDrawingRelationships(drawingID, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext)
-	f.addDrawing(sheet, drawingXML, cell, file, offsetX, offsetY, image.Width, image.Height, drawingRID, xScale, yScale)
+	f.addDrawing(sheet, drawingXML, cell, file, image.Width, image.Height, drawingRID, formatSet)
 	f.addMedia(picture, ext)
 	f.addDrawingContentTypePart(drawingID)
 	return err
@@ -175,15 +194,15 @@ func (f *File) countDrawings() int {
 // yAxis, file name and relationship index. In order to solve the problem that
 // the label structure is changed after serialization and deserialization, two
 // different structures: decodeWsDr and encodeWsDr are defined.
-func (f *File) addDrawing(sheet, drawingXML, cell, file string, offsetX, offsetY, width, height, rID int, xScale, yScale float64) {
+func (f *File) addDrawing(sheet, drawingXML, cell, file string, width, height, rID int, formatSet *xlsxFormatPicture) {
 	cell = strings.ToUpper(cell)
 	fromCol := string(strings.Map(letterOnlyMapF, cell))
 	fromRow, _ := strconv.Atoi(strings.Map(intOnlyMapF, cell))
 	row := fromRow - 1
 	col := titleToNumber(fromCol)
-	width = int(float64(width) * xScale)
-	height = int(float64(height) * yScale)
-	colStart, rowStart, _, _, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, col, row, offsetX, offsetY, width, height)
+	width = int(float64(width) * formatSet.XScale)
+	height = int(float64(height) * formatSet.YScale)
+	colStart, rowStart, _, _, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, col, row, formatSet.OffsetX, formatSet.OffsetY, width, height)
 	content := encodeWsDr{}
 	content.WsDr.A = NameSpaceDrawingML
 	content.WsDr.Xdr = NameSpaceSpreadSheetDrawing
@@ -204,9 +223,9 @@ func (f *File) addDrawing(sheet, drawingXML, cell, file string, offsetX, offsetY
 	twoCellAnchor.EditAs = "oneCell"
 	from := xlsxFrom{}
 	from.Col = colStart
-	from.ColOff = offsetX * EMU
+	from.ColOff = formatSet.OffsetX * EMU
 	from.Row = rowStart
-	from.RowOff = offsetY * EMU
+	from.RowOff = formatSet.OffsetY * EMU
 	to := xlsxTo{}
 	to.Col = colEnd
 	to.ColOff = x2 * EMU
@@ -215,7 +234,7 @@ func (f *File) addDrawing(sheet, drawingXML, cell, file string, offsetX, offsetY
 	twoCellAnchor.From = &from
 	twoCellAnchor.To = &to
 	pic := xlsxPic{}
-	pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = false
+	pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = formatSet.NoChangeAspect
 	pic.NvPicPr.CNvPr.ID = cNvPrID
 	pic.NvPicPr.CNvPr.Descr = file
 	pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
@@ -225,8 +244,8 @@ func (f *File) addDrawing(sheet, drawingXML, cell, file string, offsetX, offsetY
 
 	twoCellAnchor.Pic = &pic
 	twoCellAnchor.ClientData = &xlsxClientData{
-		FLocksWithSheet:  false,
-		FPrintsWithSheet: false,
+		FLocksWithSheet:  formatSet.FLocksWithSheet,
+		FPrintsWithSheet: formatSet.FPrintsWithSheet,
 	}
 	content.WsDr.TwoCellAnchor = append(content.WsDr.TwoCellAnchor, &twoCellAnchor)
 	output, err := xml.Marshal(content)
@@ -291,6 +310,8 @@ func (f *File) addMedia(file string, ext string) {
 	f.XLSX[media] = string(dat)
 }
 
+// setContentTypePartImageExtensions provides function to set the content type
+// for relationship parts and the Main Document part.
 func (f *File) setContentTypePartImageExtensions() {
 	var imageTypes = map[string]bool{"jpeg": false, "png": false, "gif": false}
 	var content xlsxTypes

+ 11 - 0
xmlDrawing.go

@@ -187,3 +187,14 @@ type xlsxWsDr struct {
 type encodeWsDr struct {
 	WsDr xlsxWsDr `xml:"xdr:wsDr"`
 }
+
+// xlsxFormatPicture directly maps the format settings of the picture.
+type xlsxFormatPicture struct {
+	FPrintsWithSheet bool    `json:"print_obj"`
+	FLocksWithSheet  bool    `json:"locked"`
+	NoChangeAspect   bool    `json:"lock_aspect_ratio"`
+	OffsetX          int     `json:"x_offset"`
+	OffsetY          int     `json:"y_offset"`
+	XScale           float64 `json:"x_scale"`
+	YScale           float64 `json:"y_scale"`
+}