forked from p30928647/excelize
- Initialize shape support: new function `AddShape()` added. Relate issue #38;
- Drawing `nvPicPr` element ID property calculation changed; - go test updated
This commit is contained in:
parent
46b8c46d91
commit
7f30a6c943
12
README.md
12
README.md
|
@ -45,7 +45,7 @@ func main() {
|
|||
// Set active sheet of the workbook.
|
||||
xlsx.SetActiveSheet(2)
|
||||
// Save xlsx file by the given path.
|
||||
err := xlsx.WriteTo("/tmp/Workbook.xlsx")
|
||||
err := xlsx.WriteTo("./Workbook.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
|
@ -69,7 +69,7 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
xlsx, err := excelize.OpenFile("/tmp/Workbook.xlsx")
|
||||
xlsx, err := excelize.OpenFile("./Workbook.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
|
@ -142,23 +142,23 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
xlsx, err := excelize.OpenFile("/tmp/Workbook.xlsx")
|
||||
xlsx, err := excelize.OpenFile("./Workbook.xlsx")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// Insert a picture.
|
||||
err = xlsx.AddPicture("Sheet1", "A2", "/tmp/image1.gif", "")
|
||||
err = xlsx.AddPicture("Sheet1", "A2", "./image1.gif", "")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Insert a picture to sheet with scaling.
|
||||
err = xlsx.AddPicture("Sheet1", "D2", "/tmp/image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`)
|
||||
err = xlsx.AddPicture("Sheet1", "D2", "./image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// 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}`)
|
||||
err = xlsx.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
|
277
chart.go
277
chart.go
|
@ -3,7 +3,6 @@ package excelize
|
|||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -57,8 +56,8 @@ func parseFormatChartSet(formatSet string) *formatChart {
|
|||
|
||||
// AddChart provides the method to add chart in a sheet by given chart format
|
||||
// set (such as offset, scale, aspect ratio setting and print settings) and
|
||||
// properties set. Only support "pie" and "3Dpie" type chart currently. For
|
||||
// example, create 3D bar chart with data Sheet1!$A$29:$D$32:
|
||||
// properties set. For example, create 3D bar chart with data
|
||||
// Sheet1!$A$29:$D$32:
|
||||
//
|
||||
// package main
|
||||
//
|
||||
|
@ -81,7 +80,7 @@ func parseFormatChartSet(formatSet string) *formatChart {
|
|||
// }
|
||||
// xlsx.AddChart("SHEET1", "F2", `{"type":"bar3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Line Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
|
||||
// // Save xlsx file by the given path.
|
||||
// err := xlsx.WriteTo("./tmp/Workbook.xlsx")
|
||||
// err := xlsx.WriteTo("./Workbook.xlsx")
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// os.Exit(1)
|
||||
|
@ -235,128 +234,126 @@ func (f *File) addChartContentTypePart(index int) {
|
|||
func (f *File) addChart(formatSet *formatChart) {
|
||||
count := f.countCharts()
|
||||
xlsxChartSpace := xlsxChartSpace{
|
||||
ChartSpace: cChartSpace{
|
||||
XMLNSc: NameSpaceDrawingMLChart,
|
||||
XMLNSa: NameSpaceDrawingML,
|
||||
XMLNSr: SourceRelationship,
|
||||
XMLNSc16r2: SourceRelationshipChart201506,
|
||||
Date1904: &attrValBool{Val: false},
|
||||
Lang: &attrValString{Val: "en-US"},
|
||||
RoundedCorners: &attrValBool{Val: false},
|
||||
Chart: cChart{
|
||||
Title: &cTitle{
|
||||
Tx: cTx{
|
||||
Rich: &cRich{
|
||||
P: aP{
|
||||
PPr: aPPr{
|
||||
DefRPr: aDefRPr{
|
||||
Kern: 1200,
|
||||
Strike: "noStrike",
|
||||
U: "none",
|
||||
Sz: 1400,
|
||||
SolidFill: &aSolidFill{
|
||||
SchemeClr: &aSchemeClr{
|
||||
Val: "tx1",
|
||||
LumMod: &attrValInt{
|
||||
Val: 65000,
|
||||
},
|
||||
LumOff: &attrValInt{
|
||||
Val: 35000,
|
||||
},
|
||||
},
|
||||
},
|
||||
Ea: &aEa{
|
||||
Typeface: "+mn-ea",
|
||||
},
|
||||
Cs: &aCs{
|
||||
Typeface: "+mn-cs",
|
||||
},
|
||||
Latin: &aLatin{
|
||||
Typeface: "+mn-lt",
|
||||
},
|
||||
},
|
||||
},
|
||||
R: &aR{
|
||||
RPr: aRPr{
|
||||
Lang: "en-US",
|
||||
AltLang: "en-US",
|
||||
},
|
||||
T: formatSet.Title.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
TxPr: cTxPr{
|
||||
XMLNSc: NameSpaceDrawingMLChart,
|
||||
XMLNSa: NameSpaceDrawingML,
|
||||
XMLNSr: SourceRelationship,
|
||||
XMLNSc16r2: SourceRelationshipChart201506,
|
||||
Date1904: &attrValBool{Val: false},
|
||||
Lang: &attrValString{Val: "en-US"},
|
||||
RoundedCorners: &attrValBool{Val: false},
|
||||
Chart: cChart{
|
||||
Title: &cTitle{
|
||||
Tx: cTx{
|
||||
Rich: &cRich{
|
||||
P: aP{
|
||||
PPr: aPPr{
|
||||
PPr: &aPPr{
|
||||
DefRPr: aDefRPr{
|
||||
Kern: 1200,
|
||||
U: "none",
|
||||
Sz: 14000,
|
||||
Strike: "noStrike",
|
||||
U: "none",
|
||||
Sz: 1400,
|
||||
SolidFill: &aSolidFill{
|
||||
SchemeClr: &aSchemeClr{
|
||||
Val: "tx1",
|
||||
LumMod: &attrValInt{
|
||||
Val: 65000,
|
||||
},
|
||||
LumOff: &attrValInt{
|
||||
Val: 35000,
|
||||
},
|
||||
},
|
||||
},
|
||||
Ea: &aEa{
|
||||
Typeface: "+mn-ea",
|
||||
},
|
||||
Cs: &aCs{
|
||||
Typeface: "+mn-cs",
|
||||
},
|
||||
Latin: &aLatin{
|
||||
Typeface: "+mn-lt",
|
||||
},
|
||||
},
|
||||
},
|
||||
EndParaRPr: &aEndParaRPr{
|
||||
Lang: "en-US",
|
||||
R: &aR{
|
||||
RPr: aRPr{
|
||||
Lang: "en-US",
|
||||
AltLang: "en-US",
|
||||
},
|
||||
T: formatSet.Title.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
View3D: &cView3D{
|
||||
RotX: &attrValInt{Val: chartView3DRotX[formatSet.Type]},
|
||||
RotY: &attrValInt{Val: chartView3DRotY[formatSet.Type]},
|
||||
DepthPercent: &attrValInt{Val: chartView3DDepthPercent[formatSet.Type]},
|
||||
RAngAx: &attrValInt{Val: chartView3DRAngAx[formatSet.Type]},
|
||||
},
|
||||
Floor: &cThicknessSpPr{
|
||||
Thickness: &attrValInt{Val: 0},
|
||||
},
|
||||
SideWall: &cThicknessSpPr{
|
||||
Thickness: &attrValInt{Val: 0},
|
||||
},
|
||||
BackWall: &cThicknessSpPr{
|
||||
Thickness: &attrValInt{Val: 0},
|
||||
},
|
||||
PlotArea: &cPlotArea{},
|
||||
Legend: &cLegend{
|
||||
LegendPos: &attrValString{Val: chartLegendPosition[formatSet.Legend.Position]},
|
||||
Overlay: &attrValBool{Val: false},
|
||||
TxPr: cTxPr{
|
||||
P: aP{
|
||||
PPr: &aPPr{
|
||||
DefRPr: aDefRPr{
|
||||
Kern: 1200,
|
||||
U: "none",
|
||||
Sz: 14000,
|
||||
Strike: "noStrike",
|
||||
},
|
||||
},
|
||||
EndParaRPr: &aEndParaRPr{
|
||||
Lang: "en-US",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
View3D: &cView3D{
|
||||
RotX: &attrValInt{Val: chartView3DRotX[formatSet.Type]},
|
||||
RotY: &attrValInt{Val: chartView3DRotY[formatSet.Type]},
|
||||
DepthPercent: &attrValInt{Val: chartView3DDepthPercent[formatSet.Type]},
|
||||
RAngAx: &attrValInt{Val: chartView3DRAngAx[formatSet.Type]},
|
||||
},
|
||||
Floor: &cThicknessSpPr{
|
||||
Thickness: &attrValInt{Val: 0},
|
||||
},
|
||||
SideWall: &cThicknessSpPr{
|
||||
Thickness: &attrValInt{Val: 0},
|
||||
},
|
||||
BackWall: &cThicknessSpPr{
|
||||
Thickness: &attrValInt{Val: 0},
|
||||
},
|
||||
PlotArea: &cPlotArea{},
|
||||
Legend: &cLegend{
|
||||
LegendPos: &attrValString{Val: chartLegendPosition[formatSet.Legend.Position]},
|
||||
Overlay: &attrValBool{Val: false},
|
||||
},
|
||||
|
||||
PlotVisOnly: &attrValBool{Val: false},
|
||||
DispBlanksAs: &attrValString{Val: formatSet.ShowBlanksAs},
|
||||
ShowDLblsOverMax: &attrValBool{Val: false},
|
||||
PlotVisOnly: &attrValBool{Val: false},
|
||||
DispBlanksAs: &attrValString{Val: formatSet.ShowBlanksAs},
|
||||
ShowDLblsOverMax: &attrValBool{Val: false},
|
||||
},
|
||||
SpPr: &cSpPr{
|
||||
SolidFill: &aSolidFill{
|
||||
SchemeClr: &aSchemeClr{Val: "bg1"},
|
||||
},
|
||||
SpPr: &cSpPr{
|
||||
Ln: &aLn{
|
||||
W: 9525,
|
||||
Cap: "flat",
|
||||
Cmpd: "sng",
|
||||
Algn: "ctr",
|
||||
SolidFill: &aSolidFill{
|
||||
SchemeClr: &aSchemeClr{Val: "bg1"},
|
||||
},
|
||||
Ln: &aLn{
|
||||
W: 9525,
|
||||
Cap: "flat",
|
||||
Cmpd: "sng",
|
||||
Algn: "ctr",
|
||||
SolidFill: &aSolidFill{
|
||||
SchemeClr: &aSchemeClr{Val: "tx1",
|
||||
LumMod: &attrValInt{
|
||||
Val: 15000,
|
||||
},
|
||||
LumOff: &attrValInt{
|
||||
Val: 85000,
|
||||
},
|
||||
SchemeClr: &aSchemeClr{Val: "tx1",
|
||||
LumMod: &attrValInt{
|
||||
Val: 15000,
|
||||
},
|
||||
LumOff: &attrValInt{
|
||||
Val: 85000,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
PrintSettings: &cPrintSettings{
|
||||
PageMargins: &cPageMargins{
|
||||
B: 0.75,
|
||||
L: 0.7,
|
||||
R: 0.7,
|
||||
T: 0.7,
|
||||
Header: 0.3,
|
||||
Footer: 0.3,
|
||||
},
|
||||
},
|
||||
PrintSettings: &cPrintSettings{
|
||||
PageMargins: &cPageMargins{
|
||||
B: 0.75,
|
||||
L: 0.7,
|
||||
R: 0.7,
|
||||
T: 0.7,
|
||||
Header: 0.3,
|
||||
Footer: 0.3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -370,11 +367,11 @@ func (f *File) addChart(formatSet *formatChart) {
|
|||
Radar: f.drawRadarChart,
|
||||
Scatter: f.drawScatterChart,
|
||||
}
|
||||
xlsxChartSpace.ChartSpace.Chart.PlotArea = plotAreaFunc[formatSet.Type](formatSet)
|
||||
xlsxChartSpace.Chart.PlotArea = plotAreaFunc[formatSet.Type](formatSet)
|
||||
|
||||
chart, _ := xml.Marshal(xlsxChartSpace)
|
||||
media := "xl/charts/chart" + strconv.Itoa(count+1) + ".xml"
|
||||
f.saveFileList(media, string(chart[16:len(chart)-17]))
|
||||
f.saveFileList(media, string(chart))
|
||||
}
|
||||
|
||||
// drawBarChart provides function to draw the c:plotArea element for bar chart
|
||||
|
@ -809,7 +806,7 @@ func (f *File) drawPlotAreaTxPr() *cTxPr {
|
|||
AnchorCtr: true,
|
||||
},
|
||||
P: aP{
|
||||
PPr: aPPr{
|
||||
PPr: &aPPr{
|
||||
DefRPr: aDefRPr{
|
||||
Sz: 900,
|
||||
B: false,
|
||||
|
@ -846,29 +843,29 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
|
|||
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 = NameSpaceDrawingMLSpreadSheet
|
||||
content := xlsxWsDr{}
|
||||
content.A = NameSpaceDrawingML
|
||||
content.Xdr = NameSpaceDrawingMLSpreadSheet
|
||||
cNvPrID := 1
|
||||
_, ok := f.XLSX[drawingXML]
|
||||
if ok { // Append Model
|
||||
decodeWsDr := decodeWsDr{}
|
||||
xml.Unmarshal([]byte(f.readXML(drawingXML)), &decodeWsDr)
|
||||
cNvPrID = len(decodeWsDr.TwoCellAnchor) + 1
|
||||
cNvPrID = len(decodeWsDr.OneCellAnchor) + len(decodeWsDr.TwoCellAnchor) + 1
|
||||
for _, v := range decodeWsDr.OneCellAnchor {
|
||||
content.WsDr.OneCellAnchor = append(content.WsDr.OneCellAnchor, &xlsxCellAnchor{
|
||||
content.OneCellAnchor = append(content.OneCellAnchor, &xdrCellAnchor{
|
||||
EditAs: v.EditAs,
|
||||
GraphicFrame: v.Content,
|
||||
})
|
||||
}
|
||||
for _, v := range decodeWsDr.TwoCellAnchor {
|
||||
content.WsDr.TwoCellAnchor = append(content.WsDr.TwoCellAnchor, &xlsxCellAnchor{
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &xdrCellAnchor{
|
||||
EditAs: v.EditAs,
|
||||
GraphicFrame: v.Content,
|
||||
})
|
||||
}
|
||||
}
|
||||
twoCellAnchor := xlsxCellAnchor{}
|
||||
twoCellAnchor := xdrCellAnchor{}
|
||||
twoCellAnchor.EditAs = "oneCell"
|
||||
from := xlsxFrom{}
|
||||
from.Col = colStart
|
||||
|
@ -883,39 +880,31 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
|
|||
twoCellAnchor.From = &from
|
||||
twoCellAnchor.To = &to
|
||||
|
||||
graphicFrame := graphicFrame{
|
||||
GraphicFrame: &xlsxGraphicFrame{
|
||||
NvGraphicFramePr: xlsxNvGraphicFramePr{
|
||||
CNvPr: &xlsxCNvPr{
|
||||
ID: cNvPrID,
|
||||
Name: "Chart " + strconv.Itoa(cNvPrID),
|
||||
},
|
||||
graphicFrame := xlsxGraphicFrame{
|
||||
NvGraphicFramePr: xlsxNvGraphicFramePr{
|
||||
CNvPr: &xlsxCNvPr{
|
||||
ID: f.countCharts() + f.countMedia() + 1,
|
||||
Name: "Chart " + strconv.Itoa(cNvPrID),
|
||||
},
|
||||
Graphic: &xlsxGraphic{
|
||||
GraphicData: &xlsxGraphicData{
|
||||
URI: NameSpaceDrawingMLChart,
|
||||
Chart: &xlsxChart{
|
||||
C: NameSpaceDrawingMLChart,
|
||||
R: SourceRelationship,
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
},
|
||||
},
|
||||
Graphic: &xlsxGraphic{
|
||||
GraphicData: &xlsxGraphicData{
|
||||
URI: NameSpaceDrawingMLChart,
|
||||
Chart: &xlsxChart{
|
||||
C: NameSpaceDrawingMLChart,
|
||||
R: SourceRelationship,
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
graphic, _ := xml.Marshal(graphicFrame)
|
||||
twoCellAnchor.GraphicFrame = string(graphic[14 : len(graphic)-15])
|
||||
twoCellAnchor.ClientData = &xlsxClientData{
|
||||
twoCellAnchor.GraphicFrame = string(graphic)
|
||||
twoCellAnchor.ClientData = &xdrClientData{
|
||||
FLocksWithSheet: formatSet.FLocksWithSheet,
|
||||
FPrintsWithSheet: formatSet.FPrintsWithSheet,
|
||||
}
|
||||
content.WsDr.TwoCellAnchor = append(content.WsDr.TwoCellAnchor, &twoCellAnchor)
|
||||
output, err := xml.Marshal(content)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Create replacer with pairs as arguments and replace all pairs.
|
||||
r := strings.NewReplacer("<encodeWsDr>", "", "</encodeWsDr>", "")
|
||||
result := r.Replace(string(output))
|
||||
f.saveFileList(drawingXML, result)
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
|
||||
output, _ := xml.Marshal(content)
|
||||
f.saveFileList(drawingXML, string(output))
|
||||
}
|
||||
|
|
|
@ -486,6 +486,19 @@ func TestAddTable(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAddShape(t *testing.T) {
|
||||
xlsx, err := OpenFile("./test/Workbook_2.xlsx")
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
xlsx.AddShape("Sheet1", "A30", `{"type":"rect","text":"Rectangle Shape"}`)
|
||||
xlsx.AddShape("Sheet3", "H1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "height": 90}`)
|
||||
err = xlsx.Save()
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddChart(t *testing.T) {
|
||||
xlsx, err := OpenFile("./test/Workbook1.xlsx")
|
||||
if err != nil {
|
||||
|
|
51
picture.go
51
picture.go
|
@ -5,7 +5,6 @@ import (
|
|||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -50,21 +49,21 @@ func parseFormatPictureSet(formatSet string) *formatPicture {
|
|||
// func main() {
|
||||
// xlsx := excelize.CreateFile()
|
||||
// // Insert a picture.
|
||||
// err := xlsx.AddPicture("Sheet1", "A2", "/tmp/image1.jpg", "")
|
||||
// err := xlsx.AddPicture("Sheet1", "A2", "./image1.jpg", "")
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// }
|
||||
// // Insert a picture to sheet with scaling.
|
||||
// err = xlsx.AddPicture("Sheet1", "D2", "/tmp/image1.png", `{"x_scale": 0.5, "y_scale": 0.5}`)
|
||||
// err = xlsx.AddPicture("Sheet1", "D2", "./image1.png", `{"x_scale": 0.5, "y_scale": 0.5}`)
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// }
|
||||
// // 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}`)
|
||||
// err = xlsx.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// }
|
||||
// err = xlsx.WriteTo("/tmp/Workbook.xlsx")
|
||||
// err = xlsx.WriteTo("./Workbook.xlsx")
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// os.Exit(1)
|
||||
|
@ -135,10 +134,7 @@ func (f *File) addSheetRelationships(sheet, relType, target, targetMode string)
|
|||
Target: target,
|
||||
TargetMode: targetMode,
|
||||
})
|
||||
output, err := xml.Marshal(sheetRels)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
output, _ := xml.Marshal(sheetRels)
|
||||
f.saveFileList(rels, string(output))
|
||||
return rID
|
||||
}
|
||||
|
@ -187,29 +183,29 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
|
|||
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 = NameSpaceDrawingMLSpreadSheet
|
||||
content := xlsxWsDr{}
|
||||
content.A = NameSpaceDrawingML
|
||||
content.Xdr = NameSpaceDrawingMLSpreadSheet
|
||||
cNvPrID := 1
|
||||
_, ok := f.XLSX[drawingXML]
|
||||
if ok { // Append Model
|
||||
decodeWsDr := decodeWsDr{}
|
||||
xml.Unmarshal([]byte(f.readXML(drawingXML)), &decodeWsDr)
|
||||
cNvPrID = len(decodeWsDr.TwoCellAnchor) + 1
|
||||
cNvPrID = len(decodeWsDr.OneCellAnchor) + len(decodeWsDr.TwoCellAnchor) + 1
|
||||
for _, v := range decodeWsDr.OneCellAnchor {
|
||||
content.WsDr.OneCellAnchor = append(content.WsDr.OneCellAnchor, &xlsxCellAnchor{
|
||||
content.OneCellAnchor = append(content.OneCellAnchor, &xdrCellAnchor{
|
||||
EditAs: v.EditAs,
|
||||
GraphicFrame: v.Content,
|
||||
})
|
||||
}
|
||||
for _, v := range decodeWsDr.TwoCellAnchor {
|
||||
content.WsDr.TwoCellAnchor = append(content.WsDr.TwoCellAnchor, &xlsxCellAnchor{
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &xdrCellAnchor{
|
||||
EditAs: v.EditAs,
|
||||
GraphicFrame: v.Content,
|
||||
})
|
||||
}
|
||||
}
|
||||
twoCellAnchor := xlsxCellAnchor{}
|
||||
twoCellAnchor := xdrCellAnchor{}
|
||||
twoCellAnchor.EditAs = "oneCell"
|
||||
from := xlsxFrom{}
|
||||
from.Col = colStart
|
||||
|
@ -225,7 +221,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
|
|||
twoCellAnchor.To = &to
|
||||
pic := xlsxPic{}
|
||||
pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = formatSet.NoChangeAspect
|
||||
pic.NvPicPr.CNvPr.ID = cNvPrID
|
||||
pic.NvPicPr.CNvPr.ID = f.countCharts() + f.countMedia() + 1
|
||||
pic.NvPicPr.CNvPr.Descr = file
|
||||
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
|
||||
pic.BlipFill.Blip.R = SourceRelationship
|
||||
|
@ -233,19 +229,13 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
|
|||
pic.SpPr.PrstGeom.Prst = "rect"
|
||||
|
||||
twoCellAnchor.Pic = &pic
|
||||
twoCellAnchor.ClientData = &xlsxClientData{
|
||||
twoCellAnchor.ClientData = &xdrClientData{
|
||||
FLocksWithSheet: formatSet.FLocksWithSheet,
|
||||
FPrintsWithSheet: formatSet.FPrintsWithSheet,
|
||||
}
|
||||
content.WsDr.TwoCellAnchor = append(content.WsDr.TwoCellAnchor, &twoCellAnchor)
|
||||
output, err := xml.Marshal(content)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
// Create replacer with pairs as arguments and replace all pairs.
|
||||
r := strings.NewReplacer("<encodeWsDr>", "", "</encodeWsDr>", "")
|
||||
result := r.Replace(string(output))
|
||||
f.saveFileList(drawingXML, result)
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
|
||||
output, _ := xml.Marshal(content)
|
||||
f.saveFileList(drawingXML, string(output))
|
||||
}
|
||||
|
||||
// addDrawingRelationships provides function to add image part relationships in
|
||||
|
@ -271,10 +261,7 @@ func (f *File) addDrawingRelationships(index int, relType string, target string)
|
|||
Type: relType,
|
||||
Target: target,
|
||||
})
|
||||
output, err := xml.Marshal(drawingRels)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
output, _ := xml.Marshal(drawingRels)
|
||||
f.saveFileList(rels, string(output))
|
||||
return rID
|
||||
}
|
||||
|
@ -356,7 +343,7 @@ func (f *File) getSheetRelationshipsTargetByID(sheet string, rID string) string
|
|||
// in XLSX by given worksheet and cell name. This function returns the file name
|
||||
// in XLSX and file contents as []byte data types. For example:
|
||||
//
|
||||
// xlsx, err := excelize.OpenFile("/tmp/Workbook.xlsx")
|
||||
// xlsx, err := excelize.OpenFile("./Workbook.xlsx")
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// os.Exit(1)
|
||||
|
|
|
@ -0,0 +1,375 @@
|
|||
package excelize
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// parseFormatShapeSet provides function to parse the format settings of the
|
||||
// shape with default value.
|
||||
func parseFormatShapeSet(formatSet string) *formatShape {
|
||||
format := formatShape{
|
||||
Width: 160,
|
||||
Height: 160,
|
||||
Format: formatPicture{
|
||||
FPrintsWithSheet: true,
|
||||
FLocksWithSheet: false,
|
||||
NoChangeAspect: false,
|
||||
OffsetX: 0,
|
||||
OffsetY: 0,
|
||||
XScale: 1.0,
|
||||
YScale: 1.0,
|
||||
},
|
||||
Text: " ",
|
||||
}
|
||||
json.Unmarshal([]byte(formatSet), &format)
|
||||
return &format
|
||||
}
|
||||
|
||||
// AddShape provides the method to add shape in a sheet by given worksheet
|
||||
// index, shape format set (such as offset, scale, aspect ratio setting and
|
||||
// print settings) and properties set. For example, add text box (rect shape) in
|
||||
// Sheet1:
|
||||
//
|
||||
// xlsx.AddShape("Sheet1", "G6", `{"type":"rect", "text":"Rectangle Shape", "color":{"line":"#4286F4","fill":"#8eb9ff"}, "width": 180, "height": 90}`)
|
||||
//
|
||||
// The following shows the type of chart supported by excelize:
|
||||
//
|
||||
// accentBorderCallout1 (Callout 1 with Border and Accent Shape)
|
||||
// accentBorderCallout2 (Callout 2 with Border and Accent Shape)
|
||||
// accentBorderCallout3 (Callout 3 with Border and Accent Shape)
|
||||
// accentCallout1 (Callout 1 Shape)
|
||||
// accentCallout2 (Callout 2 Shape)
|
||||
// accentCallout3 (Callout 3 Shape)
|
||||
// actionButtonBackPrevious (Back or Previous Button Shape)
|
||||
// actionButtonBeginning (Beginning Button Shape)
|
||||
// actionButtonBlank (Blank Button Shape)
|
||||
// actionButtonDocument (Document Button Shape)
|
||||
// actionButtonEnd (End Button Shape)
|
||||
// actionButtonForwardNext (Forward or Next Button Shape)
|
||||
// actionButtonHelp (Help Button Shape)
|
||||
// actionButtonHome (Home Button Shape)
|
||||
// actionButtonInformation (Information Button Shape)
|
||||
// actionButtonMovie (Movie Button Shape)
|
||||
// actionButtonReturn (Return Button Shape)
|
||||
// actionButtonSound (Sound Button Shape)
|
||||
// arc (Curved Arc Shape)
|
||||
// bentArrow (Bent Arrow Shape)
|
||||
// bentConnector2 (Bent Connector 2 Shape)
|
||||
// bentConnector3 (Bent Connector 3 Shape)
|
||||
// bentConnector4 (Bent Connector 4 Shape)
|
||||
// bentConnector5 (Bent Connector 5 Shape)
|
||||
// bentUpArrow (Bent Up Arrow Shape)
|
||||
// bevel (Bevel Shape)
|
||||
// blockArc (Block Arc Shape)
|
||||
// borderCallout1 (Callout 1 with Border Shape)
|
||||
// borderCallout2 (Callout 2 with Border Shape)
|
||||
// borderCallout3 (Callout 3 with Border Shape)
|
||||
// bracePair (Brace Pair Shape)
|
||||
// bracketPair (Bracket Pair Shape)
|
||||
// callout1 (Callout 1 Shape)
|
||||
// callout2 (Callout 2 Shape)
|
||||
// callout3 (Callout 3 Shape)
|
||||
// can (Can Shape)
|
||||
// chartPlus (Chart Plus Shape)
|
||||
// chartStar (Chart Star Shape)
|
||||
// chartX (Chart X Shape)
|
||||
// chevron (Chevron Shape)
|
||||
// chord (Chord Shape)
|
||||
// circularArrow (Circular Arrow Shape)
|
||||
// cloud (Cloud Shape)
|
||||
// cloudCallout (Callout Cloud Shape)
|
||||
// corner (Corner Shape)
|
||||
// cornerTabs (Corner Tabs Shape)
|
||||
// cube (Cube Shape)
|
||||
// curvedConnector2 (Curved Connector 2 Shape)
|
||||
// curvedConnector3 (Curved Connector 3 Shape)
|
||||
// curvedConnector4 (Curved Connector 4 Shape)
|
||||
// curvedConnector5 (Curved Connector 5 Shape)
|
||||
// curvedDownArrow (Curved Down Arrow Shape)
|
||||
// curvedLeftArrow (Curved Left Arrow Shape)
|
||||
// curvedRightArrow (Curved Right Arrow Shape)
|
||||
// curvedUpArrow (Curved Up Arrow Shape)
|
||||
// decagon (Decagon Shape)
|
||||
// diagStripe (Diagonal Stripe Shape)
|
||||
// diamond (Diamond Shape)
|
||||
// dodecagon (Dodecagon Shape)
|
||||
// donut (Donut Shape)
|
||||
// doubleWave (Double Wave Shape)
|
||||
// downArrow (Down Arrow Shape)
|
||||
// downArrowCallout (Callout Down Arrow Shape)
|
||||
// ellipse (Ellipse Shape)
|
||||
// ellipseRibbon (Ellipse Ribbon Shape)
|
||||
// ellipseRibbon2 (Ellipse Ribbon 2 Shape)
|
||||
// flowChartAlternateProcess (Alternate Process Flow Shape)
|
||||
// flowChartCollate (Collate Flow Shape)
|
||||
// flowChartConnector (Connector Flow Shape)
|
||||
// flowChartDecision (Decision Flow Shape)
|
||||
// flowChartDelay (Delay Flow Shape)
|
||||
// flowChartDisplay (Display Flow Shape)
|
||||
// flowChartDocument (Document Flow Shape)
|
||||
// flowChartExtract (Extract Flow Shape)
|
||||
// flowChartInputOutput (Input Output Flow Shape)
|
||||
// flowChartInternalStorage (Internal Storage Flow Shape)
|
||||
// flowChartMagneticDisk (Magnetic Disk Flow Shape)
|
||||
// flowChartMagneticDrum (Magnetic Drum Flow Shape)
|
||||
// flowChartMagneticTape (Magnetic Tape Flow Shape)
|
||||
// flowChartManualInput (Manual Input Flow Shape)
|
||||
// flowChartManualOperation (Manual Operation Flow Shape)
|
||||
// flowChartMerge (Merge Flow Shape)
|
||||
// flowChartMultidocument (Multi-Document Flow Shape)
|
||||
// flowChartOfflineStorage (Offline Storage Flow Shape)
|
||||
// flowChartOffpageConnector (Off-Page Connector Flow Shape)
|
||||
// flowChartOnlineStorage (Online Storage Flow Shape)
|
||||
// flowChartOr (Or Flow Shape)
|
||||
// flowChartPredefinedProcess (Predefined Process Flow Shape)
|
||||
// flowChartPreparation (Preparation Flow Shape)
|
||||
// flowChartProcess (Process Flow Shape)
|
||||
// flowChartPunchedCard (Punched Card Flow Shape)
|
||||
// flowChartPunchedTape (Punched Tape Flow Shape)
|
||||
// flowChartSort (Sort Flow Shape)
|
||||
// flowChartSummingJunction (Summing Junction Flow Shape)
|
||||
// flowChartTerminator (Terminator Flow Shape)
|
||||
// foldedCorner (Folded Corner Shape)
|
||||
// frame (Frame Shape)
|
||||
// funnel (Funnel Shape)
|
||||
// gear6 (Gear 6 Shape)
|
||||
// gear9 (Gear 9 Shape)
|
||||
// halfFrame (Half Frame Shape)
|
||||
// heart (Heart Shape)
|
||||
// heptagon (Heptagon Shape)
|
||||
// hexagon (Hexagon Shape)
|
||||
// homePlate (Home Plate Shape)
|
||||
// horizontalScroll (Horizontal Scroll Shape)
|
||||
// irregularSeal1 (Irregular Seal 1 Shape)
|
||||
// irregularSeal2 (Irregular Seal 2 Shape)
|
||||
// leftArrow (Left Arrow Shape)
|
||||
// leftArrowCallout (Callout Left Arrow Shape)
|
||||
// leftBrace (Left Brace Shape)
|
||||
// leftBracket (Left Bracket Shape)
|
||||
// leftCircularArrow (Left Circular Arrow Shape)
|
||||
// leftRightArrow (Left Right Arrow Shape)
|
||||
// leftRightArrowCallout (Callout Left Right Arrow Shape)
|
||||
// leftRightCircularArrow (Left Right Circular Arrow Shape)
|
||||
// leftRightRibbon (Left Right Ribbon Shape)
|
||||
// leftRightUpArrow (Left Right Up Arrow Shape)
|
||||
// leftUpArrow (Left Up Arrow Shape)
|
||||
// lightningBolt (Lightning Bolt Shape)
|
||||
// line (Line Shape)
|
||||
// lineInv (Line Inverse Shape)
|
||||
// mathDivide (Divide Math Shape)
|
||||
// mathEqual (Equal Math Shape)
|
||||
// mathMinus (Minus Math Shape)
|
||||
// mathMultiply (Multiply Math Shape)
|
||||
// mathNotEqual (Not Equal Math Shape)
|
||||
// mathPlus (Plus Math Shape)
|
||||
// moon (Moon Shape)
|
||||
// nonIsoscelesTrapezoid (Non-Isosceles Trapezoid Shape)
|
||||
// noSmoking (No Smoking Shape)
|
||||
// notchedRightArrow (Notched Right Arrow Shape)
|
||||
// octagon (Octagon Shape)
|
||||
// parallelogram (Parallelogram Shape)
|
||||
// pentagon (Pentagon Shape)
|
||||
// pie (Pie Shape)
|
||||
// pieWedge (Pie Wedge Shape)
|
||||
// plaque (Plaque Shape)
|
||||
// plaqueTabs (Plaque Tabs Shape)
|
||||
// plus (Plus Shape)
|
||||
// quadArrow (Quad-Arrow Shape)
|
||||
// quadArrowCallout (Callout Quad-Arrow Shape)
|
||||
// rect (Rectangle Shape)
|
||||
// ribbon (Ribbon Shape)
|
||||
// ribbon2 (Ribbon 2 Shape)
|
||||
// rightArrow (Right Arrow Shape)
|
||||
// rightArrowCallout (Callout Right Arrow Shape)
|
||||
// rightBrace (Right Brace Shape)
|
||||
// rightBracket (Right Bracket Shape)
|
||||
// round1Rect (One Round Corner Rectangle Shape)
|
||||
// round2DiagRect (Two Diagonal Round Corner Rectangle Shape)
|
||||
// round2SameRect (Two Same-side Round Corner Rectangle Shape)
|
||||
// roundRect (Round Corner Rectangle Shape)
|
||||
// rtTriangle (Right Triangle Shape)
|
||||
// smileyFace (Smiley Face Shape)
|
||||
// snip1Rect (One Snip Corner Rectangle Shape)
|
||||
// snip2DiagRect (Two Diagonal Snip Corner Rectangle Shape)
|
||||
// snip2SameRect (Two Same-side Snip Corner Rectangle Shape)
|
||||
// snipRoundRect (One Snip One Round Corner Rectangle Shape)
|
||||
// squareTabs (Square Tabs Shape)
|
||||
// star10 (Ten Pointed Star Shape)
|
||||
// star12 (Twelve Pointed Star Shape)
|
||||
// star16 (Sixteen Pointed Star Shape)
|
||||
// star24 (Twenty Four Pointed Star Shape)
|
||||
// star32 (Thirty Two Pointed Star Shape)
|
||||
// star4 (Four Pointed Star Shape)
|
||||
// star5 (Five Pointed Star Shape)
|
||||
// star6 (Six Pointed Star Shape)
|
||||
// star7 (Seven Pointed Star Shape)
|
||||
// star8 (Eight Pointed Star Shape)
|
||||
// straightConnector1 (Straight Connector 1 Shape)
|
||||
// stripedRightArrow (Striped Right Arrow Shape)
|
||||
// sun (Sun Shape)
|
||||
// swooshArrow (Swoosh Arrow Shape)
|
||||
// teardrop (Teardrop Shape)
|
||||
// trapezoid (Trapezoid Shape)
|
||||
// triangle (Triangle Shape)
|
||||
// upArrow (Up Arrow Shape)
|
||||
// upArrowCallout (Callout Up Arrow Shape)
|
||||
// upDownArrow (Up Down Arrow Shape)
|
||||
// upDownArrowCallout (Callout Up Down Arrow Shape)
|
||||
// uturnArrow (U-Turn Arrow Shape)
|
||||
// verticalScroll (Vertical Scroll Shape)
|
||||
// wave (Wave Shape)
|
||||
// wedgeEllipseCallout (Callout Wedge Ellipse Shape)
|
||||
// wedgeRectCallout (Callout Wedge Rectangle Shape)
|
||||
// wedgeRoundRectCallout (Callout Wedge Round Rectangle Shape)
|
||||
//
|
||||
func (f *File) AddShape(sheet, cell, format string) {
|
||||
formatSet := parseFormatShapeSet(format)
|
||||
// Read sheet data.
|
||||
xlsx := f.workSheetReader(sheet)
|
||||
// Add first shape for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
|
||||
drawingID := f.countDrawings() + 1
|
||||
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||
sheetRelationshipsDrawingXML := "../drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||
|
||||
if xlsx.Drawing != nil {
|
||||
// The worksheet already has a shape or chart relationships, use the relationships drawing ../drawings/drawing%d.xml.
|
||||
sheetRelationshipsDrawingXML = f.getSheetRelationshipsTargetByID(sheet, xlsx.Drawing.RID)
|
||||
drawingID, _ = strconv.Atoi(strings.TrimSuffix(strings.TrimPrefix(sheetRelationshipsDrawingXML, "../drawings/drawing"), ".xml"))
|
||||
drawingXML = strings.Replace(sheetRelationshipsDrawingXML, "..", "xl", -1)
|
||||
} else {
|
||||
// Add first shape for given sheet.
|
||||
rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
|
||||
f.addSheetDrawing(sheet, rID)
|
||||
}
|
||||
f.addDrawingShape(sheet, drawingXML, cell, formatSet)
|
||||
f.addDrawingContentTypePart(drawingID)
|
||||
}
|
||||
|
||||
// addDrawingShape
|
||||
func (f *File) addDrawingShape(sheet, drawingXML, cell string, formatSet *formatShape) {
|
||||
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(formatSet.Width) * formatSet.Format.XScale)
|
||||
height := int(float64(formatSet.Height) * formatSet.Format.YScale)
|
||||
colStart, rowStart, _, _, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, col, row, formatSet.Format.OffsetX, formatSet.Format.OffsetY, width, height)
|
||||
content := xlsxWsDr{}
|
||||
content.A = NameSpaceDrawingML
|
||||
content.Xdr = NameSpaceDrawingMLSpreadSheet
|
||||
cNvPrID := 1
|
||||
_, ok := f.XLSX[drawingXML]
|
||||
if ok { // Append Model
|
||||
decodeWsDr := decodeWsDr{}
|
||||
xml.Unmarshal([]byte(f.readXML(drawingXML)), &decodeWsDr)
|
||||
cNvPrID = len(decodeWsDr.OneCellAnchor) + len(decodeWsDr.TwoCellAnchor) + 1
|
||||
for _, v := range decodeWsDr.OneCellAnchor {
|
||||
content.OneCellAnchor = append(content.OneCellAnchor, &xdrCellAnchor{
|
||||
EditAs: v.EditAs,
|
||||
GraphicFrame: v.Content,
|
||||
})
|
||||
}
|
||||
for _, v := range decodeWsDr.TwoCellAnchor {
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &xdrCellAnchor{
|
||||
EditAs: v.EditAs,
|
||||
GraphicFrame: v.Content,
|
||||
})
|
||||
}
|
||||
}
|
||||
twoCellAnchor := xdrCellAnchor{}
|
||||
twoCellAnchor.EditAs = "oneCell"
|
||||
from := xlsxFrom{}
|
||||
from.Col = colStart
|
||||
from.ColOff = formatSet.Format.OffsetX * EMU
|
||||
from.Row = rowStart
|
||||
from.RowOff = formatSet.Format.OffsetY * EMU
|
||||
to := xlsxTo{}
|
||||
to.Col = colEnd
|
||||
to.ColOff = x2 * EMU
|
||||
to.Row = rowEnd
|
||||
to.RowOff = y2 * EMU
|
||||
twoCellAnchor.From = &from
|
||||
twoCellAnchor.To = &to
|
||||
shape := xdrSp{
|
||||
NvSpPr: &xdrNvSpPr{
|
||||
CNvPr: &xlsxCNvPr{
|
||||
ID: cNvPrID,
|
||||
Name: "Shape " + strconv.Itoa(cNvPrID),
|
||||
},
|
||||
CNvSpPr: &xdrCNvSpPr{
|
||||
TxBox: true,
|
||||
},
|
||||
},
|
||||
SpPr: &xlsxSpPr{
|
||||
PrstGeom: xlsxPrstGeom{
|
||||
Prst: formatSet.Type,
|
||||
},
|
||||
},
|
||||
Style: &xdrStyle{
|
||||
LnRef: setShapeRef(formatSet.Color.Line, 2),
|
||||
FillRef: setShapeRef(formatSet.Color.Fill, 1),
|
||||
EffectRef: setShapeRef(formatSet.Color.Effect, 0),
|
||||
FontRef: &aFontRef{
|
||||
Idx: "minor",
|
||||
SchemeClr: &attrValString{
|
||||
Val: "tx1",
|
||||
},
|
||||
},
|
||||
},
|
||||
TxBody: &xdrTxBody{
|
||||
BodyPr: &aBodyPr{
|
||||
VertOverflow: "clip",
|
||||
HorzOverflow: "clip",
|
||||
Wrap: "none",
|
||||
RtlCol: false,
|
||||
Anchor: "t",
|
||||
},
|
||||
P: &aP{
|
||||
R: &aR{
|
||||
RPr: aRPr{
|
||||
Lang: "en-US",
|
||||
AltLang: "en-US",
|
||||
Sz: 1100,
|
||||
},
|
||||
T: formatSet.Text,
|
||||
},
|
||||
EndParaRPr: &aEndParaRPr{
|
||||
Lang: "en-US",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
twoCellAnchor.Sp = &shape
|
||||
twoCellAnchor.ClientData = &xdrClientData{
|
||||
FLocksWithSheet: formatSet.Format.FLocksWithSheet,
|
||||
FPrintsWithSheet: formatSet.Format.FPrintsWithSheet,
|
||||
}
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
|
||||
output, _ := xml.Marshal(content)
|
||||
f.saveFileList(drawingXML, string(output))
|
||||
}
|
||||
|
||||
// setShapeRef provides function to set color with hex model by given actual
|
||||
// color value.
|
||||
func setShapeRef(color string, i int) *aRef {
|
||||
if color == "" {
|
||||
return &aRef{
|
||||
Idx: 0,
|
||||
ScrgbClr: &aScrgbClr{
|
||||
R: 0,
|
||||
G: 0,
|
||||
B: 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
return &aRef{
|
||||
Idx: i,
|
||||
SrgbClr: &attrValString{
|
||||
Val: strings.Replace(strings.ToUpper(color), "#", "", -1),
|
||||
},
|
||||
}
|
||||
}
|
2
sheet.go
2
sheet.go
|
@ -291,7 +291,7 @@ func (f *File) GetSheetIndex(name string) int {
|
|||
|
||||
// GetSheetMap provides function to get sheet map of XLSX. For example:
|
||||
//
|
||||
// xlsx, err := excelize.OpenFile("/tmp/Workbook.xlsx")
|
||||
// xlsx, err := excelize.OpenFile("./Workbook.xlsx")
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// os.Exit(1)
|
||||
|
|
3
table.go
3
table.go
|
@ -52,11 +52,9 @@ func (f *File) AddTable(sheet, hcell, vcell, format string) {
|
|||
vyAxis := vrow - 1
|
||||
vxAxis := titleToNumber(vcol)
|
||||
if vxAxis < hxAxis {
|
||||
hcell, vcell = vcell, hcell
|
||||
vxAxis, hxAxis = hxAxis, vxAxis
|
||||
}
|
||||
if vyAxis < hyAxis {
|
||||
hcell, vcell = vcell, hcell
|
||||
vyAxis, hyAxis = hyAxis, vyAxis
|
||||
}
|
||||
tableID := f.countTables() + 1
|
||||
|
@ -156,7 +154,6 @@ func (f *File) addTable(sheet, tableXML string, hxAxis, hyAxis, vxAxis, vyAxis,
|
|||
// addTableContentTypePart provides function to add image part relationships
|
||||
// in the file [Content_Types].xml by given drawing index.
|
||||
func (f *File) addTableContentTypePart(index int) {
|
||||
f.setContentTypePartImageExtensions()
|
||||
content := f.contentTypesReader()
|
||||
for _, v := range content.Overrides {
|
||||
if v.PartName == "/xl/tables/table"+strconv.Itoa(index)+".xml" {
|
||||
|
|
Binary file not shown.
17
xmlChart.go
17
xmlChart.go
|
@ -1,14 +1,12 @@
|
|||
package excelize
|
||||
|
||||
// chartSpace directly maps the xlsxChart element.
|
||||
type xlsxChartSpace struct {
|
||||
ChartSpace cChartSpace `xml:"c:chartSpace"`
|
||||
}
|
||||
import "encoding/xml"
|
||||
|
||||
// cChartSpace directly maps the c:chartSpace element. The chart namespace in
|
||||
// xlsxChartSpace directly maps the c:chartSpace element. The chart namespace in
|
||||
// DrawingML is for representing visualizations of numeric data with column
|
||||
// charts, pie charts, scatter charts, or other types of charts.
|
||||
type cChartSpace struct {
|
||||
type xlsxChartSpace struct {
|
||||
XMLName xml.Name `xml:"c:chartSpace"`
|
||||
XMLNSc string `xml:"xmlns:c,attr"`
|
||||
XMLNSa string `xml:"xmlns:a,attr"`
|
||||
XMLNSr string `xml:"xmlns:r,attr"`
|
||||
|
@ -98,7 +96,7 @@ type aBodyPr struct {
|
|||
// aP (Paragraph) directly maps the a:p element. This element specifies a
|
||||
// paragraph of content in the document.
|
||||
type aP struct {
|
||||
PPr aPPr `xml:"a:pPr"`
|
||||
PPr *aPPr `xml:"a:pPr"`
|
||||
R *aR `xml:"a:r"`
|
||||
EndParaRPr *aEndParaRPr `xml:"a:endParaRPr"`
|
||||
}
|
||||
|
@ -210,6 +208,7 @@ type aR struct {
|
|||
type aRPr struct {
|
||||
Lang string `xml:"lang,attr,omitempty"`
|
||||
AltLang string `xml:"altLang,attr,omitempty"`
|
||||
Sz int `xml:"sz,attr,omitempty"`
|
||||
}
|
||||
|
||||
// cSpPr (Shape Properties) directly maps the c:spPr element. This element
|
||||
|
@ -271,7 +270,9 @@ type cTxPr struct {
|
|||
// element be specified at the end of the list of text runs within the paragraph
|
||||
// so that an orderly list is maintained.
|
||||
type aEndParaRPr struct {
|
||||
Lang string `xml:"lang,attr"`
|
||||
Lang string `xml:"lang,attr"`
|
||||
AltLang string `xml:"altLang,attr,omitempty"`
|
||||
Sz int `xml:"sz,attr,omitempty"`
|
||||
}
|
||||
|
||||
// cAutoTitleDeleted (Auto Title Is Deleted) directly maps the
|
||||
|
|
137
xmlDrawing.go
137
xmlDrawing.go
|
@ -1,5 +1,7 @@
|
|||
package excelize
|
||||
|
||||
import "encoding/xml"
|
||||
|
||||
// Source relationship and namespace.
|
||||
const (
|
||||
SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
|
@ -162,42 +164,40 @@ type xlsxTo struct {
|
|||
RowOff int `xml:"xdr:rowOff"`
|
||||
}
|
||||
|
||||
// xlsxClientData directly maps the clientData element. An empty element which
|
||||
// xdrClientData directly maps the clientData element. An empty element which
|
||||
// specifies (via attributes) certain properties related to printing and
|
||||
// selection of the drawing object. The fLocksWithSheet attribute (either true
|
||||
// or false) determines whether to disable selection when the sheet is
|
||||
// protected, and fPrintsWithSheet attribute (either true or false) determines
|
||||
// whether the object is printed when the sheet is printed.
|
||||
type xlsxClientData struct {
|
||||
type xdrClientData struct {
|
||||
FLocksWithSheet bool `xml:"fLocksWithSheet,attr"`
|
||||
FPrintsWithSheet bool `xml:"fPrintsWithSheet,attr"`
|
||||
}
|
||||
|
||||
// xlsxCellAnchor directly maps the oneCellAnchor (One Cell Anchor Shape Size)
|
||||
// xdrCellAnchor directly maps the oneCellAnchor (One Cell Anchor Shape Size)
|
||||
// and twoCellAnchor (Two Cell Anchor Shape Size). This element specifies a two
|
||||
// cell anchor placeholder for a group, a shape, or a drawing element. It moves
|
||||
// with cells and its extents are in EMU units.
|
||||
type xlsxCellAnchor struct {
|
||||
EditAs string `xml:"editAs,attr,omitempty"`
|
||||
From *xlsxFrom `xml:"xdr:from"`
|
||||
To *xlsxTo `xml:"xdr:to"`
|
||||
Pic *xlsxPic `xml:"xdr:pic,omitempty"`
|
||||
GraphicFrame string `xml:",innerxml"`
|
||||
ClientData *xlsxClientData `xml:"xdr:clientData"`
|
||||
type xdrCellAnchor struct {
|
||||
EditAs string `xml:"editAs,attr,omitempty"`
|
||||
From *xlsxFrom `xml:"xdr:from"`
|
||||
To *xlsxTo `xml:"xdr:to"`
|
||||
Ext *xlsxExt `xml:"xdr:ext"`
|
||||
Sp *xdrSp `xml:"xdr:sp"`
|
||||
Pic *xlsxPic `xml:"xdr:pic,omitempty"`
|
||||
GraphicFrame string `xml:",innerxml"`
|
||||
ClientData *xdrClientData `xml:"xdr:clientData"`
|
||||
}
|
||||
|
||||
// xlsxWsDr directly maps the root element for a part of this content type shall
|
||||
// wsDr.
|
||||
type xlsxWsDr struct {
|
||||
OneCellAnchor []*xlsxCellAnchor `xml:"xdr:oneCellAnchor"`
|
||||
TwoCellAnchor []*xlsxCellAnchor `xml:"xdr:twoCellAnchor"`
|
||||
Xdr string `xml:"xmlns:xdr,attr"`
|
||||
A string `xml:"xmlns:a,attr"`
|
||||
}
|
||||
|
||||
// graphicFrame (Graphic Frame) directly maps the graphicFrame element.
|
||||
type graphicFrame struct {
|
||||
GraphicFrame *xlsxGraphicFrame `xml:"xdr:graphicFrame"`
|
||||
XMLName xml.Name `xml:"xdr:wsDr"`
|
||||
OneCellAnchor []*xdrCellAnchor `xml:"xdr:oneCellAnchor"`
|
||||
TwoCellAnchor []*xdrCellAnchor `xml:"xdr:twoCellAnchor"`
|
||||
Xdr string `xml:"xmlns:xdr,attr"`
|
||||
A string `xml:"xmlns:a,attr"`
|
||||
}
|
||||
|
||||
// xlsxGraphicFrame (Graphic Frame) directly maps the xdr:graphicFrame element.
|
||||
|
@ -205,6 +205,7 @@ type graphicFrame struct {
|
|||
// a graphic that was generated by an external source and needs a container in
|
||||
// which to be displayed on the slide surface.
|
||||
type xlsxGraphicFrame struct {
|
||||
XMLName xml.Name `xml:"xdr:graphicFrame"`
|
||||
Macro string `xml:"macro,attr"`
|
||||
NvGraphicFramePr xlsxNvGraphicFramePr `xml:"xdr:nvGraphicFramePr"`
|
||||
Xfrm xlsxXfrm `xml:"xdr:xfrm"`
|
||||
|
@ -248,9 +249,85 @@ type xlsxChart struct {
|
|||
R string `xml:"xmlns:r,attr"`
|
||||
}
|
||||
|
||||
// encodeWsDr directly maps the element xdr:wsDr.
|
||||
type encodeWsDr struct {
|
||||
WsDr xlsxWsDr `xml:"xdr:wsDr"`
|
||||
// xdrSp (Shape) directly maps the xdr:sp element. This element specifies the
|
||||
// existence of a single shape. A shape can either be a preset or a custom
|
||||
// geometry, defined using the SpreadsheetDrawingML framework. In addition to a
|
||||
// geometry each shape can have both visual and non-visual properties attached.
|
||||
// Text and corresponding styling information can also be attached to a shape.
|
||||
// This shape is specified along with all other shapes within either the shape
|
||||
// tree or group shape elements.
|
||||
type xdrSp struct {
|
||||
Macro string `xml:"macro,attr"`
|
||||
Textlink string `xml:"textlink,attr"`
|
||||
NvSpPr *xdrNvSpPr `xml:"xdr:nvSpPr"`
|
||||
SpPr *xlsxSpPr `xml:"xdr:spPr"`
|
||||
Style *xdrStyle `xml:"xdr:style"`
|
||||
TxBody *xdrTxBody `xml:"xdr:txBody"`
|
||||
}
|
||||
|
||||
// xdrNvSpPr (Non-Visual Properties for a Shape) directly maps the xdr:nvSpPr
|
||||
// element. This element specifies all non-visual properties for a shape. This
|
||||
// element is a container for the non-visual identification properties, shape
|
||||
// properties and application properties that are to be associated with a shape.
|
||||
// This allows for additional information that does not affect the appearance of
|
||||
// the shape to be stored.
|
||||
type xdrNvSpPr struct {
|
||||
CNvPr *xlsxCNvPr `xml:"xdr:cNvPr"`
|
||||
CNvSpPr *xdrCNvSpPr `xml:"xdr:cNvSpPr"`
|
||||
}
|
||||
|
||||
// xdrCNvSpPr (Connection Non-Visual Shape Properties) directly maps the
|
||||
// xdr:cNvSpPr element. This element specifies the set of non-visual properties
|
||||
// for a connection shape. These properties specify all data about the
|
||||
// connection shape which do not affect its display within a spreadsheet.
|
||||
type xdrCNvSpPr struct {
|
||||
TxBox bool `xml:"txBox,attr"`
|
||||
}
|
||||
|
||||
// xdrStyle (Shape Style) directly maps the xdr:style element. The element
|
||||
// specifies the style that is applied to a shape and the corresponding
|
||||
// references for each of the style components such as lines and fills.
|
||||
type xdrStyle struct {
|
||||
LnRef *aRef `xml:"a:lnRef"`
|
||||
FillRef *aRef `xml:"a:fillRef"`
|
||||
EffectRef *aRef `xml:"a:effectRef"`
|
||||
FontRef *aFontRef `xml:"a:fontRef"`
|
||||
}
|
||||
|
||||
// aRef directly maps the a:lnRef, a:fillRef and a:effectRef element.
|
||||
type aRef struct {
|
||||
Idx int `xml:"idx,attr"`
|
||||
ScrgbClr *aScrgbClr `xml:"a:scrgbClr"`
|
||||
SchemeClr *attrValString `xml:"a:schemeClr"`
|
||||
SrgbClr *attrValString `xml:"a:srgbClr"`
|
||||
}
|
||||
|
||||
// aScrgbClr (RGB Color Model - Percentage Variant) directly maps the a:scrgbClr
|
||||
// element. This element specifies a color using the red, green, blue RGB color
|
||||
// model. Each component, red, green, and blue is expressed as a percentage from
|
||||
// 0% to 100%. A linear gamma of 1.0 is assumed.
|
||||
type aScrgbClr struct {
|
||||
R float64 `xml:"r,attr"`
|
||||
G float64 `xml:"g,attr"`
|
||||
B float64 `xml:"b,attr"`
|
||||
}
|
||||
|
||||
// aFontRef (Font Reference) directly maps the a:fontRef element. This element
|
||||
// represents a reference to a themed font. When used it specifies which themed
|
||||
// font to use along with a choice of color.
|
||||
type aFontRef struct {
|
||||
Idx string `xml:"idx,attr"`
|
||||
SchemeClr *attrValString `xml:"a:schemeClr"`
|
||||
}
|
||||
|
||||
// xdrTxBody (Shape Text Body) directly maps the xdr:txBody element. This
|
||||
// element specifies the existence of text to be contained within the
|
||||
// corresponding shape. All visible text and visible text related properties are
|
||||
// contained within this element. There can be multiple paragraphs and within
|
||||
// paragraphs multiple runs of text.
|
||||
type xdrTxBody struct {
|
||||
BodyPr *aBodyPr `xml:"a:bodyPr"`
|
||||
P *aP `xml:"a:p"`
|
||||
}
|
||||
|
||||
// formatPicture directly maps the format settings of the picture.
|
||||
|
@ -263,3 +340,19 @@ type formatPicture struct {
|
|||
XScale float64 `json:"x_scale"`
|
||||
YScale float64 `json:"y_scale"`
|
||||
}
|
||||
|
||||
// formatShape directly maps the format settings of the shape.
|
||||
type formatShape struct {
|
||||
Type string `json:"type"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Format formatPicture `json:"format"`
|
||||
Text string `json:"text"`
|
||||
Color formatShapeColor `json:"color"`
|
||||
}
|
||||
|
||||
type formatShapeColor struct {
|
||||
Line string `json:"line"`
|
||||
Fill string `json:"fill"`
|
||||
Effect string `json:"effect"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue