forked from p30928647/excelize
Resolve #451, support create chart sheet
This commit is contained in:
parent
a75c6f63be
commit
6afc468a02
1
LICENSE
1
LICENSE
|
@ -1,7 +1,6 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2016-2020, 360 Enterprise Security Group, Endpoint Security, Inc.
|
||||
Copyright (c) 2011-2017, Geoffrey J. Teale
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
68
chart.go
68
chart.go
|
@ -11,7 +11,9 @@ package excelize
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
@ -768,6 +770,72 @@ func (f *File) AddChart(sheet, cell, format string, combo ...string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// AddChartSheet provides the method to create a chartsheet by given chart
|
||||
// format set (such as offset, scale, aspect ratio setting and print settings)
|
||||
// and properties set. In Excel a chartsheet is a worksheet that only contains
|
||||
// a chart.
|
||||
func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
|
||||
// Check if the worksheet already exists
|
||||
if f.GetSheetIndex(sheet) != 0 {
|
||||
return errors.New("already existing name worksheet")
|
||||
}
|
||||
formatSet, err := parseFormatChartSet(format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
comboCharts := []*formatChart{}
|
||||
for _, comboFormat := range combo {
|
||||
comboChart, err := parseFormatChartSet(comboFormat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := chartValAxNumFmtFormatCode[comboChart.Type]; !ok {
|
||||
return errors.New("unsupported chart type " + comboChart.Type)
|
||||
}
|
||||
comboCharts = append(comboCharts, comboChart)
|
||||
}
|
||||
if _, ok := chartValAxNumFmtFormatCode[formatSet.Type]; !ok {
|
||||
return errors.New("unsupported chart type " + formatSet.Type)
|
||||
}
|
||||
cs := xlsxChartsheet{
|
||||
SheetViews: []*xlsxChartsheetViews{{
|
||||
SheetView: []*xlsxChartsheetView{{ZoomScaleAttr: 100, ZoomToFitAttr: true}}},
|
||||
},
|
||||
}
|
||||
wb := f.workbookReader()
|
||||
sheetID := 0
|
||||
for _, v := range wb.Sheets.Sheet {
|
||||
if v.SheetID > sheetID {
|
||||
sheetID = v.SheetID
|
||||
}
|
||||
}
|
||||
sheetID++
|
||||
path := "xl/chartsheets/sheet" + strconv.Itoa(sheetID) + ".xml"
|
||||
f.sheetMap[trimSheetName(sheet)] = path
|
||||
f.Sheet[path] = nil
|
||||
drawingID := f.countDrawings() + 1
|
||||
chartID := f.countCharts() + 1
|
||||
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||
drawingID, drawingXML = f.prepareChartSheetDrawing(&cs, drawingID, sheet, drawingXML)
|
||||
drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
|
||||
drawingRID := f.addRels(drawingRels, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
|
||||
err = f.addSheetDrawingChart(sheet, drawingXML, formatSet.Dimension.Width, formatSet.Dimension.Height, drawingRID, &formatSet.Format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.addChart(formatSet, comboCharts)
|
||||
f.addContentTypePart(chartID, "chart")
|
||||
f.addContentTypePart(sheetID, "chartsheet")
|
||||
f.addContentTypePart(drawingID, "drawings")
|
||||
// Update xl/_rels/workbook.xml.rels
|
||||
rID := f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipChartsheet, fmt.Sprintf("chartsheets/sheet%d.xml", sheetID), "")
|
||||
// Update xl/workbook.xml
|
||||
f.setWorkbook(sheet, sheetID, rID)
|
||||
v, _ := xml.Marshal(cs)
|
||||
f.saveFileList(path, replaceRelationshipsBytes(replaceWorkSheetsRelationshipsNameSpaceBytes(v)))
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteChart provides a function to delete chart in XLSX by given worksheet
|
||||
// and cell name.
|
||||
func (f *File) DeleteChart(sheet, cell string) (err error) {
|
||||
|
|
|
@ -200,12 +200,31 @@ func TestAddChart(t *testing.T) {
|
|||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddChart.xlsx")))
|
||||
// Test with unsupported chart type
|
||||
assert.EqualError(t, f.AddChart("Sheet2", "BD32", `{"type":"unknown","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"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"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":"Bubble 3D 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"}`), "unsupported chart type unknown")
|
||||
// Test add combo chart with invalid format set.
|
||||
// Test add combo chart with invalid format set
|
||||
assert.EqualError(t, f.AddChart("Sheet2", "BD32", `{"type":"col","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"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"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":"2D Column 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"}`, ""), "unexpected end of JSON input")
|
||||
// Test add combo chart with unsupported chart type.
|
||||
// Test add combo chart with unsupported chart type
|
||||
assert.EqualError(t, f.AddChart("Sheet2", "BD64", `{"type":"barOfPie","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$A$30:$D$37","values":"Sheet1!$B$30:$B$37"}],"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":"Bar of 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","x_axis":{"major_grid_lines":true},"y_axis":{"major_grid_lines":true}}`, `{"type":"unknown","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$A$30:$D$37","values":"Sheet1!$B$30:$B$37"}],"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":"Bar of 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","x_axis":{"major_grid_lines":true},"y_axis":{"major_grid_lines":true}}`), "unsupported chart type unknown")
|
||||
}
|
||||
|
||||
func TestAddChartSheet(t *testing.T) {
|
||||
categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
|
||||
values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8}
|
||||
f := NewFile()
|
||||
for k, v := range categories {
|
||||
assert.NoError(t, f.SetCellValue("Sheet1", k, v))
|
||||
}
|
||||
for k, v := range values {
|
||||
assert.NoError(t, f.SetCellValue("Sheet1", k, v))
|
||||
}
|
||||
assert.NoError(t, f.AddChartSheet("Chart1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`))
|
||||
|
||||
assert.EqualError(t, f.AddChartSheet("Sheet1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`), "already existing name worksheet")
|
||||
// Test with unsupported chart type
|
||||
assert.EqualError(t, f.AddChartSheet("Chart2", `{"type":"unknown","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`), "unsupported chart type unknown")
|
||||
|
||||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddChartSheet.xlsx")))
|
||||
}
|
||||
|
||||
func TestDeleteChart(t *testing.T) {
|
||||
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
|
||||
assert.NoError(t, err)
|
||||
|
|
63
drawing.go
63
drawing.go
|
@ -38,6 +38,26 @@ func (f *File) prepareDrawing(xlsx *xlsxWorksheet, drawingID int, sheet, drawing
|
|||
return drawingID, drawingXML
|
||||
}
|
||||
|
||||
// prepareChartSheetDrawing provides a function to prepare drawing ID and XML
|
||||
// by given drawingID, worksheet name and default drawingXML.
|
||||
func (f *File) prepareChartSheetDrawing(xlsx *xlsxChartsheet, 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.
|
||||
sheetRels := "xl/chartsheets/_rels/" + strings.TrimPrefix(f.sheetMap[trimSheetName(sheet)], "xl/chartsheets/") + ".rels"
|
||||
rID := f.addRels(sheetRels, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
|
||||
xlsx.Drawing = &xlsxDrawing{
|
||||
RID: "rId" + strconv.Itoa(rID),
|
||||
}
|
||||
}
|
||||
return drawingID, drawingXML
|
||||
}
|
||||
|
||||
// addChart provides a function to create chart as xl/charts/chart%d.xml by
|
||||
// given format sets.
|
||||
func (f *File) addChart(formatSet *formatChart, comboCharts []*formatChart) {
|
||||
|
@ -1209,6 +1229,49 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
|
|||
return err
|
||||
}
|
||||
|
||||
// addSheetDrawingChart provides a function to add chart graphic frame for
|
||||
// chartsheet by given sheet, drawingXML, width, height, relationship index
|
||||
// and format sets.
|
||||
func (f *File) addSheetDrawingChart(sheet, drawingXML string, width, height, rID int, formatSet *formatPicture) (err error) {
|
||||
width = int(float64(width) * formatSet.XScale)
|
||||
height = int(float64(height) * formatSet.YScale)
|
||||
|
||||
content, cNvPrID := f.drawingParser(drawingXML)
|
||||
absoluteAnchor := xdrCellAnchor{
|
||||
EditAs: formatSet.Positioning,
|
||||
Pos: &xlsxPoint2D{},
|
||||
Ext: &xlsxExt{},
|
||||
}
|
||||
|
||||
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)
|
||||
absoluteAnchor.GraphicFrame = string(graphic)
|
||||
absoluteAnchor.ClientData = &xdrClientData{
|
||||
FLocksWithSheet: formatSet.FLocksWithSheet,
|
||||
FPrintsWithSheet: formatSet.FPrintsWithSheet,
|
||||
}
|
||||
content.AbsoluteAnchor = append(content.AbsoluteAnchor, &absoluteAnchor)
|
||||
f.Drawings[drawingXML] = content
|
||||
return err
|
||||
}
|
||||
|
||||
// deleteDrawing provides a function to delete chart graphic frame by given by
|
||||
// given coordinates and graphic type.
|
||||
func (f *File) deleteDrawing(col, row int, drawingXML, drawingType string) (err error) {
|
||||
|
|
23
excelize.go
23
excelize.go
|
@ -228,21 +228,10 @@ func (f *File) addRels(relPath, relType, target, targetMode string) int {
|
|||
}
|
||||
|
||||
// replaceWorkSheetsRelationshipsNameSpaceBytes provides a function to replace
|
||||
// xl/worksheets/sheet%d.xml XML tags to self-closing for compatible Microsoft
|
||||
// Office Excel 2007.
|
||||
func replaceWorkSheetsRelationshipsNameSpaceBytes(workbookMarshal []byte) []byte {
|
||||
var oldXmlns = []byte(`<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
|
||||
var newXmlns = []byte(`<worksheet` + templateNamespaceIDMap)
|
||||
workbookMarshal = bytes.Replace(workbookMarshal, oldXmlns, newXmlns, -1)
|
||||
return workbookMarshal
|
||||
}
|
||||
|
||||
// replaceStyleRelationshipsNameSpaceBytes provides a function to replace
|
||||
// xl/styles.xml XML tags to self-closing for compatible Microsoft Office
|
||||
// Excel 2007.
|
||||
func replaceStyleRelationshipsNameSpaceBytes(contentMarshal []byte) []byte {
|
||||
var oldXmlns = []byte(`<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
|
||||
var newXmlns = []byte(`<styleSheet` + templateNamespaceIDMap)
|
||||
// XML tags to self-closing for compatible Microsoft Office Excel 2007.
|
||||
func replaceWorkSheetsRelationshipsNameSpaceBytes(contentMarshal []byte) []byte {
|
||||
var oldXmlns = []byte(` xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
|
||||
var newXmlns = []byte(templateNamespaceIDMap)
|
||||
contentMarshal = bytes.Replace(contentMarshal, oldXmlns, newXmlns, -1)
|
||||
return contentMarshal
|
||||
}
|
||||
|
@ -354,13 +343,13 @@ func (f *File) setContentTypePartVBAProjectExtensions() {
|
|||
}
|
||||
for idx, o := range content.Overrides {
|
||||
if o.PartName == "/xl/workbook.xml" {
|
||||
content.Overrides[idx].ContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml"
|
||||
content.Overrides[idx].ContentType = ContentTypeMacro
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
content.Defaults = append(content.Defaults, xlsxDefault{
|
||||
Extension: "bin",
|
||||
ContentType: "application/vnd.ms-office.vbaProject",
|
||||
ContentType: ContentTypeVBA,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
16
picture.go
16
picture.go
|
@ -354,7 +354,7 @@ func (f *File) setContentTypePartVMLExtensions() {
|
|||
if !vml {
|
||||
content.Defaults = append(content.Defaults, xlsxDefault{
|
||||
Extension: "vml",
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.vmlDrawing",
|
||||
ContentType: ContentTypeVML,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -368,6 +368,7 @@ func (f *File) addContentTypePart(index int, contentType string) {
|
|||
}
|
||||
partNames := map[string]string{
|
||||
"chart": "/xl/charts/chart" + strconv.Itoa(index) + ".xml",
|
||||
"chartsheet": "/xl/chartsheets/sheet" + 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",
|
||||
|
@ -375,12 +376,13 @@ func (f *File) addContentTypePart(index int, contentType string) {
|
|||
"pivotCache": "/xl/pivotCache/pivotCacheDefinition" + 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",
|
||||
"pivotTable": "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
|
||||
"pivotCache": "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml",
|
||||
"chart": ContentTypeDrawingML,
|
||||
"chartsheet": ContentTypeSpreadSheetMLChartsheet,
|
||||
"comments": ContentTypeSpreadSheetMLComments,
|
||||
"drawings": ContentTypeDrawing,
|
||||
"table": ContentTypeSpreadSheetMLTable,
|
||||
"pivotTable": ContentTypeSpreadSheetMLPivotTable,
|
||||
"pivotCache": ContentTypeSpreadSheetMLPivotCacheDefinition,
|
||||
}
|
||||
s, ok := setContentType[contentType]
|
||||
if ok {
|
||||
|
|
16
sheet.go
16
sheet.go
|
@ -50,7 +50,7 @@ func (f *File) NewSheet(name string) int {
|
|||
// Update docProps/app.xml
|
||||
f.setAppXML()
|
||||
// Update [Content_Types].xml
|
||||
f.setContentTypes(sheetID)
|
||||
f.setContentTypes("/xl/worksheets/sheet"+strconv.Itoa(sheetID)+".xml", ContentTypeSpreadSheetMLWorksheet)
|
||||
// Create new sheet /xl/worksheets/sheet%d.xml
|
||||
f.setSheet(sheetID, name)
|
||||
// Update xl/_rels/workbook.xml.rels
|
||||
|
@ -151,11 +151,11 @@ func trimCell(column []xlsxC) []xlsxC {
|
|||
|
||||
// setContentTypes provides a function to read and update property of contents
|
||||
// type of XLSX.
|
||||
func (f *File) setContentTypes(index int) {
|
||||
func (f *File) setContentTypes(partName, contentType string) {
|
||||
content := f.contentTypesReader()
|
||||
content.Overrides = append(content.Overrides, xlsxOverride{
|
||||
PartName: "/xl/worksheets/sheet" + strconv.Itoa(index) + ".xml",
|
||||
ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
|
||||
PartName: partName,
|
||||
ContentType: contentType,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -336,8 +336,8 @@ func (f *File) GetSheetIndex(name string) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
// GetSheetMap provides a function to get worksheet name and index map of XLSX.
|
||||
// For example:
|
||||
// GetSheetMap provides a function to get worksheet and chartsheet name and
|
||||
// index map of XLSX. For example:
|
||||
//
|
||||
// f, err := excelize.OpenFile("Book1.xlsx")
|
||||
// if err != nil {
|
||||
|
@ -358,8 +358,8 @@ func (f *File) GetSheetMap() map[int]string {
|
|||
return sheetMap
|
||||
}
|
||||
|
||||
// getSheetMap provides a function to get worksheet name and XML file path map
|
||||
// of XLSX.
|
||||
// getSheetMap provides a function to get worksheet and chartsheet name and
|
||||
// XML file path map of XLSX.
|
||||
func (f *File) getSheetMap() map[string]string {
|
||||
content := f.workbookReader()
|
||||
rels := f.relsReader("xl/_rels/workbook.xml.rels")
|
||||
|
|
|
@ -1018,7 +1018,7 @@ func (f *File) stylesReader() *xlsxStyleSheet {
|
|||
func (f *File) styleSheetWriter() {
|
||||
if f.Styles != nil {
|
||||
output, _ := xml.Marshal(f.Styles)
|
||||
f.saveFileList("xl/styles.xml", replaceStyleRelationshipsNameSpaceBytes(output))
|
||||
f.saveFileList("xl/styles.xml", replaceWorkSheetsRelationshipsNameSpaceBytes(output))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ type xlsxChartsheet struct {
|
|||
PageMargins *xlsxPageMargins `xml:"pageMargins"`
|
||||
PageSetup []*xlsxPageSetUp `xml:"pageSetup"`
|
||||
HeaderFooter *xlsxHeaderFooter `xml:"headerFooter"`
|
||||
Drawing []*xlsxDrawing `xml:"drawing"`
|
||||
Drawing *xlsxDrawing `xml:"drawing"`
|
||||
DrawingHF []*xlsxDrawingHF `xml:"drawingHF"`
|
||||
Picture []*xlsxPicture `xml:"picture"`
|
||||
WebPublishItems []*xlsxInnerXML `xml:"webPublishItems"`
|
||||
|
|
101
xmlDrawing.go
101
xmlDrawing.go
|
@ -13,40 +13,52 @@ import "encoding/xml"
|
|||
|
||||
// Source relationship and namespace.
|
||||
const (
|
||||
SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
|
||||
SourceRelationshipComments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
|
||||
SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
|
||||
SourceRelationshipTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
|
||||
SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
|
||||
SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"
|
||||
SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
|
||||
SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
|
||||
SourceRelationshipPivotTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"
|
||||
SourceRelationshipPivotCache = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition"
|
||||
SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
|
||||
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"
|
||||
NameSpaceDrawingMLSpreadSheet = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
NameSpaceSpreadSheet = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
NameSpaceSpreadSheetX14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
|
||||
NameSpaceSpreadSheetX15 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"
|
||||
NameSpaceSpreadSheetExcel2006Main = "http://schemas.microsoft.com/office/excel/2006/main"
|
||||
NameSpaceMacExcel2008Main = "http://schemas.microsoft.com/office/mac/excel/2008/main"
|
||||
NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
|
||||
NameSpaceXMLSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
StrictSourceRelationship = "http://purl.oclc.org/ooxml/officeDocument/relationships"
|
||||
StrictSourceRelationshipChart = "http://purl.oclc.org/ooxml/officeDocument/relationships/chart"
|
||||
StrictSourceRelationshipComments = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments"
|
||||
StrictSourceRelationshipImage = "http://purl.oclc.org/ooxml/officeDocument/relationships/image"
|
||||
StrictNameSpaceSpreadSheet = "http://purl.oclc.org/ooxml/spreadsheetml/main"
|
||||
NameSpaceDublinCore = "http://purl.org/dc/elements/1.1/"
|
||||
NameSpaceDublinCoreTerms = "http://purl.org/dc/terms/"
|
||||
NameSpaceDublinCoreMetadataIntiative = "http://purl.org/dc/dcmitype/"
|
||||
SourceRelationship = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
||||
SourceRelationshipChart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"
|
||||
SourceRelationshipComments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"
|
||||
SourceRelationshipImage = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
|
||||
SourceRelationshipTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/table"
|
||||
SourceRelationshipDrawingML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"
|
||||
SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"
|
||||
SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
|
||||
SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
|
||||
SourceRelationshipChartsheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet"
|
||||
SourceRelationshipPivotTable = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"
|
||||
SourceRelationshipPivotCache = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition"
|
||||
SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
|
||||
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"
|
||||
NameSpaceDrawingMLSpreadSheet = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"
|
||||
NameSpaceSpreadSheet = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
||||
NameSpaceSpreadSheetX14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
|
||||
NameSpaceSpreadSheetX15 = "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"
|
||||
NameSpaceSpreadSheetExcel2006Main = "http://schemas.microsoft.com/office/excel/2006/main"
|
||||
NameSpaceMacExcel2008Main = "http://schemas.microsoft.com/office/mac/excel/2008/main"
|
||||
NameSpaceXML = "http://www.w3.org/XML/1998/namespace"
|
||||
NameSpaceXMLSchemaInstance = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
StrictSourceRelationship = "http://purl.oclc.org/ooxml/officeDocument/relationships"
|
||||
StrictSourceRelationshipChart = "http://purl.oclc.org/ooxml/officeDocument/relationships/chart"
|
||||
StrictSourceRelationshipComments = "http://purl.oclc.org/ooxml/officeDocument/relationships/comments"
|
||||
StrictSourceRelationshipImage = "http://purl.oclc.org/ooxml/officeDocument/relationships/image"
|
||||
StrictNameSpaceSpreadSheet = "http://purl.oclc.org/ooxml/spreadsheetml/main"
|
||||
NameSpaceDublinCore = "http://purl.org/dc/elements/1.1/"
|
||||
NameSpaceDublinCoreTerms = "http://purl.org/dc/terms/"
|
||||
NameSpaceDublinCoreMetadataIntiative = "http://purl.org/dc/dcmitype/"
|
||||
ContentTypeDrawing = "application/vnd.openxmlformats-officedocument.drawing+xml"
|
||||
ContentTypeDrawingML = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"
|
||||
ContentTypeMacro = "application/vnd.ms-excel.sheet.macroEnabled.main+xml"
|
||||
ContentTypeSpreadSheetMLChartsheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml"
|
||||
ContentTypeSpreadSheetMLComments = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"
|
||||
ContentTypeSpreadSheetMLPivotCacheDefinition = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml"
|
||||
ContentTypeSpreadSheetMLPivotTable = "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"
|
||||
ContentTypeSpreadSheetMLTable = "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"
|
||||
ContentTypeSpreadSheetMLWorksheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"
|
||||
ContentTypeVBA = "application/vnd.ms-office.vbaProject"
|
||||
ContentTypeVML = "application/vnd.openxmlformats-officedocument.vmlDrawing"
|
||||
// ExtURIConditionalFormattings is the extLst child element
|
||||
// ([ISO/IEC29500-1:2016] section 18.2.10) of the worksheet element
|
||||
// ([ISO/IEC29500-1:2016] section 18.3.1.99) is extended by the addition of
|
||||
|
@ -240,6 +252,7 @@ type xdrClientData struct {
|
|||
// with cells and its extents are in EMU units.
|
||||
type xdrCellAnchor struct {
|
||||
EditAs string `xml:"editAs,attr,omitempty"`
|
||||
Pos *xlsxPoint2D `xml:"xdr:pos"`
|
||||
From *xlsxFrom `xml:"xdr:from"`
|
||||
To *xlsxTo `xml:"xdr:to"`
|
||||
Ext *xlsxExt `xml:"xdr:ext"`
|
||||
|
@ -249,15 +262,23 @@ type xdrCellAnchor struct {
|
|||
ClientData *xdrClientData `xml:"xdr:clientData"`
|
||||
}
|
||||
|
||||
// xlsxPoint2D describes the position of a drawing element within a spreadsheet.
|
||||
type xlsxPoint2D struct {
|
||||
XMLName xml.Name `xml:"xdr:pos"`
|
||||
X int `xml:"x,attr"`
|
||||
Y int `xml:"y,attr"`
|
||||
}
|
||||
|
||||
// xlsxWsDr directly maps the root element for a part of this content type shall
|
||||
// wsDr.
|
||||
type xlsxWsDr struct {
|
||||
XMLName xml.Name `xml:"xdr:wsDr"`
|
||||
OneCellAnchor []*xdrCellAnchor `xml:"xdr:oneCellAnchor"`
|
||||
TwoCellAnchor []*xdrCellAnchor `xml:"xdr:twoCellAnchor"`
|
||||
A string `xml:"xmlns:a,attr,omitempty"`
|
||||
Xdr string `xml:"xmlns:xdr,attr,omitempty"`
|
||||
R string `xml:"xmlns:r,attr,omitempty"`
|
||||
XMLName xml.Name `xml:"xdr:wsDr"`
|
||||
AbsoluteAnchor []*xdrCellAnchor `xml:"xdr:absoluteAnchor"`
|
||||
OneCellAnchor []*xdrCellAnchor `xml:"xdr:oneCellAnchor"`
|
||||
TwoCellAnchor []*xdrCellAnchor `xml:"xdr:twoCellAnchor"`
|
||||
A string `xml:"xmlns:a,attr,omitempty"`
|
||||
Xdr string `xml:"xmlns:xdr,attr,omitempty"`
|
||||
R string `xml:"xmlns:r,attr,omitempty"`
|
||||
}
|
||||
|
||||
// xlsxGraphicFrame (Graphic Frame) directly maps the xdr:graphicFrame element.
|
||||
|
|
|
@ -12,8 +12,7 @@ package excelize
|
|||
import "encoding/xml"
|
||||
|
||||
// xlsxWorksheet directly maps the worksheet element in the namespace
|
||||
// http://schemas.openxmlformats.org/spreadsheetml/2006/main - currently I have
|
||||
// not checked it for completeness - it does as much as I need.
|
||||
// http://schemas.openxmlformats.org/spreadsheetml/2006/main.
|
||||
type xlsxWorksheet struct {
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"`
|
||||
SheetPr *xlsxSheetPr `xml:"sheetPr"`
|
||||
|
|
Loading…
Reference in New Issue