소스 검색

Code optimize.

Ri Xu 8 년 전
부모
커밋
dea57dd0ae
10개의 변경된 파일168개의 추가작업 그리고 303개의 파일을 삭제
  1. 16 28
      cell.go
  2. 71 98
      chart.go
  3. 1 1
      comment.go
  4. 4 22
      excelize.go
  5. 30 58
      picture.go
  6. 4 20
      shape.go
  7. 10 3
      sheet.go
  8. 1 16
      table.go
  9. 31 49
      xmlChart.go
  10. 0 8
      xmlWorkbook.go

+ 16 - 28
cell.go

@@ -6,13 +6,9 @@ import (
 	"strings"
 )
 
-// GetCellValue provides function to get formatted value from cell by given
-// sheet index and axis in XLSX file. If it is possible to apply a format to the
-// cell value, it will do so, if not then an error will be returned, along with
-// the raw value of the cell.
-func (f *File) GetCellValue(sheet, axis string) string {
-	xlsx := f.workSheetReader(sheet)
-	axis = strings.ToUpper(axis)
+// mergeCellsParser provides function to check merged cells in worksheet by
+// given axis.
+func (f *File) mergeCellsParser(xlsx *xlsxWorksheet, axis string) {
 	if xlsx.MergeCells != nil {
 		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
 			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
@@ -20,6 +16,16 @@ func (f *File) GetCellValue(sheet, axis string) string {
 			}
 		}
 	}
+}
+
+// GetCellValue provides function to get formatted value from cell by given
+// sheet index and axis in XLSX file. If it is possible to apply a format to the
+// cell value, it will do so, if not then an error will be returned, along with
+// the raw value of the cell.
+func (f *File) GetCellValue(sheet, axis string) string {
+	xlsx := f.workSheetReader(sheet)
+	axis = strings.ToUpper(axis)
+	f.mergeCellsParser(xlsx, axis)
 	row, _ := strconv.Atoi(strings.Map(intOnlyMapF, axis))
 	xAxis := row - 1
 	rows := len(xlsx.SheetData.Row)
@@ -78,13 +84,7 @@ func (f *File) formattedValue(s int, v string) string {
 func (f *File) GetCellFormula(sheet, axis string) string {
 	xlsx := f.workSheetReader(sheet)
 	axis = strings.ToUpper(axis)
-	if xlsx.MergeCells != nil {
-		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
-			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
-				axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
-			}
-		}
-	}
+	f.mergeCellsParser(xlsx, axis)
 	row, _ := strconv.Atoi(strings.Map(intOnlyMapF, axis))
 	xAxis := row - 1
 	rows := len(xlsx.SheetData.Row)
@@ -118,13 +118,7 @@ func (f *File) GetCellFormula(sheet, axis string) string {
 func (f *File) SetCellFormula(sheet, axis, formula string) {
 	xlsx := f.workSheetReader(sheet)
 	axis = strings.ToUpper(axis)
-	if xlsx.MergeCells != nil {
-		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
-			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
-				axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
-			}
-		}
-	}
+	f.mergeCellsParser(xlsx, axis)
 	col := string(strings.Map(letterOnlyMapF, axis))
 	row, _ := strconv.Atoi(strings.Map(intOnlyMapF, axis))
 	xAxis := row - 1
@@ -151,13 +145,7 @@ func (f *File) SetCellFormula(sheet, axis, formula string) {
 func (f *File) SetCellHyperLink(sheet, axis, link string) {
 	xlsx := f.workSheetReader(sheet)
 	axis = strings.ToUpper(axis)
-	if xlsx.MergeCells != nil {
-		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
-			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
-				axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
-			}
-		}
-	}
+	f.mergeCellsParser(xlsx, axis)
 	rID := f.addSheetRelationships(sheet, SourceRelationshipHyperLink, link, "External")
 	hyperlink := xlsxHyperlink{
 		Ref: axis,

+ 71 - 98
chart.go

@@ -187,24 +187,12 @@ func (f *File) AddChart(sheet, cell, format string) {
 	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")
+	drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
+	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)
+	f.addContentTypePart(chartID, "chart")
+	f.addContentTypePart(drawingID, "drawings")
 }
 
 // countCharts provides function to get chart files count storage in the
@@ -219,19 +207,21 @@ func (f *File) countCharts() int {
 	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
-		}
+// prepareDrawing provides function to prepare drawing ID and XML by given
+// drawingID, worksheet index and default drawingXML.
+func (f *File) prepareDrawing(xlsx *xlsxWorksheet, drawingID int, sheet, drawingXML string) (int, string) {
+	sheetRelationshipsDrawingXML := "../drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
+	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)
 	}
