Skip to content

Commit

Permalink
- Add a hyperlink to an image support for the function AddPicture()
Browse files Browse the repository at this point in the history
…, relate issue #185;

- go test and document has been updated.
  • Loading branch information
xuri committed Feb 3, 2018
1 parent 638bd44 commit 7621927
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 22 deletions.
2 changes: 1 addition & 1 deletion chart.go
Expand Up @@ -258,7 +258,7 @@ func (f *File) AddChart(sheet, cell, format string) {
chartID := f.countCharts() + 1
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml")
drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
f.addDrawingChart(sheet, drawingXML, cell, 480, 290, drawingRID, &formatSet.Format)
f.addChart(formatSet)
f.addContentTypePart(chartID, "chart")
Expand Down
12 changes: 6 additions & 6 deletions excelize_test.go
Expand Up @@ -132,22 +132,22 @@ func TestAddPicture(t *testing.T) {
if err != nil {
t.Log(err)
}
// Test add picture to sheet.
err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", `{"x_offset": 140, "y_offset": 120}`)
// Test add picture to worksheet with offset and location hyperlink.
err = xlsx.AddPicture("Sheet2", "I9", "./test/images/excel.jpg", `{"x_offset": 140, "y_offset": 120, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
if err != nil {
t.Log(err)
}
// Test add picture to sheet with offset.
err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10}`)
// Test add picture to worksheet with offset and external hyperlink.
err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External"}`)
if err != nil {
t.Log(err)
}
// Test add picture to sheet with invalid file path.
// Test add picture to worksheet with invalid file path.
err = xlsx.AddPicture("Sheet1", "G21", "./test/images/excel.icon", "")
if err != nil {
t.Log(err)
}
// Test add picture to sheet with unsupport file type.
// Test add picture to worksheet with unsupport file type.
err = xlsx.AddPicture("Sheet1", "G21", "./test/Workbook1.xlsx", "")
if err != nil {
t.Log(err)
Expand Down
41 changes: 30 additions & 11 deletions picture.go
Expand Up @@ -52,13 +52,13 @@ func parseFormatPictureSet(formatSet string) *formatPicture {
// if err != nil {
// fmt.Println(err)
// }
// // Insert a picture to sheet with scaling.
// err = xlsx.AddPicture("Sheet1", "D2", "./image1.png", `{"x_scale": 0.5, "y_scale": 0.5}`)
// // Insert a picture scaling in the cell with location hyperlink.
// err = xlsx.AddPicture("Sheet1", "D2", "./image1.png", `{"x_scale": 0.5, "y_scale": 0.5, "hyperlink": "#Sheet2!D8", "hyperlink_type": "Location"}`)
// if err != nil {
// fmt.Println(err)
// }
// // Insert a picture offset in the cell with printing support.
// err = xlsx.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
// // Insert a picture offset in the cell with external hyperlink and printing support.
// err = xlsx.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
// if err != nil {
// fmt.Println(err)
// }
Expand All @@ -68,8 +68,13 @@ func parseFormatPictureSet(formatSet string) *formatPicture {
// }
// }
//
// LinkType defines two types of hyperlink "External" for web site or
// "Location" for moving to one of cell in this workbook. When the
// "hyperlink_type" is "Location", coordinates need to start with "#".
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
Expand All @@ -89,8 +94,15 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
pictureID := f.countMedia() + 1
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext)
f.addDrawingPicture(sheet, drawingXML, cell, file, image.Width, image.Height, drawingRID, formatSet)
drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext, hyperlinkType)
// Add picture with hyperlink.
if formatSet.Hyperlink != "" && formatSet.HyperlinkType != "" {
if formatSet.HyperlinkType == "External" {
hyperlinkType = formatSet.HyperlinkType
}
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.addContentTypePart(drawingID, "drawings")
return err
Expand Down Expand Up @@ -191,7 +203,7 @@ func (f *File) countDrawings() int {
// addDrawingPicture provides 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 string, width, height, rID int, formatSet *formatPicture) {
func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, height, rID, hyperlinkRID int, formatSet *formatPicture) {
cell = strings.ToUpper(cell)
fromCol := string(strings.Map(letterOnlyMapF, cell))
fromRow, _ := strconv.Atoi(strings.Map(intOnlyMapF, cell))
Expand Down Expand Up @@ -223,6 +235,12 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
pic.NvPicPr.CNvPr.ID = f.countCharts() + f.countMedia() + 1
pic.NvPicPr.CNvPr.Descr = file
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
if hyperlinkRID != 0 {
pic.NvPicPr.CNvPr.HlinkClick = &xlsxHlinkClick{
R: SourceRelationship,
RID: "rId" + strconv.Itoa(hyperlinkRID),
}
}
pic.BlipFill.Blip.R = SourceRelationship
pic.BlipFill.Blip.Embed = "rId" + strconv.Itoa(rID)
pic.SpPr.PrstGeom.Prst = "rect"
Expand All @@ -240,7 +258,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
// addDrawingRelationships provides function to add image part relationships in
// the file xl/drawings/_rels/drawing%d.xml.rels by given drawing index,
// relationship type and target.
func (f *File) addDrawingRelationships(index int, relType, target string) int {
func (f *File) addDrawingRelationships(index int, relType, target, targetMode string) int {
var rels = "xl/drawings/_rels/drawing" + strconv.Itoa(index) + ".xml.rels"
var drawingRels xlsxWorkbookRels
var rID = 1
Expand All @@ -256,9 +274,10 @@ func (f *File) addDrawingRelationships(index int, relType, target string) int {
ID.WriteString(strconv.Itoa(rID))
}
drawingRels.Relationships = append(drawingRels.Relationships, xlsxWorkbookRelation{
ID: ID.String(),
Type: relType,
Target: target,
ID: ID.String(),
Type: relType,
Target: target,
TargetMode: targetMode,
})
output, _ := xml.Marshal(drawingRels)
f.saveFileList(rels, string(output))
Expand Down
26 changes: 22 additions & 4 deletions xmlDrawing.go
Expand Up @@ -30,10 +30,26 @@ var supportImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpe
// element specifies non-visual canvas properties. This allows for additional
// information that does not affect the appearance of the picture to be stored.
type xlsxCNvPr struct {
ID int `xml:"id,attr"`
Name string `xml:"name,attr"`
Descr string `xml:"descr,attr"`
Title string `xml:"title,attr,omitempty"`
ID int `xml:"id,attr"`
Name string `xml:"name,attr"`
Descr string `xml:"descr,attr"`
Title string `xml:"title,attr,omitempty"`
HlinkClick *xlsxHlinkClick `xml:"a:hlinkClick"`
}

// xlsxHlinkClick (Click Hyperlink) Specifies the on-click hyperlink
// information to be applied to a run of text. When the hyperlink text is
// clicked the link is fetched.
type xlsxHlinkClick struct {
R string `xml:"xmlns:r,attr,omitempty"`
RID string `xml:"r:id,attr,omitempty"`
InvalidURL string `xml:"invalidUrl,attr,omitempty"`
Action string `xml:"action,attr,omitempty"`
TgtFrame string `xml:"tgtFrame,attr,omitempty"`
Tooltip string `xml:"tooltip,attr,omitempty"`
History bool `xml:"history,attr,omitempty"`
HighlightClick bool `xml:"highlightClick,attr,omitempty"`
EndSnd bool `xml:"endSnd,attr,omitempty"`
}

// xlsxPicLocks directly maps the picLocks (Picture Locks). This element
Expand Down Expand Up @@ -342,6 +358,8 @@ type formatPicture struct {
OffsetY int `json:"y_offset"`
XScale float64 `json:"x_scale"`
YScale float64 `json:"y_scale"`
Hyperlink string `json:"hyperlink"`
HyperlinkType string `json:"hyperlink_type"`
}

// formatShape directly maps the format settings of the shape.
Expand Down

0 comments on commit 7621927

Please sign in to comment.