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

This commit is contained in:
Ri Xu 2017-02-28 12:59:04 +08:00
parent 4b8b410f52
commit 1e340aea40
4 changed files with 59 additions and 27 deletions

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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"`
}