-	content.Overrides = append(content.Overrides, xlsxOverride{
-		PartName:    "/xl/charts/chart" + strconv.Itoa(index) + ".xml",
-		ContentType: "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
-	})
+	return drawingID, drawingXML
 }
 
 // addChart provides function to create chart as xl/charts/chart%d.xml by given
@@ -364,7 +354,7 @@ func (f *File) addChart(formatSet *formatChart) {
 	}
 	plotAreaFunc := map[string]func(*formatChart) *cPlotArea{
 		Bar:      f.drawBarChart,
-		Bar3D:    f.drawBar3DChart,
+		Bar3D:    f.drawBarChart,
 		Doughnut: f.drawDoughnutChart,
 		Line:     f.drawLineChart,
 		Pie3D:    f.drawPie3DChart,
@@ -379,56 +369,39 @@ func (f *File) addChart(formatSet *formatChart) {
 	f.saveFileList(media, string(chart))
 }
 
-// drawBarChart provides function to draw the c:plotArea element for bar chart
-// by given format sets.
+// drawBarChart provides function to draw the c:plotArea element for bar and
+// bar3D 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{
-				{Val: 754001152},
-				{Val: 753999904},
-			},
+	c := cCharts{
+		BarDir: &attrValString{
+			Val: "col",
+		},
+		Grouping: &attrValString{
+			Val: "clustered",
+		},
+		VaryColors: &attrValBool{
+			Val: true,
+		},
+		Ser:   f.drawChartSeries(formatSet),
+		DLbls: f.drawChartDLbls(formatSet),
+		AxID: []*attrValInt{
+			{Val: 754001152},
+			{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{
-				{Val: 754001152},
-				{Val: 753999904},
-			},
+	charts := map[string]*cPlotArea{
+		"bar": &cPlotArea{
+			BarChart: &c,
+			CatAx:    f.drawPlotAreaCatAx(),
+			ValAx:    f.drawPlotAreaValAx(),
+		},
+		"bar3D": &cPlotArea{
+			Bar3DChart: &c,
+			CatAx:      f.drawPlotAreaCatAx(),
+			ValAx:      f.drawPlotAreaValAx(),
 		},
-		CatAx: f.drawPlotAreaCatAx(),
-		ValAx: f.drawPlotAreaValAx(),
 	}
+	return charts[formatSet.Type]
 }
 
 // drawDoughnutChart provides function to draw the c:plotArea element for
@@ -711,15 +684,7 @@ func (f *File) drawChartDLbls(formatSet *formatChart) *cDLbls {
 // 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},
-	}
+	dLbls := f.drawChartDLbls(formatSet)
 	chartSeriesDLbls := map[string]*cDLbls{Bar: dLbls, Bar3D: dLbls, Doughnut: dLbls, Line: dLbls, Pie: dLbls, Pie3D: dLbls, Radar: dLbls, Scatter: nil}
 	return chartSeriesDLbls[formatSet.Type]
 }
@@ -837,21 +802,11 @@ func (f *File) drawPlotAreaTxPr() *cTxPr {
 	}
 }
 
-// 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 := xlsxWsDr{}
-	content.A = NameSpaceDrawingML
-	content.Xdr = NameSpaceDrawingMLSpreadSheet
-	cNvPrID := 1
+// drawingParser provides function to parse drawingXML. 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) drawingParser(drawingXML string, cNvPrID int, content *xlsxWsDr) {
 	_, ok := f.XLSX[drawingXML]
 	if ok { // Append Model
 		decodeWsDr := decodeWsDr{}
@@ -870,6 +825,24 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
 			})
 		}
 	}
