diff --git a/README.md b/README.md
index 6ac668e..3f71454 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,7 @@ package main
import (
"fmt"
"os"
+ "strconv"
"github.com/Luxurioust/excelize"
)
@@ -76,8 +77,10 @@ func main() {
// Get value from cell by given sheet index and axis.
cell := xlsx.GetCellValue("Sheet1", "B2")
fmt.Println(cell)
+ // Get sheet index.
+ index := xlsx.GetSheetIndex("Sheet2")
// Get all the rows in a sheet.
- rows := xlsx.GetRows("Sheet2")
+ rows := xlsx.GetRows("sheet" + strconv.Itoa(index))
for _, row := range rows {
for _, colCell := range row {
fmt.Print(colCell, "\t")
@@ -87,6 +90,42 @@ func main() {
}
```
+### Add chart to XLSX file
+
+With Excelize chart generation and management is as easy as a few lines of code. You can build charts based off data in your worksheet or generate charts without any data in your sheet at all.
+
+![Excelize](./test/images/chart.png "Excelize")
+
+```
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/Luxurioust/excelize"
+)
+
+func main() {
+ categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Large", "C1": "Apple", "D1": "Pear"}
+ values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8}
+ xlsx := excelize.CreateFile()
+ for k, v := range categories {
+ xlsx.SetCellValue("Sheet1", k, v)
+ }
+ for k, v := range values {
+ xlsx.SetCellValue("Sheet1", k, v)
+ }
+ xlsx.AddChart("Sheet1", "E1", `{"type":"bar3D","series":[{"name":"=Sheet1!$A$2","categories":"=Sheet1!$B$1:$D$1","values":"=Sheet1!$B$2:$D$2"},{"name":"=Sheet1!$A$2","categories":"=Sheet1!$B$1:$D$1","values":"=Sheet1!$B$3:$D$3"},{"name":"=Sheet1!$A$3","categories":"=Sheet1!$B$1:$D$1","values":"=Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Line Chart"}}`)
+ // Save xlsx file by the given path.
+ err := xlsx.WriteTo("./Workbook.xlsx")
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+```
+
### Add picture to XLSX file
```go
diff --git a/chart.go b/chart.go
new file mode 100644
index 0000000..c5ef6b8
--- /dev/null
+++ b/chart.go
@@ -0,0 +1,928 @@
+package excelize
+
+import (
+ "encoding/json"
+ "encoding/xml"
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// This section defines the currently supported chart types.
+const (
+ Bar = "bar"
+ Bar3D = "bar3D"
+ Doughnut = "doughnut"
+ Line = "line"
+ Pie = "pie"
+ Pie3D = "pie3D"
+ Radar = "radar"
+ Scatter = "scatter"
+)
+
+// This section defines the default value of chart properties.
+var (
+ chartView3DRotX = map[string]int{Bar: 0, Bar3D: 15, Doughnut: 0, Line: 0, Pie: 0, Pie3D: 30, Radar: 0, Scatter: 0}
+ chartView3DRotY = map[string]int{Bar: 0, Bar3D: 20, Doughnut: 0, Line: 0, Pie: 0, Pie3D: 0, Radar: 0, Scatter: 0}
+ chartView3DDepthPercent = map[string]int{Bar: 100, Bar3D: 100, Doughnut: 100, Line: 100, Pie: 100, Pie3D: 100, Radar: 100, Scatter: 100}
+ chartView3DRAngAx = map[string]int{Bar: 0, Bar3D: 1, Doughnut: 0, Line: 0, Pie: 0, Pie3D: 0, Radar: 0, Scatter: 0}
+ chartLegendPosition = map[string]string{"bottom": "b", "left": "l", "right": "r", "top": "t", "top_right": "tr"}
+)
+
+// parseFormatChartSet provides function to parse the format settings of the
+// chart with default value.
+func parseFormatChartSet(formatSet string) *formatChart {
+ format := formatChart{
+ Format: formatPicture{
+ FPrintsWithSheet: true,
+ FLocksWithSheet: false,
+ NoChangeAspect: false,
+ OffsetX: 0,
+ OffsetY: 0,
+ XScale: 1.0,
+ YScale: 1.0,
+ },
+ Legend: formatChartLegend{
+ Position: "bottom",
+ ShowLegendKey: false,
+ },
+ Title: formatChartTitle{
+ Name: " ",
+ },
+ ShowBlanksAs: "gap",
+ }
+ json.Unmarshal([]byte(formatSet), &format)
+ return &format
+}
+
+// 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:
+//
+// package main
+//
+// import (
+// "fmt"
+// "os"
+//
+// "github.com/Luxurioust/excelize"
+// )
+//
+// func main() {
+// xlsx := excelize.CreateFile()
+// xlsx.SetCellValue("SHEET1", "A30", "Small")
+// xlsx.SetCellValue("SHEET1", "A31", "Normal")
+// xlsx.SetCellValue("SHEET1", "A32", "Large")
+// xlsx.SetCellValue("SHEET1", "B29", "Apple")
+// xlsx.SetCellValue("SHEET1", "C29", "Prange")
+// xlsx.SetCellValue("SHEET1", "D29", "Pear")
+// xlsx.SetCellValue("SHEET1", "B30", 2)
+// xlsx.SetCellValue("SHEET1", "C30", 3)
+// xlsx.SetCellValue("SHEET1", "D30", 3)
+// xlsx.SetCellValue("SHEET1", "B31", 5)
+// xlsx.SetCellValue("SHEET1", "C31", 2)
+// xlsx.SetCellValue("SHEET1", "D31", 4)
+// xlsx.SetCellValue("SHEET1", "B32", 6)
+// xlsx.SetCellValue("SHEET1", "C32", 7)
+// xlsx.SetCellValue("SHEET1", "D32", 8)
+// 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")
+// if err != nil {
+// fmt.Println(err)
+// os.Exit(1)
+// }
+// }
+//
+// The following shows the type of chart supported by excelize:
+//
+// +---------------------------+
+// | Type | Chart |
+// +==========+================+
+// | bar | bar chart |
+// +----------+----------------+
+// | bar3D | 3D bar chart |
+// +----------+----------------+
+// | doughnut | doughnut chart |
+// +----------+----------------+
+// | line | line chart |
+// +----------+----------------+
+// | pie | pie chart |
+// +----------+----------------+
+// | pie3D | 3D pie chart |
+// +----------+----------------+
+// | radar | radar chart |
+// +----------+----------------+
+// | scatter | scatter chart |
+// +----------+----------------+
+//
+// In Excel a chart series is a collection of information that defines which data is plotted such as values, axis labels and formatting.
+//
+// The series options that can be set are:
+//
+// name
+// categories
+// values
+//
+// name: Set the name for the series. The name is displayed in the chart legend and in the formula bar. The name property is optional and if it isn't supplied it will default to Series 1..n. The name can also be a formula such as =Sheet1!$A$1
+//
+// categories: This sets the chart category labels. The category is more or less the same as the X axis. In most chart types the categories property is optional and the chart will just assume a sequential series from 1..n.
+//
+// values: This is the most important property of a series and is the only mandatory option for every chart object. This option links the chart with the worksheet data that it displays.
+//
+// Set properties of the chart legend. The options that can be set are:
+//
+// position
+// show_legend_key
+//
+// position: Set the position of the chart legend. The default legend position is right. The available positions are:
+//
+// top
+// bottom
+// left
+// right
+// top_right
+//
+// show_legend_key: Set the legend keys shall be shown in data labels. The default value is false.
+//
+// Set properties of the chart title. The properties that can be set are:
+//
+// title
+//
+// name: Set the name (title) for the chart. The name is displayed above the chart. The name can also be a formula such as =Sheet1!$A$1 or a list with a sheetname. The name property is optional. The default is to have no chart title.
+//
+// Specifies how blank cells are plotted on the chart by show_blanks_as. The default value is gap. The options that can be set are:
+//
+// gap
+// span
+// zero
+//
+// gap: Specifies that blank values shall be left as a gap.
+//
+// sapn: Specifies that blank values shall be spanned with a line.
+//
+// zero: Specifies that blank values shall be treated as zero.
+//
+// Set chart offset, scale, aspect ratio setting and print settings by format, same as function AddPicture.
+//
+// Set the position of the chart plot area by plotarea. The properties that can be set are:
+//
+// show_bubble_size
+// show_cat_name
+// show_leader_lines
+// show_percent
+// show_series_name
+// show_val
+//
+// show_bubble_size: Specifies the bubble size shall be shown in a data label. The show_bubble_size property is optional. The default value is false.
+// show_cat_name: Specifies that the category name shall be shown in the data label. The show_cat_name property is optional. The default value is true.
+// show_leader_lines: Specifies leader lines shall be shown for data labels. The show_leader_lines property is optional. The default value is false.
+// show_percent: Specifies that the percentage shall be shown in a data label. The show_percent property is optional. The default value is false.
+// show_series_name: Specifies that the series name shall be shown in a data label. The show_series_name property is optional. The default value is false.
+// show_val: Specifies that the value shall be shown in a data label. The show_val property is optional. The default value is false.
+//
+func (f *File) AddChart(sheet, cell, format string) {
+ formatSet := parseFormatChartSet(format)
+ // Read sheet data.
+ xlsx := f.workSheetReader(sheet)
+ // Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
+ drawingID := f.countDrawings() + 1
+ chartID := f.countCharts() + 1
+ drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
+ sheetRelationshipsDrawingXML := "../drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
+
+ var drawingRID int
+ if xlsx.Drawing != nil {
+ // The worksheet already has a picture 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 picture for given sheet.
+ rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
+ f.addSheetDrawing(sheet, rID)
+ }
+ 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.addChartContentTypePart(chartID)
+ f.addDrawingContentTypePart(drawingID)
+}
+
+// countCharts provides function to get chart files count storage in the
+// folder xl/charts.
+func (f *File) countCharts() int {
+ count := 0
+ for k := range f.XLSX {
+ if strings.Contains(k, "xl/charts/chart") {
+ count++
+ }
+ }
+ return count
+}
+
+// addChartContentTypePart provides function to add chart part relationships in
+// the file [Content_Types].xml by given chart index.
+func (f *File) addChartContentTypePart(index int) {
+ content := f.contentTypesReader()
+ for _, v := range content.Overrides {
+ if v.PartName == "/xl/charts/chart"+strconv.Itoa(index)+".xml" {
+ return
+ }
+ }
+ content.Overrides = append(content.Overrides, xlsxOverride{
+ PartName: "/xl/charts/chart" + strconv.Itoa(index) + ".xml",
+ ContentType: "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
+ })
+}
+
+// addChart provides function to create chart as xl/charts/chart%d.xml by given
+// format sets.
+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{
+ 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},
+ },
+ SpPr: &cSpPr{
+ 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,
+ },
+ },
+ },
+ },
+ },
+ PrintSettings: &cPrintSettings{
+ PageMargins: &cPageMargins{
+ B: 0.75,
+ L: 0.7,
+ R: 0.7,
+ T: 0.7,
+ Header: 0.3,
+ Footer: 0.3,
+ },
+ },
+ },
+ }
+ plotAreaFunc := map[string]func(*formatChart) *cPlotArea{
+ Bar: f.drawBarChart,
+ Bar3D: f.drawBar3DChart,
+ Doughnut: f.drawDoughnutChart,
+ Line: f.drawLineChart,
+ Pie3D: f.drawPie3DChart,
+ Pie: f.drawPieChart,
+ Radar: f.drawRadarChart,
+ Scatter: f.drawScatterChart,
+ }
+ xlsxChartSpace.ChartSpace.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]))
+}
+
+// drawBarChart provides function to draw the c:plotArea element for bar chart
+// by given format sets.
+func (f *File) drawBarChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ BarChart: &cCharts{
+ BarDir: &attrValString{
+ Val: "col",
+ },
+ Grouping: &attrValString{
+ Val: "clustered",
+ },
+ VaryColors: &attrValBool{
+ Val: true,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ DLbls: f.drawChartDLbls(formatSet),
+ AxID: []*attrValInt{
+ &attrValInt{Val: 754001152},
+ &attrValInt{Val: 753999904},
+ },
+ },
+ CatAx: f.drawPlotAreaCatAx(),
+ ValAx: f.drawPlotAreaValAx(),
+ }
+}
+
+// drawBar3DChart provides function to draw the c:plotArea element for 3D bar
+// chart by given format sets.
+func (f *File) drawBar3DChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ Bar3DChart: &cCharts{
+ BarDir: &attrValString{
+ Val: "col",
+ },
+ Grouping: &attrValString{
+ Val: "clustered",
+ },
+ VaryColors: &attrValBool{
+ Val: true,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ DLbls: f.drawChartDLbls(formatSet),
+ AxID: []*attrValInt{
+ &attrValInt{Val: 754001152},
+ &attrValInt{Val: 753999904},
+ },
+ },
+ CatAx: f.drawPlotAreaCatAx(),
+ ValAx: f.drawPlotAreaValAx(),
+ }
+}
+
+// drawDoughnutChart provides function to draw the c:plotArea element for
+// doughnut chart by given format sets.
+func (f *File) drawDoughnutChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ DoughnutChart: &cCharts{
+ VaryColors: &attrValBool{
+ Val: true,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ HoleSize: &attrValInt{Val: 75},
+ },
+ }
+}
+
+// drawLineChart provides function to draw the c:plotArea element for line chart
+// by given format sets.
+func (f *File) drawLineChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ LineChart: &cCharts{
+ Grouping: &attrValString{
+ Val: "standard",
+ },
+ VaryColors: &attrValBool{
+ Val: false,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ DLbls: f.drawChartDLbls(formatSet),
+ Smooth: &attrValBool{
+ Val: false,
+ },
+ AxID: []*attrValInt{
+ &attrValInt{Val: 754001152},
+ &attrValInt{Val: 753999904},
+ },
+ },
+ CatAx: f.drawPlotAreaCatAx(),
+ ValAx: f.drawPlotAreaValAx(),
+ }
+}
+
+// drawPieChart provides function to draw the c:plotArea element for pie chart
+// by given format sets.
+func (f *File) drawPieChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ PieChart: &cCharts{
+ VaryColors: &attrValBool{
+ Val: true,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ },
+ }
+}
+
+// drawPie3DChart provides function to draw the c:plotArea element for 3D pie
+// chart by given format sets.
+func (f *File) drawPie3DChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ Pie3DChart: &cCharts{
+ VaryColors: &attrValBool{
+ Val: true,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ },
+ }
+}
+
+// drawRadarChart provides function to draw the c:plotArea element for radar
+// chart by given format sets.
+func (f *File) drawRadarChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ RadarChart: &cCharts{
+ RadarStyle: &attrValString{
+ Val: "marker",
+ },
+ VaryColors: &attrValBool{
+ Val: false,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ DLbls: f.drawChartDLbls(formatSet),
+ AxID: []*attrValInt{
+ &attrValInt{Val: 754001152},
+ &attrValInt{Val: 753999904},
+ },
+ },
+ CatAx: f.drawPlotAreaCatAx(),
+ ValAx: f.drawPlotAreaValAx(),
+ }
+}
+
+// drawScatterChart provides function to draw the c:plotArea element for scatter
+// chart by given format sets.
+func (f *File) drawScatterChart(formatSet *formatChart) *cPlotArea {
+ return &cPlotArea{
+ ScatterChart: &cCharts{
+ ScatterStyle: &attrValString{
+ Val: "smoothMarker", // line,lineMarker,marker,none,smooth,smoothMarker
+ },
+ VaryColors: &attrValBool{
+ Val: false,
+ },
+ Ser: f.drawChartSeries(formatSet),
+ DLbls: f.drawChartDLbls(formatSet),
+ AxID: []*attrValInt{
+ &attrValInt{Val: 754001152},
+ &attrValInt{Val: 753999904},
+ },
+ },
+ CatAx: f.drawPlotAreaCatAx(),
+ ValAx: f.drawPlotAreaValAx(),
+ }
+}
+
+// drawChartSeries provides function to draw the c:ser element by given format
+// sets.
+func (f *File) drawChartSeries(formatSet *formatChart) *[]cSer {
+ ser := []cSer{}
+ for k, v := range formatSet.Series {
+ ser = append(ser, cSer{
+ IDx: &attrValInt{Val: k},
+ Order: &attrValInt{Val: k},
+ Tx: &cTx{
+ StrRef: &cStrRef{
+ F: v.Name,
+ },
+ },
+ SpPr: f.drawChartSeriesSpPr(k, formatSet),
+ Marker: f.drawChartSeriesMarker(k, formatSet),
+ DPt: f.drawChartSeriesDPt(k, formatSet),
+ DLbls: f.drawChartSeriesDLbls(formatSet),
+ Cat: f.drawChartSeriesCat(v, formatSet),
+ Val: f.drawChartSeriesVal(v, formatSet),
+ XVal: f.drawChartSeriesXVal(v, formatSet),
+ YVal: f.drawChartSeriesYVal(v, formatSet),
+ })
+ }
+ return &ser
+}
+
+// drawChartSeriesSpPr provides function to draw the c:spPr element by given
+// format sets.
+func (f *File) drawChartSeriesSpPr(i int, formatSet *formatChart) *cSpPr {
+ spPrScatter := &cSpPr{
+ Ln: &aLn{
+ W: 25400,
+ NoFill: " ",
+ },
+ }
+ spPrLine := &cSpPr{
+ Ln: &aLn{
+ W: 25400,
+ Cap: "rnd", // rnd, sq, flat
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{Val: "accent" + strconv.Itoa(i+1)},
+ },
+ },
+ }
+ chartSeriesSpPr := map[string]*cSpPr{Bar: nil, Bar3D: nil, Doughnut: nil, Line: spPrLine, Pie: nil, Pie3D: nil, Radar: nil, Scatter: spPrScatter}
+ return chartSeriesSpPr[formatSet.Type]
+}
+
+// drawChartSeriesDPt provides function to draw the c:dPt element by given data
+// index and format sets.
+func (f *File) drawChartSeriesDPt(i int, formatSet *formatChart) []*cDPt {
+ dpt := []*cDPt{&cDPt{
+ IDx: &attrValInt{Val: i},
+ Bubble3D: &attrValBool{Val: false},
+ SpPr: &cSpPr{
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{Val: "accent" + strconv.Itoa(i+1)},
+ },
+ Ln: &aLn{
+ W: 25400,
+ Cap: "rnd",
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{Val: "lt" + strconv.Itoa(i+1)},
+ },
+ },
+ Sp3D: &aSp3D{
+ ContourW: 25400,
+ ContourClr: &aContourClr{
+ SchemeClr: &aSchemeClr{Val: "lt" + strconv.Itoa(i+1)},
+ },
+ },
+ },
+ }}
+ chartSeriesDPt := map[string][]*cDPt{Bar: nil, Bar3D: nil, Doughnut: nil, Line: nil, Pie: dpt, Pie3D: dpt, Radar: nil, Scatter: nil}
+ return chartSeriesDPt[formatSet.Type]
+}
+
+// drawChartSeriesCat provides function to draw the c:cat element by given chart
+// series and format sets.
+func (f *File) drawChartSeriesCat(v formatChartSeries, formatSet *formatChart) *cCat {
+ cat := &cCat{
+ StrRef: &cStrRef{
+ F: v.Categories,
+ },
+ }
+ chartSeriesCat := map[string]*cCat{Bar: cat, Bar3D: cat, Doughnut: cat, Line: cat, Pie: cat, Pie3D: cat, Radar: cat, Scatter: nil}
+ return chartSeriesCat[formatSet.Type]
+}
+
+// drawChartSeriesVal provides function to draw the c:val element by given chart
+// series and format sets.
+func (f *File) drawChartSeriesVal(v formatChartSeries, formatSet *formatChart) *cVal {
+ val := &cVal{
+ NumRef: &cNumRef{
+ F: v.Values,
+ },
+ }
+ chartSeriesVal := map[string]*cVal{Bar: val, Bar3D: val, Doughnut: val, Line: val, Pie: val, Pie3D: val, Radar: val, Scatter: nil}
+ return chartSeriesVal[formatSet.Type]
+}
+
+// drawChartSeriesMarker provides function to draw the c:marker element by given
+// data index and format sets.
+func (f *File) drawChartSeriesMarker(i int, formatSet *formatChart) *cMarker {
+ marker := &cMarker{
+ Symbol: &attrValString{Val: "circle"},
+ Size: &attrValInt{Val: 5},
+ SpPr: &cSpPr{
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{
+ Val: "accent" + strconv.Itoa(i+1),
+ },
+ },
+ Ln: &aLn{
+ W: 9252,
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{
+ Val: "accent" + strconv.Itoa(i+1),
+ },
+ },
+ },
+ },
+ }
+ chartSeriesMarker := map[string]*cMarker{Bar: nil, Bar3D: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: marker}
+ return chartSeriesMarker[formatSet.Type]
+}
+
+// drawChartSeriesXVal provides function to draw the c:xVal element by given
+// chart series and format sets.
+func (f *File) drawChartSeriesXVal(v formatChartSeries, formatSet *formatChart) *cCat {
+ cat := &cCat{
+ StrRef: &cStrRef{
+ F: v.Categories,
+ },
+ }
+ chartSeriesXVal := map[string]*cCat{Bar: nil, Bar3D: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: cat}
+ return chartSeriesXVal[formatSet.Type]
+}
+
+// drawChartSeriesYVal provides function to draw the c:yVal element by given
+// chart series and format sets.
+func (f *File) drawChartSeriesYVal(v formatChartSeries, formatSet *formatChart) *cVal {
+ val := &cVal{
+ NumRef: &cNumRef{
+ F: v.Values,
+ },
+ }
+ chartSeriesYVal := map[string]*cVal{Bar: nil, Bar3D: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: val}
+ return chartSeriesYVal[formatSet.Type]
+}
+
+// drawChartDLbls provides function to draw the c:dLbls element by given format
+// sets.
+func (f *File) drawChartDLbls(formatSet *formatChart) *cDLbls {
+ return &cDLbls{
+ ShowLegendKey: &attrValBool{Val: formatSet.Legend.ShowLegendKey},
+ ShowVal: &attrValBool{Val: formatSet.Plotarea.ShowVal},
+ ShowCatName: &attrValBool{Val: formatSet.Plotarea.ShowCatName},
+ ShowSerName: &attrValBool{Val: formatSet.Plotarea.ShowSerName},
+ ShowBubbleSize: &attrValBool{Val: formatSet.Plotarea.ShowBubbleSize},
+ ShowPercent: &attrValBool{Val: formatSet.Plotarea.ShowPercent},
+ ShowLeaderLines: &attrValBool{Val: formatSet.Plotarea.ShowLeaderLines},
+ }
+}
+
+// drawChartSeriesDLbls provides function to draw the c:dLbls element by given
+// format sets.
+func (f *File) drawChartSeriesDLbls(formatSet *formatChart) *cDLbls {
+ dLbls := &cDLbls{
+ ShowLegendKey: &attrValBool{Val: formatSet.Legend.ShowLegendKey},
+ ShowVal: &attrValBool{Val: formatSet.Plotarea.ShowVal},
+ ShowCatName: &attrValBool{Val: formatSet.Plotarea.ShowCatName},
+ ShowSerName: &attrValBool{Val: formatSet.Plotarea.ShowSerName},
+ ShowBubbleSize: &attrValBool{Val: formatSet.Plotarea.ShowBubbleSize},
+ ShowPercent: &attrValBool{Val: formatSet.Plotarea.ShowPercent},
+ ShowLeaderLines: &attrValBool{Val: formatSet.Plotarea.ShowLeaderLines},
+ }
+ chartSeriesDLbls := map[string]*cDLbls{Bar: dLbls, Bar3D: dLbls, Doughnut: dLbls, Line: dLbls, Pie: dLbls, Pie3D: dLbls, Radar: dLbls, Scatter: nil}
+ return chartSeriesDLbls[formatSet.Type]
+}
+
+// drawPlotAreaCatAx provides function to draw the c:catAx element.
+func (f *File) drawPlotAreaCatAx() []*cAxs {
+ return []*cAxs{
+ &cAxs{
+ AxID: &attrValInt{Val: 754001152},
+ Scaling: &cScaling{
+ Orientation: &attrValString{Val: "minMax"},
+ },
+ Delete: &attrValBool{Val: false},
+ AxPos: &attrValString{Val: "b"},
+ NumFmt: &cNumFmt{
+ FormatCode: "General",
+ SourceLinked: true,
+ },
+ MajorTickMark: &attrValString{Val: "none"},
+ MinorTickMark: &attrValString{Val: "none"},
+ TickLblPos: &attrValString{Val: "nextTo"},
+ SpPr: f.drawPlotAreaSpPr(),
+ TxPr: f.drawPlotAreaTxPr(),
+ CrossAx: &attrValInt{Val: 753999904},
+ Crosses: &attrValString{Val: "autoZero"},
+ Auto: &attrValBool{Val: true},
+ LblAlgn: &attrValString{Val: "ctr"},
+ LblOffset: &attrValInt{Val: 100},
+ NoMultiLvlLbl: &attrValBool{Val: false},
+ },
+ }
+}
+
+// drawPlotAreaCatAx provides function to draw the c:valAx element.
+func (f *File) drawPlotAreaValAx() []*cAxs {
+ return []*cAxs{
+ &cAxs{
+ AxID: &attrValInt{Val: 753999904},
+ Scaling: &cScaling{
+ Orientation: &attrValString{Val: "minMax"},
+ },
+ Delete: &attrValBool{Val: false},
+ AxPos: &attrValString{Val: "l"},
+ NumFmt: &cNumFmt{
+ FormatCode: "General",
+ SourceLinked: true,
+ },
+ MajorTickMark: &attrValString{Val: "none"},
+ MinorTickMark: &attrValString{Val: "none"},
+ TickLblPos: &attrValString{Val: "nextTo"},
+ SpPr: f.drawPlotAreaSpPr(),
+ TxPr: f.drawPlotAreaTxPr(),
+ CrossAx: &attrValInt{Val: 754001152},
+ Crosses: &attrValString{Val: "autoZero"},
+ CrossBetween: &attrValString{Val: "between"},
+ },
+ }
+}
+
+// drawPlotAreaSpPr provides function to draw the c:spPr element.
+func (f *File) drawPlotAreaSpPr() *cSpPr {
+ return &cSpPr{
+ Ln: &aLn{
+ W: 9525,
+ Cap: "flat",
+ Cmpd: "sng",
+ Algn: "ctr",
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{
+ Val: "tx1",
+ LumMod: &attrValInt{Val: 15000},
+ LumOff: &attrValInt{Val: 85000},
+ },
+ },
+ },
+ }
+}
+
+// drawPlotAreaTxPr provides function to draw the c:txPr element.
+func (f *File) drawPlotAreaTxPr() *cTxPr {
+ return &cTxPr{
+ BodyPr: aBodyPr{
+ Rot: -60000000,
+ SpcFirstLastPara: true,
+ VertOverflow: "ellipsis",
+ Vert: "horz",
+ Wrap: "square",
+ Anchor: "ctr",
+ AnchorCtr: true,
+ },
+ P: aP{
+ PPr: aPPr{
+ DefRPr: aDefRPr{
+ Sz: 900,
+ B: false,
+ I: false,
+ U: "none",
+ Strike: "noStrike",
+ Kern: 1200,
+ Baseline: 0,
+ SolidFill: &aSolidFill{
+ SchemeClr: &aSchemeClr{
+ Val: "tx1",
+ LumMod: &attrValInt{Val: 15000},
+ LumOff: &attrValInt{Val: 85000},
+ },
+ },
+ Latin: &aLatin{Typeface: "+mn-lt"},
+ Ea: &aEa{Typeface: "+mn-ea"},
+ Cs: &aCs{Typeface: "+mn-cs"},
+ },
+ },
+ EndParaRPr: &aEndParaRPr{Lang: "en-US"},
+ },
+ }
+}
+
+// addDrawingChart provides function to add chart graphic frame by given sheet,
+// drawingXML, cell, width, height, relationship index and format sets.
+func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rID int, formatSet *formatPicture) {
+ 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) * 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
+ cNvPrID := 1
+ _, ok := f.XLSX[drawingXML]
+ if ok { // Append Model
+ decodeWsDr := decodeWsDr{}
+ xml.Unmarshal([]byte(f.readXML(drawingXML)), &decodeWsDr)
+ cNvPrID = len(decodeWsDr.TwoCellAnchor) + 1
+ for _, v := range decodeWsDr.OneCellAnchor {
+ content.WsDr.OneCellAnchor = append(content.WsDr.OneCellAnchor, &xlsxCellAnchor{
+ EditAs: v.EditAs,
+ GraphicFrame: v.Content,
+ })
+ }
+ for _, v := range decodeWsDr.TwoCellAnchor {
+ content.WsDr.TwoCellAnchor = append(content.WsDr.TwoCellAnchor, &xlsxCellAnchor{
+ EditAs: v.EditAs,
+ GraphicFrame: v.Content,
+ })
+ }
+ }
+ twoCellAnchor := xlsxCellAnchor{}
+ twoCellAnchor.EditAs = "oneCell"
+ from := xlsxFrom{}
+ from.Col = colStart
+ from.ColOff = formatSet.OffsetX * EMU
+ from.Row = rowStart
+ from.RowOff = formatSet.OffsetY * EMU
+ to := xlsxTo{}
+ to.Col = colEnd
+ to.ColOff = x2 * EMU
+ to.Row = rowEnd
+ to.RowOff = y2 * EMU
+ twoCellAnchor.From = &from
+ twoCellAnchor.To = &to
+
+ graphicFrame := graphicFrame{
+ GraphicFrame: &xlsxGraphicFrame{
+ NvGraphicFramePr: xlsxNvGraphicFramePr{
+ CNvPr: &xlsxCNvPr{
+ ID: cNvPrID,
+ Name: "Chart " + strconv.Itoa(cNvPrID),
+ },
+ },
+ 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{
+ 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("", "", "", "")
+ result := r.Replace(string(output))
+ f.saveFileList(drawingXML, result)
+}
diff --git a/excelize_test.go b/excelize_test.go
index b5aa917..6c484e3 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -426,3 +426,38 @@ func TestCopySheet(t *testing.T) {
t.Log(err)
}
}
+
+func TestAddChart(t *testing.T) {
+ xlsx, err := OpenFile("./test/Workbook1.xlsx")
+ if err != nil {
+ t.Log(err)
+ }
+ xlsx.SetCellValue("SHEET1", "A30", "Small")
+ xlsx.SetCellValue("SHEET1", "A31", "Normal")
+ xlsx.SetCellValue("SHEET1", "A32", "Large")
+ xlsx.SetCellValue("SHEET1", "B29", "Apple")
+ xlsx.SetCellValue("SHEET1", "C29", "Prange")
+ xlsx.SetCellValue("SHEET1", "D29", "Pear")
+ xlsx.SetCellValue("SHEET1", "B30", 2)
+ xlsx.SetCellValue("SHEET1", "C30", 3)
+ xlsx.SetCellValue("SHEET1", "D30", 3)
+ xlsx.SetCellValue("SHEET1", "B31", 5)
+ xlsx.SetCellValue("SHEET1", "C31", 2)
+ xlsx.SetCellValue("SHEET1", "D31", 4)
+ xlsx.SetCellValue("SHEET1", "B32", 6)
+ xlsx.SetCellValue("SHEET1", "C32", 7)
+ xlsx.SetCellValue("SHEET1", "D32", 8)
+ xlsx.AddChart("SHEET1", "P1", `{"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 3D Bar 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"}`)
+ xlsx.AddChart("SHEET1", "X1", `{"type":"bar","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":"left","show_legend_key":false},"title":{"name":"Fruit Bar 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"}`)
+ xlsx.AddChart("SHEET1", "P16", `{"type":"doughnut","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":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut 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"}`)
+ xlsx.AddChart("SHEET1", "X16", `{"type":"line","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":"top","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"}`)
+ xlsx.AddChart("SHEET1", "P30", `{"type":"pie3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"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 3D Pie 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"}`)
+ xlsx.AddChart("SHEET1", "X30", `{"type":"pie","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"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 Pie 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":"gap"}`)
+ xlsx.AddChart("SHEET2", "P1", `{"type":"radar","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":"top_right","show_legend_key":false},"title":{"name":"Fruit Radar 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":"span"}`)
+ xlsx.AddChart("SHEET2", "X1", `{"type":"scatter","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 Scatter 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("./test/Workbook_6.xlsx")
+ if err != nil {
+ t.Log(err)
+ }
+}
diff --git a/file.go b/file.go
index d0f1c51..da1fbc7 100644
--- a/file.go
+++ b/file.go
@@ -15,15 +15,15 @@ import (
//
func CreateFile() *File {
file := make(map[string]string)
- file["_rels/.rels"] = templateRels
- file["docProps/app.xml"] = templateDocpropsApp
- file["docProps/core.xml"] = templateDocpropsCore
- file["xl/_rels/workbook.xml.rels"] = templateWorkbookRels
- file["xl/theme/theme1.xml"] = templateTheme
- file["xl/worksheets/sheet1.xml"] = templateSheet
- file["xl/styles.xml"] = templateStyles
- file["xl/workbook.xml"] = templateWorkbook
- file["[Content_Types].xml"] = templateContentTypes
+ file["_rels/.rels"] = XMLHeader + templateRels
+ file["docProps/app.xml"] = XMLHeader + templateDocpropsApp
+ file["docProps/core.xml"] = XMLHeader + templateDocpropsCore
+ file["xl/_rels/workbook.xml.rels"] = XMLHeader + templateWorkbookRels
+ file["xl/theme/theme1.xml"] = XMLHeader + templateTheme
+ file["xl/worksheets/sheet1.xml"] = XMLHeader + templateSheet
+ file["xl/styles.xml"] = XMLHeader + templateStyles
+ file["xl/workbook.xml"] = XMLHeader + templateWorkbook
+ file["[Content_Types].xml"] = XMLHeader + templateContentTypes
return &File{
Sheet: make(map[string]*xlsxWorksheet),
XLSX: file,
diff --git a/picture.go b/picture.go
index 3df8e98..61b489a 100644
--- a/picture.go
+++ b/picture.go
@@ -105,7 +105,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
f.addSheetDrawing(sheet, rID)
}
drawingRID = f.addDrawingRelationships(drawingID, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext)
- f.addDrawing(sheet, drawingXML, cell, file, image.Width, image.Height, drawingRID, formatSet)
+ f.addDrawingPicture(sheet, drawingXML, cell, file, image.Width, image.Height, drawingRID, formatSet)
f.addMedia(picture, ext)
f.addDrawingContentTypePart(drawingID)
return err
@@ -173,11 +173,12 @@ func (f *File) countDrawings() int {
return count
}
-// addDrawing provides function to add picture by given drawingXML, xAxis,
-// 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, width, height, rID int, formatSet *formatPicture) {
+// addDrawingPicture provides function to add picture by given sheet,
+// drawingXML, cell, file name, width, height relationship index and format
+// sets. 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) addDrawingPicture(sheet, drawingXML, cell, file string, width, height, rID int, formatSet *formatPicture) {
cell = strings.ToUpper(cell)
fromCol := string(strings.Map(letterOnlyMapF, cell))
fromRow, _ := strconv.Atoi(strings.Map(intOnlyMapF, cell))
@@ -321,8 +322,7 @@ func (f *File) setContentTypePartImageExtensions() {
}
// addDrawingContentTypePart provides function to add image part relationships
-// in http://purl.oclc.org/ooxml/officeDocument/relationships/image and
-// appropriate content type.
+// in the file [Content_Types].xml by given drawing index.
func (f *File) addDrawingContentTypePart(index int) {
f.setContentTypePartImageExtensions()
content := f.contentTypesReader()
diff --git a/rows.go b/rows.go
index b76a823..b753fcd 100644
--- a/rows.go
+++ b/rows.go
@@ -6,9 +6,10 @@ import (
"strings"
)
-// GetRows return all the rows in a sheet, for example:
+// GetRows return all the rows in a sheet by given "sheet" + index, for example:
//
-// rows := xlsx.GetRows("Sheet2")
+// index := xlsx.GetSheetIndex("Sheet2")
+// rows := xlsx.GetRows("sheet" + strconv.Itoa(index))
// for _, row := range rows {
// for _, colCell := range row {
// fmt.Print(colCell, "\t")
diff --git a/templates.go b/templates.go
index 68c2fa1..81b531e 100644
--- a/templates.go
+++ b/templates.go
@@ -10,9 +10,9 @@ const templateDocpropsApp = ``
-const templateWorkbook = ``
+const templateWorkbook = ``
-const templateStyles = ``
+const templateStyles = ``
const templateSheet = ``
@@ -22,4 +22,4 @@ const templateDocpropsCore = ``
-const templateTheme = ``
+const templateTheme = ``
diff --git a/test/images/chart.png b/test/images/chart.png
new file mode 100644
index 0000000..03482da
Binary files /dev/null and b/test/images/chart.png differ
diff --git a/xmlChart.go b/xmlChart.go
new file mode 100644
index 0000000..335e388
--- /dev/null
+++ b/xmlChart.go
@@ -0,0 +1,634 @@
+package excelize
+
+// chartSpace directly maps the xlsxChart element.
+type xlsxChartSpace struct {
+ ChartSpace cChartSpace `xml:"c:chartSpace"`
+}
+
+// cChartSpace 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 {
+ XMLNSc string `xml:"xmlns:c,attr"`
+ XMLNSa string `xml:"xmlns:a,attr"`
+ XMLNSr string `xml:"xmlns:r,attr"`
+ XMLNSc16r2 string `xml:"xmlns:c16r2,attr"`
+ Date1904 *attrValBool `xml:"c:date1904"`
+ Lang *attrValString `xml:"c:lang"`
+ RoundedCorners *attrValBool `xml:"c:roundedCorners"`
+ Chart cChart `xml:"c:chart"`
+ SpPr *cSpPr `xml:"c:spPr"`
+ TxPr *cTxPr `xml:"c:txPr"`
+ PrintSettings *cPrintSettings `xml:"c:printSettings"`
+}
+
+// cThicknessSpPr directly maps the element that specifies the thickness of the
+// walls or floor as a percentage of the largest dimension of the plot volume
+// and SpPr element.
+type cThicknessSpPr struct {
+ Thickness *attrValInt `xml:"c:thickness"`
+ SpPr *cSpPr `xml:"c:spPr"`
+}
+
+// cChart (Chart) directly maps the c:chart element. This element specifies a
+// title.
+type cChart struct {
+ Title *cTitle `xml:"c:title"`
+ AutoTitleDeleted *cAutoTitleDeleted `xml:"c:autoTitleDeleted"`
+ View3D *cView3D `xml:"c:view3D"`
+ Floor *cThicknessSpPr `xml:"c:floor"`
+ SideWall *cThicknessSpPr `xml:"c:sideWall"`
+ BackWall *cThicknessSpPr `xml:"c:backWall"`
+ PlotArea *cPlotArea `xml:"c:plotArea"`
+ Legend *cLegend `xml:"c:legend"`
+ PlotVisOnly *attrValBool `xml:"c:plotVisOnly"`
+ DispBlanksAs *attrValString `xml:"c:dispBlanksAs"`
+ ShowDLblsOverMax *attrValBool `xml:"c:showDLblsOverMax"`
+}
+
+// cTitle (Title) directly maps the c:title element. This element specifies a
+// title.
+type cTitle struct {
+ Tx cTx `xml:"c:tx,omitempty"`
+ Layout string `xml:"c:layout,omitempty"`
+ Overlay attrValBool `xml:"c:overlay,omitempty"`
+ SpPr cSpPr `xml:"c:spPr,omitempty"`
+ TxPr cTxPr `xml:"c:txPr,omitempty"`
+}
+
+// cTx (Chart Text) directly maps the c:tx element. This element specifies text
+// to use on a chart, including rich text formatting.
+type cTx struct {
+ StrRef *cStrRef `xml:"c:strRef"`
+ Rich *cRich `xml:"c:rich,omitempty"`
+}
+
+// cRich (Rich Text) directly maps the c:rich element. This element contains a
+// string with rich text formatting.
+type cRich struct {
+ BodyPr aBodyPr `xml:"a:bodyPr,omitempty"`
+ LstStyle string `xml:"a:lstStyle,omitempty"`
+ P aP `xml:"a:p"`
+}
+
+// aBodyPr (Body Properties) directly maps the a:bodyPr element. This element
+// defines the body properties for the text body within a shape.
+type aBodyPr struct {
+ Anchor string `xml:"anchor,attr,omitempty"`
+ AnchorCtr bool `xml:"anchorCtr,attr"`
+ Rot int `xml:"rot,attr"`
+ BIns float64 `xml:"bIns,attr,omitempty"`
+ CompatLnSpc bool `xml:"compatLnSpc,attr,omitempty"`
+ ForceAA bool `xml:"forceAA,attr,omitempty"`
+ FromWordArt bool `xml:"fromWordArt,attr,omitempty"`
+ HorzOverflow string `xml:"horzOverflow,attr,omitempty"`
+ LIns float64 `xml:"lIns,attr,omitempty"`
+ NumCol int `xml:"numCol,attr,omitempty"`
+ RIns float64 `xml:"rIns,attr,omitempty"`
+ RtlCol bool `xml:"rtlCol,attr,omitempty"`
+ SpcCol int `xml:"spcCol,attr,omitempty"`
+ SpcFirstLastPara bool `xml:"spcFirstLastPara,attr"`
+ TIns float64 `xml:"tIns,attr,omitempty"`
+ Upright bool `xml:"upright,attr,omitempty"`
+ Vert string `xml:"vert,attr,omitempty"`
+ VertOverflow string `xml:"vertOverflow,attr,omitempty"`
+ Wrap string `xml:"wrap,attr,omitempty"`
+}
+
+// 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"`
+ R *aR `xml:"a:r"`
+ EndParaRPr *aEndParaRPr `xml:"a:endParaRPr"`
+}
+
+// aPPr (Paragraph Properties) directly maps the a:pPr element. This element
+// specifies a set of paragraph properties which shall be applied to the
+// contents of the parent paragraph after all style/numbering/table properties
+// have been applied to the text. These properties are defined as direct
+// formatting, since they are directly applied to the paragraph and supersede
+// any formatting from styles.
+type aPPr struct {
+ DefRPr aDefRPr `xml:"a:defRPr"`
+}
+
+// aDefRPr directly maps the a:defRPr element. This element contains all
+// default run level text properties for the text runs within a containing
+// paragraph. These properties are to be used when overriding properties have
+// not been defined within the rPr element.
+type aDefRPr struct {
+ AltLang string `xml:"altLang,attr,omitempty"`
+ B bool `xml:"b,attr"`
+ Baseline int `xml:"baseline,attr"`
+ Bmk string `xml:"bmk,attr,omitempty"`
+ Cap string `xml:"cap,attr,omitempty"`
+ Dirty bool `xml:"dirty,attr,omitempty"`
+ Err bool `xml:"err,attr,omitempty"`
+ I bool `xml:"i,attr"`
+ Kern int `xml:"kern,attr"`
+ Kumimoji bool `xml:"kumimoji,attr,omitempty"`
+ Lang string `xml:"lang,attr,omitempty"`
+ NoProof bool `xml:"noProof,attr,omitempty"`
+ NormalizeH bool `xml:"normalizeH,attr,omitempty"`
+ SmtClean bool `xml:"smtClean,attr,omitempty"`
+ SmtID uint64 `xml:"smtId,attr,omitempty"`
+ Spc int `xml:"spc,attr"`
+ Strike string `xml:"strike,attr,omitempty"`
+ Sz int `xml:"sz,attr"`
+ U string `xml:"u,attr,omitempty"`
+ SolidFill *aSolidFill `xml:"a:solidFill"`
+ Latin *aLatin `xml:"a:latin"`
+ Ea *aEa `xml:"a:ea"`
+ Cs *aCs `xml:"a:cs"`
+}
+
+// aSolidFill (Solid Fill) directly maps the solidFill element. This element
+// specifies a solid color fill. The shape is filled entirely with the specified
+// color.
+type aSolidFill struct {
+ SchemeClr *aSchemeClr `xml:"a:schemeClr,omitempty"`
+}
+
+// aSchemeClr (Scheme Color) directly maps the a:schemeClr element. This
+// element specifies a color bound to a user's theme. As with all elements which
+// define a color, it is possible to apply a list of color transforms to the
+// base color defined.
+type aSchemeClr struct {
+ Val string `xml:"val,attr,omitempty"`
+ LumMod *attrValInt `xml:"a:lumMod"`
+ LumOff *attrValInt `xml:"a:lumOff"`
+}
+
+// attrValInt directly maps the val element with integer data type as an
+// attribute。
+type attrValInt struct {
+ Val int `xml:"val,attr"`
+}
+
+// attrValBool directly maps the val element with boolean data type as an
+// attribute。
+type attrValBool struct {
+ Val bool `xml:"val,attr"`
+}
+
+// attrValString directly maps the val element with string data type as an
+// attribute。
+type attrValString struct {
+ Val string `xml:"val,attr"`
+}
+
+// aCs directly maps the a:cs element.
+type aCs struct {
+ Typeface string `xml:"typeface,attr"`
+}
+
+// aEa directly maps the a:ea element.
+type aEa struct {
+ Typeface string `xml:"typeface,attr"`
+}
+
+// aLatin (Latin Font) directly maps the a:latin element. This element
+// specifies that a Latin font be used for a specific run of text. This font is
+// specified with a typeface attribute much like the others but is specifically
+// classified as a Latin font.
+type aLatin struct {
+ Typeface string `xml:"typeface,attr"`
+}
+
+// aR directly maps the a:r element.
+type aR struct {
+ RPr aRPr `xml:"a:rPr,omitempty"`
+ T string `xml:"a:t,omitempty"`
+}
+
+// aRPr (Run Properties) directly maps the c:rPr element. This element
+// specifies a set of run properties which shall be applied to the contents of
+// the parent run after all style formatting has been applied to the text. These
+// properties are defined as direct formatting, since they are directly applied
+// to the run and supersede any formatting from styles.
+type aRPr struct {
+ Lang string `xml:"lang,attr,omitempty"`
+ AltLang string `xml:"altLang,attr,omitempty"`
+}
+
+// cSpPr (Shape Properties) directly maps the c:spPr element. This element
+// specifies the visual shape properties that can be applied to a shape. These
+// properties include the shape fill, outline, geometry, effects, and 3D
+// orientation.
+type cSpPr struct {
+ NoFill *string `xml:"a:noFill"`
+ SolidFill *aSolidFill `xml:"a:solidFill"`
+ Ln *aLn `xml:"a:ln"`
+ Sp3D *aSp3D `xml:"a:sp3d"`
+ EffectLst *string `xml:"a:effectLst"`
+}
+
+// aSp3D (3-D Shape Properties) directly maps the a:sp3d element. This element
+// defines the 3D properties associated with a particular shape in DrawingML.
+// The 3D properties which can be applied to a shape are top and bottom bevels,
+// a contour and an extrusion.
+type aSp3D struct {
+ ContourW int `xml:"contourW,attr"`
+ ContourClr *aContourClr `xml:"a:contourClr"`
+}
+
+// aContourClr (Contour Color) directly maps the a:contourClr element. This
+// element defines the color for the contour on a shape. The contour of a shape
+// is a solid filled line which surrounds the outer edges of the shape.
+type aContourClr struct {
+ SchemeClr *aSchemeClr `xml:"a:schemeClr"`
+}
+
+// aLn (Outline) directly maps the a:ln element. This element specifies an
+// outline style that can be applied to a number of different objects such as
+// shapes and text. The line allows for the specifying of many different types
+// of outlines including even line dashes and bevels.
+type aLn struct {
+ Algn string `xml:"algn,attr,omitempty"`
+ Cap string `xml:"cap,attr,omitempty"`
+ Cmpd string `xml:"cmpd,attr,omitempty"`
+ W int `xml:"w,attr,omitempty" `
+ NoFill string `xml:"a:noFill,omitempty"`
+ Round string `xml:"a:round,omitempty"`
+ SolidFill *aSolidFill `xml:"a:solidFill"`
+}
+
+// cTxPr (Text Properties) directly maps the c:txPr element. This element
+// specifies text formatting. The lstStyle element is not supported.
+type cTxPr struct {
+ BodyPr aBodyPr `xml:"a:bodyPr,omitempty"`
+ LstStyle string `xml:"a:lstStyle,omitempty"`
+ P aP `xml:"a:p,omitempty"`
+}
+
+// aEndParaRPr (End Paragraph Run Properties) directly maps the a:endParaRPr
+// element. This element specifies the text run properties that are to be used
+// if another run is inserted after the last run specified. This effectively
+// saves the run property state so that it can be applied when the user enters
+// additional text. If this element is omitted, then the application can
+// determine which default properties to apply. It is recommended that this
+// 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"`
+}
+
+// cAutoTitleDeleted (Auto Title Is Deleted) directly maps the
+// c:autoTitleDeleted element. This element specifies the title shall not be
+// shown for this chart.
+type cAutoTitleDeleted struct {
+ Val bool `xml:"val,attr"`
+}
+
+// cView3D (View In 3D) directly maps the c:view3D element. This element
+// specifies the 3-D view of the chart.
+type cView3D struct {
+ RotX *attrValInt `xml:"c:rotX"`
+ RotY *attrValInt `xml:"c:rotY"`
+ DepthPercent *attrValInt `xml:"c:depthPercent"`
+ RAngAx *attrValInt `xml:"c:rAngAx"`
+}
+
+// cPlotArea directly maps the c:plotArea element. This element specifies the
+// plot area of the chart.
+type cPlotArea struct {
+ Layout *string `xml:"c:layout"`
+ BarChart *cCharts `xml:"c:barChart"`
+ Bar3DChart *cCharts `xml:"c:bar3DChart"`
+ DoughnutChart *cCharts `xml:"c:doughnutChart"`
+ LineChart *cCharts `xml:"c:lineChart"`
+ PieChart *cCharts `xml:"c:pieChart"`
+ Pie3DChart *cCharts `xml:"c:pie3DChart"`
+ RadarChart *cCharts `xml:"c:radarChart"`
+ ScatterChart *cCharts `xml:"c:scatterChart"`
+ CatAx []*cAxs `xml:"c:catAx"`
+ ValAx []*cAxs `xml:"c:valAx"`
+ SpPr *cSpPr `xml:"c:spPr"`
+}
+
+// cCharts specifies the common element of the chart.
+type cCharts struct {
+ BarDir *attrValString `xml:"c:barDir"`
+ Grouping *attrValString `xml:"c:grouping"`
+ RadarStyle *attrValString `xml:"c:radarStyle"`
+ ScatterStyle *attrValString `xml:"c:scatterStyle"`
+ VaryColors *attrValBool `xml:"c:varyColors"`
+ Ser *[]cSer `xml:"c:ser"`
+ DLbls *cDLbls `xml:"c:dLbls"`
+ HoleSize *attrValInt `xml:"c:holeSize"`
+ Smooth *attrValBool `xml:"c:smooth"`
+ AxID []*attrValInt `xml:"c:axId"`
+}
+
+// cAxs directly maps the c:catAx and c:valAx element.
+type cAxs struct {
+ AxID *attrValInt `xml:"c:axId"`
+ Scaling *cScaling `xml:"c:scaling"`
+ Delete *attrValBool `xml:"c:delete"`
+ AxPos *attrValString `xml:"c:axPos"`
+ NumFmt *cNumFmt `xml:"c:numFmt"`
+ MajorTickMark *attrValString `xml:"c:majorTickMark"`
+ MinorTickMark *attrValString `xml:"c:minorTickMark"`
+ TickLblPos *attrValString `xml:"c:tickLblPos"`
+ SpPr *cSpPr `xml:"c:spPr"`
+ TxPr *cTxPr `xml:"c:txPr"`
+ CrossAx *attrValInt `xml:"c:crossAx"`
+ Crosses *attrValString `xml:"c:crosses"`
+ CrossBetween *attrValString `xml:"c:crossBetween"`
+ Auto *attrValBool `xml:"c:auto"`
+ LblAlgn *attrValString `xml:"c:lblAlgn"`
+ LblOffset *attrValInt `xml:"c:lblOffset"`
+ NoMultiLvlLbl *attrValBool `xml:"c:noMultiLvlLbl"`
+}
+
+// cScaling directly maps the c:scaling element. This element contains
+// additional axis settings.
+type cScaling struct {
+ Orientation *attrValString `xml:"c:orientation"`
+}
+
+// cNumFmt (Numbering Format) directly maps the c:numFmt element. This element
+// specifies number formatting for the parent element.
+type cNumFmt struct {
+ FormatCode string `xml:"formatCode,attr"`
+ SourceLinked bool `xml:"sourceLinked,attr"`
+}
+
+// cSer directly maps the c:ser element. This element specifies a series on a
+// chart.
+type cSer struct {
+ IDx *attrValInt `xml:"c:idx"`
+ Order *attrValInt `xml:"c:order"`
+ Tx *cTx `xml:"c:tx"`
+ SpPr *cSpPr `xml:"c:spPr"`
+ DPt []*cDPt `xml:"c:dPt"`
+ DLbls *cDLbls `xml:"c:dLbls"`
+ Marker *cMarker `xml:"c:marker"`
+ InvertIfNegative *attrValBool `xml:"c:invertIfNegative"`
+ Cat *cCat `xml:"c:cat"`
+ Val *cVal `xml:"c:val"`
+ XVal *cCat `xml:"c:xVal"`
+ YVal *cVal `xml:"c:yVal"`
+ Smooth *attrValBool `xml:"c:smooth"`
+}
+
+// cMarker (Marker) directly maps the c:marker element. This element specifies a
+// data marker.
+type cMarker struct {
+ Symbol *attrValString `xml:"c:symbol"`
+ Size *attrValInt `xml:"c:size"`
+ SpPr *cSpPr `xml:"c:spPr"`
+}
+
+// cDPt (Data Point) directly maps the c:dPt element. This element specifies a
+// single data point.
+type cDPt struct {
+ IDx *attrValInt `xml:"c:idx"`
+ Bubble3D *attrValBool `xml:"c:bubble3D"`
+ SpPr *cSpPr `xml:"c:spPr"`
+}
+
+// cCat (Category Axis Data) directly maps the c:cat element. This element
+// specifies the data used for the category axis.
+type cCat struct {
+ StrRef *cStrRef `xml:"c:strRef"`
+}
+
+// cStrRef (String Reference) directly maps the c:strRef element. This element
+// specifies a reference to data for a single data label or title with a cache
+// of the last values used.
+type cStrRef struct {
+ F string `xml:"c:f"`
+ StrCache *cStrCache `xml:"c:strCache"`
+}
+
+// cStrCache (String Cache) directly maps the c:strCache element. This element
+// specifies the last string data used for a chart.
+type cStrCache struct {
+ Pt []*cPt `xml:"c:pt"`
+ PtCount *attrValInt `xml:"c:ptCount"`
+}
+
+// cPt directly maps the c:pt element. This element specifies data for a
+// particular data point.
+type cPt struct {
+ IDx int `xml:"idx,attr"`
+ V *string `xml:"c:v"`
+}
+
+// cVal directly maps the c:val element. This element specifies the data values
+// which shall be used to define the location of data markers on a chart.
+type cVal struct {
+ NumRef *cNumRef `xml:"c:numRef"`
+}
+
+// cNumRef directly maps the c:numRef element. This element specifies a
+// reference to numeric data with a cache of the last values used.
+type cNumRef struct {
+ F string `xml:"c:f"`
+ NumCache *cNumCache `xml:"c:numCache"`
+}
+
+// cNumCache directly maps the c:numCache element. This element specifies the
+// last data shown on the chart for a series.
+type cNumCache struct {
+ FormatCode string `xml:"c:formatCode"`
+ Pt []*cPt `xml:"c:pt"`
+ PtCount *attrValInt `xml:"c:ptCount"`
+}
+
+// cDLbls (Data Lables) directly maps the c:dLbls element. This element serves
+// as a root element that specifies the settings for the data labels for an
+// entire series or the entire chart. It contains child elements that specify
+// the specific formatting and positioning settings.
+type cDLbls struct {
+ ShowLegendKey *attrValBool `xml:"c:showLegendKey"`
+ ShowVal *attrValBool `xml:"c:showVal"`
+ ShowCatName *attrValBool `xml:"c:showCatName"`
+ ShowSerName *attrValBool `xml:"c:showSerName"`
+ ShowPercent *attrValBool `xml:"c:showPercent"`
+ ShowBubbleSize *attrValBool `xml:"c:showBubbleSize"`
+ ShowLeaderLines *attrValBool `xml:"c:showLeaderLines"`
+}
+
+// cLegend (Legend) directly maps the c:legend element. This element specifies
+// the legend.
+type cLegend struct {
+ Layout *string `xml:"c:layout"`
+ LegendPos *attrValString `xml:"c:legendPos"`
+ Overlay *attrValBool `xml:"c:overlay"`
+ SpPr *cSpPr `xml:"c:spPr"`
+ TxPr *cTxPr `xml:"c:txPr"`
+}
+
+// cPrintSettings directly maps the c:printSettings element. This element
+// specifies the print settings for the chart.
+type cPrintSettings struct {
+ HeaderFooter *string `xml:"c:headerFooter"`
+ PageMargins *cPageMargins `xml:"c:pageMargins"`
+ PageSetup *string `xml:"c:pageSetup"`
+}
+
+// cPageMargins directly maps the c:pageMargins element. This element specifies
+// the page margins for a chart.
+type cPageMargins struct {
+ B float64 `xml:"b,attr"`
+ Footer float64 `xml:"footer,attr"`
+ Header float64 `xml:"header,attr"`
+ L float64 `xml:"l,attr"`
+ R float64 `xml:"r,attr"`
+ T float64 `xml:"t,attr"`
+}
+
+// formatChart directly maps the format settings of the chart.
+type formatChart struct {
+ Type string `json:"type"`
+ Series []formatChartSeries `json:"series"`
+ Format formatPicture `json:"format"`
+ Legend formatChartLegend `json:"legend"`
+ Title formatChartTitle `json:"title"`
+ XAxis struct {
+ Crossing string `json:"crossing"`
+ MajorTickMark string `json:"major_tick_mark"`
+ MinorTickMark string `json:"minor_tick_mark"`
+ MinorUnitType string `json:"minor_unit_type"`
+ MajorUnit int `json:"major_unit"`
+ MajorUnitType string `json:"major_unit_type"`
+ DisplayUnits string `json:"display_units"`
+ DisplayUnitsVisible bool `json:"display_units_visible"`
+ DateAxis bool `json:"date_axis"`
+ NumFormat string `json:"num_format"`
+ NumFont struct {
+ Color string `json:"color"`
+ Bold bool `json:"bold"`
+ Italic bool `json:"italic"`
+ Underline bool `json:"underline"`
+ } `json:"num_font"`
+ NameLayout struct {
+ X float64 `json:"x"`
+ Y float64 `json:"y"`
+ } `json:"name_layout"`
+ } `json:"x_axis"`
+ YAxis struct {
+ Crossing string `json:"crossing"`
+ MajorTickMark string `json:"major_tick_mark"`
+ MinorTickMark string `json:"minor_tick_mark"`
+ MinorUnitType string `json:"minor_unit_type"`
+ MajorUnit int `json:"major_unit"`
+ MajorUnitType string `json:"major_unit_type"`
+ DisplayUnits string `json:"display_units"`
+ DisplayUnitsVisible bool `json:"display_units_visible"`
+ DateAxis bool `json:"date_axis"`
+ NumFormat string `json:"num_format"`
+ NumFont struct {
+ Color string `json:"color"`
+ Bold bool `json:"bold"`
+ Italic bool `json:"italic"`
+ Underline bool `json:"underline"`
+ } `json:"num_font"`
+ NameLayout struct {
+ X float64 `json:"x"`
+ Y float64 `json:"y"`
+ } `json:"name_layout"`
+ } `json:"y_axis"`
+ Chartarea struct {
+ Border struct {
+ None bool `json:"none"`
+ } `json:"border"`
+ Fill struct {
+ Color string `json:"color"`
+ } `json:"fill"`
+ Pattern struct {
+ Pattern string `json:"pattern"`
+ FgColor string `json:"fg_color"`
+ BgColor string `json:"bg_color"`
+ } `json:"pattern"`
+ } `json:"chartarea"`
+ Plotarea struct {
+ ShowBubbleSize bool `json:"show_bubble_size"`
+ ShowCatName bool `json:"show_cat_name"`
+ ShowLeaderLines bool `json:"show_leader_lines"`
+ ShowPercent bool `json:"show_percent"`
+ ShowSerName bool `json:"show_series_name"`
+ ShowVal bool `json:"show_val"`
+ Gradient struct {
+ Colors []string `json:"colors"`
+ } `json:"gradient"`
+ Border struct {
+ Color string `json:"color"`
+ Width int `json:"width"`
+ DashType string `json:"dash_type"`
+ } `json:"border"`
+ Fill struct {
+ Color string `json:"color"`
+ } `json:"fill"`
+ Layout struct {
+ X float64 `json:"x"`
+ Y float64 `json:"y"`
+ Width float64 `json:"width"`
+ Height float64 `json:"height"`
+ } `json:"layout"`
+ } `json:"plotarea"`
+ ShowBlanksAs string `json:"show_blanks_as"`
+ ShowHiddenData bool `json:"show_hidden_data"`
+ SetRotation int `json:"set_rotation"`
+ SetHoleSize int `json:"set_hole_size"`
+}
+
+// formatChartLegend directly maps the format settings of the chart legend.
+type formatChartLegend struct {
+ None bool `json:"none"`
+ DeleteSeries []int `json:"delete_series"`
+ Font struct {
+ Size int `json:"size"`
+ Blod bool `json:"blod"`
+ Italic bool `json:"italic"`
+ } `json:"font"`
+ Layout struct {
+ X float64 `json:"x"`
+ Y float64 `json:"y"`
+ Width float64 `json:"width"`
+ Height float64 `json:"height"`
+ } `json:"layout"`
+ Position string `json:"position"`
+ ShowLegendEntry bool `json:"show_legend_entry"`
+ ShowLegendKey bool `json:"show_legend_key"`
+}
+
+// formatChartSeries directly maps the format settings of the chart series.
+type formatChartSeries struct {
+ Name string `json:"name"`
+ Categories string `json:"categories"`
+ Values string `json:"values"`
+ Line struct {
+ None bool `json:"none"`
+ Color string `json:"color"`
+ } `json:"line"`
+ Marker struct {
+ Type string `json:"type"`
+ Size int `json:"size,"`
+ Width float64 `json:"width"`
+ Border struct {
+ Color string `json:"color"`
+ None bool `json:"none"`
+ } `json:"border"`
+ Fill struct {
+ Color string `json:"color"`
+ None bool `json:"none"`
+ } `json:"fill"`
+ } `json:"marker"`
+}
+
+// formatChartTitle directly maps the format settings of the chart title.
+type formatChartTitle struct {
+ None bool `json:"none"`
+ Name string `json:"name"`
+ Overlay bool `json:"overlay"`
+ Layout struct {
+ X float64 `json:"x"`
+ Y float64 `json:"y"`
+ Width float64 `json:"width"`
+ Height float64 `json:"height"`
+ } `json:"layout"`
+}
diff --git a/xmlContentTypes.go b/xmlContentTypes.go
index c44b8d5..121c684 100644
--- a/xmlContentTypes.go
+++ b/xmlContentTypes.go
@@ -2,7 +2,7 @@ package excelize
import "encoding/xml"
-// xlsxTypes directly maps the types elemen of content types for relationship
+// xlsxTypes directly maps the types element of content types for relationship
// parts, it takes a Multipurpose Internet Mail Extension (MIME) media type as a
// value.
type xlsxTypes struct {
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 4b87d9d..156b2ac 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -2,14 +2,20 @@ package excelize
// Source relationship and namespace.
const (
- SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
- SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
- SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
- SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
- SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
- NameSpaceDrawingML = "http://schemas.openxmlformats.org/drawingml/2006/main"
- NameSpaceSpreadSheetDrawing = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
- NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
+ SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
+ SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
+ SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
+ SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
+ SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
+ SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
+ SourceRelationshipChart201506 = "http://schemas.microsoft.com/office/drawing/2015/06/chart"
+ SourceRelationshipChart20070802 = "http://schemas.microsoft.com/office/drawing/2007/8/2/chart"
+ SourceRelationshipChart2014 = "http://schemas.microsoft.com/office/drawing/2014/chart"
+ SourceRelationshipCompatibility = "http://schemas.openxmlformats.org/markup-compatibility/2006"
+ NameSpaceDrawingML = "http://schemas.openxmlformats.org/drawingml/2006/main"
+ NameSpaceDrawingMLChart = "http://schemas.openxmlformats.org/drawingml/2006/chart"
+ NameSpaceSpreadSheetDrawing = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
+ NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
)
var supportImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png"}
@@ -187,6 +193,59 @@ type xlsxWsDr struct {
A string `xml:"xmlns:a,attr"`
}
+// graphicFrame (Graphic Frame) directly maps the graphicFrame element.
+type graphicFrame struct {
+ GraphicFrame *xlsxGraphicFrame `xml:"xdr:graphicFrame"`
+}
+
+// xlsxGraphicFrame (Graphic Frame) directly maps the xdr:graphicFrame element.
+// This element specifies the existence of a graphics frame. This frame contains
+// 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 {
+ Macro string `xml:"macro,attr"`
+ NvGraphicFramePr xlsxNvGraphicFramePr `xml:"xdr:nvGraphicFramePr"`
+ Xfrm xlsxXfrm `xml:"xdr:xfrm"`
+ Graphic *xlsxGraphic `xml:"a:graphic"`
+}
+
+// xlsxNvGraphicFramePr (Non-Visual Properties for a Graphic Frame) directly
+// maps the xdr:nvGraphicFramePr element. This element specifies all non-visual
+// properties for a graphic frame. This element is a container for the non-
+// visual identification properties, shape properties and application properties
+// that are to be associated with a graphic frame. This allows for additional
+// information that does not affect the appearance of the graphic frame to be
+// stored.
+type xlsxNvGraphicFramePr struct {
+ CNvPr *xlsxCNvPr `xml:"xdr:cNvPr"`
+ ChicNvGraphicFramePr string `xml:"xdr:cNvGraphicFramePr"`
+}
+
+// xlsxGraphic (Graphic Object) directly maps the a:graphic element. This
+// element specifies the existence of a single graphic object. Document authors
+// should refer to this element when they wish to persist a graphical object of
+// some kind. The specification for this graphical object is provided entirely
+// by the document author and referenced within the graphicData child element.
+type xlsxGraphic struct {
+ GraphicData *xlsxGraphicData `xml:"a:graphicData"`
+}
+
+// xlsxGraphicData (Graphic Object Data) directly maps the a:graphicData
+// element. This element specifies the reference to a graphic object within the
+// document. This graphic object is provided entirely by the document authors
+// who choose to persist this data within the document.
+type xlsxGraphicData struct {
+ URI string `xml:"uri,attr"`
+ Chart *xlsxChart `xml:"c:chart,omitempty"`
+}
+
+// xlsxChart (Chart) directly maps the c:chart element.
+type xlsxChart struct {
+ C string `xml:"xmlns:c,attr"`
+ RID string `xml:"r:id,attr"`
+ R string `xml:"xmlns:r,attr"`
+}
+
// encodeWsDr directly maps the element xdr:wsDr.
type encodeWsDr struct {
WsDr xlsxWsDr `xml:"xdr:wsDr"`