+}
+
+// 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 := xlsxWsDr{}
+	content.A = NameSpaceDrawingML
+	content.Xdr = NameSpaceDrawingMLSpreadSheet
+	cNvPrID := 1
+	f.drawingParser(drawingXML, cNvPrID, &content)
 	twoCellAnchor := xdrCellAnchor{}
 	twoCellAnchor.EditAs = "oneCell"
 	from := xlsxFrom{}

+ 1 - 1
comment.go

@@ -47,7 +47,7 @@ func (f *File) AddComment(sheet, cell, format string) {
 	commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml"
 	f.addComment(commentsXML, cell, formatSet)
 	f.addDrawingVML(commentID, drawingVML, cell)
-	f.addCommentsContentTypePart(commentID)
+	f.addContentTypePart(commentID, "comments")
 }
 
 // addDrawingVML provides function to create comment as

+ 4 - 22
excelize.go

@@ -123,13 +123,7 @@ func (f *File) workSheetReader(sheet string) *xlsxWorksheet {
 func (f *File) SetCellInt(sheet, axis string, value int) {
 	xlsx := f.workSheetReader(sheet)
 	axis = strings.ToUpper(axis)
-	if xlsx.MergeCells != nil {
-		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
-			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
-				axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
-			}
-		}
-	}
+	f.mergeCellsParser(xlsx, axis)
 	col := string(strings.Map(letterOnlyMapF, axis))
 	row, _ := strconv.Atoi(strings.Map(intOnlyMapF, axis))
 	xAxis := row - 1
@@ -150,13 +144,7 @@ func (f *File) SetCellInt(sheet, axis string, value int) {
 func (f *File) SetCellStr(sheet, axis, value string) {
 	xlsx := f.workSheetReader(sheet)
 	axis = strings.ToUpper(axis)
-	if xlsx.MergeCells != nil {
-		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
-			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
-				axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
-			}
-		}
-	}
+	f.mergeCellsParser(xlsx, axis)
 	if len(value) > 32767 {
 		value = value[0:32767]
 	}
@@ -189,13 +177,7 @@ func (f *File) SetCellStr(sheet, axis, value string) {
 func (f *File) SetCellDefault(sheet, axis, value string) {
 	xlsx := f.workSheetReader(sheet)
 	axis = strings.ToUpper(axis)
-	if xlsx.MergeCells != nil {
-		for i := 0; i < len(xlsx.MergeCells.Cells); i++ {
-			if checkCellInArea(axis, xlsx.MergeCells.Cells[i].Ref) {
-				axis = strings.Split(xlsx.MergeCells.Cells[i].Ref, ":")[0]
-			}
-		}
-	}
+	f.mergeCellsParser(xlsx, axis)
 	col := string(strings.Map(letterOnlyMapF, axis))
 	row, _ := strconv.Atoi(strings.Map(intOnlyMapF, axis))
 	xAxis := row - 1
@@ -272,7 +254,7 @@ func completeRow(xlsx *xlsxWorksheet, row, cell int) {
 // continuous in a worksheet of XML.
 func checkSheet(xlsx *xlsxWorksheet) {
 	row := len(xlsx.SheetData.Row)
-	if row > 1 {
+	if row >= 1 {
 		lastRow := xlsx.SheetData.Row[row-1].R
 		if lastRow >= row {
 			row = lastRow

+ 30 - 58
picture.go

@@ -90,23 +90,11 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
 	drawingID := f.countDrawings() + 1
 	pictureID := f.countMedia() + 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, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext)
+	drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
+	drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipImage, "../media/image"+strconv.Itoa(pictureID)+ext)
 	f.addDrawingPicture(sheet, drawingXML, cell, file, image.Width, image.Height, drawingRID, formatSet)
 	f.addMedia(picture, ext)
-	f.addDrawingContentTypePart(drawingID)
+	f.addContentTypePart(drawingID, "drawings")
 	return err
 }
 
@@ -180,9 +168,7 @@ func (f *File) countDrawings() int {
 
 // addDrawingPicture provides function to add picture by given sheet,
 // drawingXML, cell, file name, width, height relationship index and format
-// sets. In order to solve the problem that the label structure is changed after
-// serialization and deserialization, two different structures: decodeWsDr and
-// encodeWsDr are defined.
+// sets.
 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))
@@ -196,24 +182,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
 	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,
-			})
-		}
-	}
+	f.drawingParser(drawingXML, cNvPrID, &content)
 	twoCellAnchor := xdrCellAnchor{}
 	twoCellAnchor.EditAs = "oneCell"
 	from := xlsxFrom{}
@@ -335,35 +304,38 @@ func (f *File) setContentTypePartVMLExtensions() {
 	}
 }
 
-// addDrawingContentTypePart provides function to add image part relationships
-// in the file [Content_Types].xml by given drawing index.
-func (f *File) addDrawingContentTypePart(index int) {
-	f.setContentTypePartImageExtensions()
-	content := f.contentTypesReader()
-	for _, v := range content.Overrides {
-		if v.PartName == "/xl/drawings/drawing"+strconv.Itoa(index)+".xml" {
-			return
-		}
+// addContentTypePart provides function to add content type part relationships
+// in the file [Content_Types].xml by given index.
+func (f *File) addContentTypePart(index int, contentType string) {
+	setContentType := map[string]func(){
+		"comments": f.setContentTypePartVMLExtensions,
+		"drawings": f.setContentTypePartImageExtensions,
+	}
+	partNames := map[string]string{
+		"chart":    "/xl/charts/chart" + strconv.Itoa(index) + ".xml",
+		"comments": "/xl/comments" + strconv.Itoa(index) + ".xml",
+		"drawings": "/xl/drawings/drawing" + strconv.Itoa(index) + ".xml",
+		"table":    "/xl/tables/table" + strconv.Itoa(index) + ".xml",
+	}
+	contentTypes := map[string]string{
+		"chart":    "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
+		"comments": "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
+		"drawings": "application/vnd.openxmlformats-officedocument.drawing+xml",
+		"table":    "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
+	}
+	s, ok := setContentType[contentType]
+	if ok {
+		s()
 	}
-	content.Overrides = append(content.Overrides, xlsxOverride{
-		PartName:    "/xl/drawings/drawing" + strconv.Itoa(index) + ".xml",
-		ContentType: "application/vnd.openxmlformats-officedocument.drawing+xml",
-	})
-}
-
-// addCommentsContentTypePart provides function to add comments part
-// relationships in the file [Content_Types].xml by given comment index.
-func (f *File) addCommentsContentTypePart(index int) {
-	f.setContentTypePartVMLExtensions()
 	content := f.contentTypesReader()
 	for _, v := range content.Overrides {
-		if v.PartName == "/xl/comments"+strconv.Itoa(index)+".xml" {
+		if v.PartName == partNames[contentType] {
 			return
 		}
 	}
 	content.Overrides = append(content.Overrides, xlsxOverride{
-		PartName:    "/xl/comments" + strconv.Itoa(index) + ".xml",
-		ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
+		PartName:    partNames[contentType],
+		ContentType: contentTypes[contentType],
 	})
 }
 

+ 4 - 20
shape.go

@@ -274,10 +274,11 @@ func (f *File) AddShape(sheet, cell, format string) {
 		f.addSheetDrawing(sheet, rID)
 	}
 	f.addDrawingShape(sheet, drawingXML, cell, formatSet)
-	f.addDrawingContentTypePart(drawingID)
+	f.addContentTypePart(drawingID, "drawings")
 }
 
-// addDrawingShape
+// addDrawingShape provides function to add preset geometry by given sheet,
+// drawingXMLand format sets.
 func (f *File) addDrawingShape(sheet, drawingXML, cell string, formatSet *formatShape) {
 	textUnderlineType := map[string]bool{"none": true, "words": true, "sng": true, "dbl": true, "heavy": true, "dotted": true, "dottedHeavy": true, "dash": true, "dashHeavy": true, "dashLong": true, "dashLongHeavy": true, "dotDash": true, "dotDashHeavy": true, "dotDotDash": true, "dotDotDashHeavy": true, "wavy": true, "wavyHeavy": true, "wavyDbl": true}
 	u := formatSet.Font.Underline
@@ -297,24 +298,7 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, formatSet *format
 	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,
-			})
-		}
-	}
+	f.drawingParser(drawingXML, cNvPrID, &content)
 	twoCellAnchor := xdrCellAnchor{}
 	twoCellAnchor.EditAs = "oneCell"
 	from := xlsxFrom{}

+ 10 - 3
sheet.go

@@ -437,13 +437,20 @@ func (f *File) copySheet(from, to int) {
 
 // HideSheet provides function to hide worksheet by given name. A workbook must
 // contain at least one visible worksheet. If the given worksheet has been
-// activated, this setting will be invalidated.
+// activated, this setting will be invalidated. Sheet state values as defined by
+// http://msdn.microsoft.com/en-
+// us/library/office/documentformat.openxml.spreadsheet.sheetstatevalues.aspx
+//
+//    visible
+//    hidden
+//    veryHidden
+//
 func (f *File) HideSheet(name string) {
 	name = trimSheetName(name)
 	content := f.workbookReader()
 	count := 0
 	for _, v := range content.Sheets.Sheet {
-		if v.State != sheetStateHidden {
+		if v.State != `hidden` {
 			count++
 		}
 	}
@@ -455,7 +462,7 @@ func (f *File) HideSheet(name string) {
 			tabSelected = xlsx.SheetViews.SheetView[0].TabSelected
 		}
 		if v.Name == name && count > 1 && !tabSelected {
-			content.Sheets.Sheet[k].State = sheetStateHidden
+			content.Sheets.Sheet[k].State = `hidden`
 		}
 	}
 }

+ 1 - 16
table.go

@@ -64,7 +64,7 @@ func (f *File) AddTable(sheet, hcell, vcell, format string) {
 	rID := f.addSheetRelationships(sheet, SourceRelationshipTable, sheetRelationshipsTableXML, "")
 	f.addSheetTable(sheet, rID)
 	f.addTable(sheet, tableXML, hxAxis, hyAxis, vxAxis, vyAxis, tableID, formatSet)
-	f.addTableContentTypePart(tableID)
+	f.addContentTypePart(tableID, "table")
 }
 
 // countTables provides function to get table files count storage in the folder
@@ -150,18 +150,3 @@ func (f *File) addTable(sheet, tableXML string, hxAxis, hyAxis, vxAxis, vyAxis,
 	table, _ := xml.Marshal(t)
 	f.saveFileList(tableXML, string(table))
 }
-
-// addTableContentTypePart provides function to add image part relationships
-// in the file [Content_Types].xml by given drawing index.
-func (f *File) addTableContentTypePart(index int) {
-	content := f.contentTypesReader()
-	for _, v := range content.Overrides {
-		if v.PartName == "/xl/tables/table"+strconv.Itoa(index)+".xml" {
-			return
-		}
-	}
-	content.Overrides = append(content.Overrides, xlsxOverride{
-		PartName:    "/xl/tables/table" + strconv.Itoa(index) + ".xml",
-		ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
-	})
-}

+ 31 - 49
xmlChart.go

@@ -473,57 +473,39 @@ type cPageMargins struct {
 	T      float64 `xml:"t,attr"`
 }
 
+// formatChartAxis directly maps the format settings of the chart axis.
+type formatChartAxis 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"`
+}
+
 // 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"`
+	Type      string              `json:"type"`
+	Series    []formatChartSeries `json:"series"`
+	Format    formatPicture       `json:"format"`
+	Legend    formatChartLegend   `json:"legend"`
+	Title     formatChartTitle    `json:"title"`
+	XAxis     formatChartAxis     `json:"x_axis"`
+	YAxis     formatChartAxis     `json:"y_axis"`
 	Chartarea struct {
 		Border struct {
 			None bool `json:"none"`

+ 0 - 8
xmlWorkbook.go

@@ -2,14 +2,6 @@ package excelize
 
 import "encoding/xml"
 
-const (
-	// sheet state values as defined by
-	// http://msdn.microsoft.com/en-us/library/office/documentformat.openxml.spreadsheet.sheetstatevalues.aspx
-	sheetStateVisible    = `visible`
-	sheetStateHidden     = `hidden`
-	sheetStateVeryHidden = `veryHidden`
-)
-
 // xmlxWorkbookRels contains xmlxWorkbookRelations which maps sheet id and sheet XML.
 type xlsxWorkbookRels struct {
 	XMLName       xml.Name               `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`