summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2020-07-18 15:15:16 +0800
committerxuri <xuri.me@gmail.com>2020-07-18 15:15:16 +0800
commitc922c32fb7571d3d40d3244e5635142bc390a3db (patch)
tree12c2a1541458963caca5f7714d7861c42637d4c6
parent820a314cfbcaa4d32401b0b6c67bf65f064483ec (diff)
support parse and generate XML element namespace dynamic, fix #651
-rw-r--r--cell.go1
-rw-r--r--chart.go4
-rw-r--r--col.go2
-rw-r--r--comment.go1
-rw-r--r--drawing.go7
-rw-r--r--excelize.go14
-rw-r--r--lib.go101
-rw-r--r--picture.go5
-rw-r--r--rows.go15
-rw-r--r--shape.go1
-rw-r--r--sheet.go21
-rw-r--r--sparkline.go2
-rw-r--r--stream.go2
-rw-r--r--styles.go4
-rw-r--r--table.go26
-rw-r--r--xmlDrawing.go10
16 files changed, 171 insertions, 45 deletions
diff --git a/cell.go b/cell.go
index 0163c3b..3293d19 100644
--- a/cell.go
+++ b/cell.go
@@ -490,6 +490,7 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string) error {
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipHyperLink, link, linkType)
linkData.RID = "rId" + strconv.Itoa(rID)
+ f.addSheetNameSpace(sheet, SourceRelationship)
case "Location":
linkData = xlsxHyperlink{
Ref: axis,
diff --git a/chart.go b/chart.go
index b584c18..ae31f71 100644
--- a/chart.go
+++ b/chart.go
@@ -755,6 +755,7 @@ func (f *File) AddChart(sheet, cell, format string, combo ...string) error {
f.addChart(formatSet, comboCharts)
f.addContentTypePart(chartID, "chart")
f.addContentTypePart(drawingID, "drawings")
+ f.addSheetNameSpace(sheet, SourceRelationship)
return err
}
@@ -804,7 +805,8 @@ func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
// Update xl/workbook.xml
f.setWorkbook(sheet, sheetID, rID)
chartsheet, _ := xml.Marshal(cs)
- f.saveFileList(path, replaceRelationshipsBytes(replaceRelationshipsNameSpaceBytes(chartsheet)))
+ f.addSheetNameSpace(sheet, NameSpaceSpreadSheet)
+ f.saveFileList(path, replaceRelationshipsBytes(f.replaceNameSpaceBytes(path, chartsheet)))
return err
}
diff --git a/col.go b/col.go
index 472106f..5a8299e 100644
--- a/col.go
+++ b/col.go
@@ -159,7 +159,7 @@ func (f *File) Cols(sheet string) (*Cols, error) {
}
if f.Sheet[name] != nil {
output, _ := xml.Marshal(f.Sheet[name])
- f.saveFileList(name, replaceRelationshipsNameSpaceBytes(output))
+ f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
}
var (
inElement string
diff --git a/comment.go b/comment.go
index 28140bf..8414b40 100644
--- a/comment.go
+++ b/comment.go
@@ -109,6 +109,7 @@ func (f *File) AddComment(sheet, cell, format string) error {
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(f.sheetMap[trimSheetName(sheet)], "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipDrawingVML, sheetRelationshipsDrawingVML, "")
f.addRels(sheetRels, SourceRelationshipComments, sheetRelationshipsComments, "")
+ f.addSheetNameSpace(sheet, SourceRelationship)
f.addSheetLegacyDrawing(sheet, rID)
}
commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml"
diff --git a/drawing.go b/drawing.go
index 5e5bba9..ced747d 100644
--- a/drawing.go
+++ b/drawing.go
@@ -47,6 +47,7 @@ func (f *File) prepareChartSheetDrawing(xlsx *xlsxChartsheet, drawingID int, she
// Only allow one chart in a chartsheet.
sheetRels := "xl/chartsheets/_rels/" + strings.TrimPrefix(f.sheetMap[trimSheetName(sheet)], "xl/chartsheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
+ f.addSheetNameSpace(sheet, SourceRelationship)
xlsx.Drawing = &xlsxDrawing{
RID: "rId" + strconv.Itoa(rID),
}
@@ -60,7 +61,7 @@ func (f *File) addChart(formatSet *formatChart, comboCharts []*formatChart) {
xlsxChartSpace := xlsxChartSpace{
XMLNSc: NameSpaceDrawingMLChart,
XMLNSa: NameSpaceDrawingML,
- XMLNSr: SourceRelationship,
+ XMLNSr: SourceRelationship.Value,
XMLNSc16r2: SourceRelationshipChart201506,
Date1904: &attrValBool{Val: boolPtr(false)},
Lang: &attrValString{Val: stringPtr("en-US")},
@@ -1212,7 +1213,7 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
URI: NameSpaceDrawingMLChart,
Chart: &xlsxChart{
C: NameSpaceDrawingMLChart,
- R: SourceRelationship,
+ R: SourceRelationship.Value,
RID: "rId" + strconv.Itoa(rID),
},
},
@@ -1252,7 +1253,7 @@ func (f *File) addSheetDrawingChart(drawingXML string, rID int, formatSet *forma
URI: NameSpaceDrawingMLChart,
Chart: &xlsxChart{
C: NameSpaceDrawingMLChart,
- R: SourceRelationship,
+ R: SourceRelationship.Value,
RID: "rId" + strconv.Itoa(rID),
},
},
diff --git a/excelize.go b/excelize.go
index bac569a..5cc88e9 100644
--- a/excelize.go
+++ b/excelize.go
@@ -30,6 +30,7 @@ import (
// File define a populated spreadsheet file struct.
type File struct {
+ xmlAttr map[string][]xml.Attr
checked map[string]bool
sheetMap map[string]string
CalcChain *xlsxCalcChain
@@ -72,6 +73,7 @@ func OpenFile(filename string) (*File, error) {
// newFile is object builder
func newFile() *File {
return &File{
+ xmlAttr: make(map[string][]xml.Attr),
checked: make(map[string]bool),
sheetMap: make(map[string]string),
Comments: make(map[string]*xlsxComments),
@@ -166,6 +168,10 @@ func (f *File) workSheetReader(sheet string) (xlsx *xlsxWorksheet, err error) {
return
}
xlsx = new(xlsxWorksheet)
+ if _, ok := f.xmlAttr[name]; !ok {
+ d := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(name))))
+ f.xmlAttr[name] = append(f.xmlAttr[name], getRootElement(d)...)
+ }
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(name)))).
Decode(xlsx); err != nil && err != io.EOF {
err = fmt.Errorf("xml decode error: %s", err)
@@ -254,14 +260,6 @@ func (f *File) addRels(relPath, relType, target, targetMode string) int {
return rID
}
-// replaceRelationshipsNameSpaceBytes provides a function to replace
-// XML tags to self-closing for compatible Microsoft Office Excel 2007.
-func replaceRelationshipsNameSpaceBytes(contentMarshal []byte) []byte {
- var oldXmlns = stringToBytes(` xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
- var newXmlns = []byte(templateNamespaceIDMap)
- return bytesReplace(contentMarshal, oldXmlns, newXmlns, -1)
-}
-
// UpdateLinkedValue fix linked values within a spreadsheet are not updating in
// Office Excel 2007 and 2010. This function will be remove value tag when met a
// cell have a linked value. Reference
diff --git a/lib.go b/lib.go
index 5d18064..6dcd97e 100644
--- a/lib.go
+++ b/lib.go
@@ -15,6 +15,7 @@ import (
"archive/zip"
"bytes"
"container/list"
+ "encoding/xml"
"fmt"
"io"
"strconv"
@@ -243,11 +244,11 @@ func parseFormatSet(formatSet string) []byte {
// Transitional namespaces.
func namespaceStrictToTransitional(content []byte) []byte {
var namespaceTranslationDic = map[string]string{
- StrictSourceRelationship: SourceRelationship,
+ StrictSourceRelationship: SourceRelationship.Value,
StrictSourceRelationshipChart: SourceRelationshipChart,
StrictSourceRelationshipComments: SourceRelationshipComments,
StrictSourceRelationshipImage: SourceRelationshipImage,
- StrictNameSpaceSpreadSheet: NameSpaceSpreadSheet,
+ StrictNameSpaceSpreadSheet: NameSpaceSpreadSheet.Value,
}
for s, n := range namespaceTranslationDic {
content = bytesReplace(content, stringToBytes(s), stringToBytes(n), -1)
@@ -319,6 +320,102 @@ func genSheetPasswd(plaintext string) string {
return strings.ToUpper(strconv.FormatInt(password, 16))
}
+// getRootElement extract root element attributes by given XML decoder.
+func getRootElement(d *xml.Decoder) []xml.Attr {
+ tokenIdx := 0
+ for {
+ token, _ := d.Token()
+ if token == nil {
+ break
+ }
+ switch startElement := token.(type) {
+ case xml.StartElement:
+ tokenIdx++
+ if tokenIdx == 1 {
+ return startElement.Attr
+ }
+ }
+ }
+ return nil
+}
+
+// genXMLNamespace generate serialized XML attributes with a multi namespace
+// by given element attributes.
+func genXMLNamespace(attr []xml.Attr) string {
+ var rootElement string
+ for _, v := range attr {
+ if lastSpace := getXMLNamespace(v.Name.Space, attr); lastSpace != "" {
+ rootElement += fmt.Sprintf("%s:%s=\"%s\" ", lastSpace, v.Name.Local, v.Value)
+ continue
+ }
+ rootElement += fmt.Sprintf("%s=\"%s\" ", v.Name.Local, v.Value)
+ }
+ return strings.TrimSpace(rootElement) + ">"
+}
+
+// getXMLNamespace extract XML namespace from specified element name and attributes.
+func getXMLNamespace(space string, attr []xml.Attr) string {
+ for _, attribute := range attr {
+ if attribute.Value == space {
+ return attribute.Name.Local
+ }
+ }
+ return space
+}
+
+// replaceNameSpaceBytes provides a function to replace the XML root element
+// attribute by the given component part path and XML content.
+func (f *File) replaceNameSpaceBytes(path string, contentMarshal []byte) []byte {
+ var oldXmlns = stringToBytes(`xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
+ var newXmlns = []byte(templateNamespaceIDMap)
+ if attr, ok := f.xmlAttr[path]; ok {
+ newXmlns = []byte(genXMLNamespace(attr))
+ }
+ return bytesReplace(contentMarshal, oldXmlns, newXmlns, -1)
+}
+
+// addNameSpaces provides a function to add a XML attribute by the given
+// component part path.
+func (f *File) addNameSpaces(path string, ns xml.Attr) {
+ exist := false
+ mc := false
+ ignore := false
+ if attr, ok := f.xmlAttr[path]; ok {
+ for _, attribute := range attr {
+ if attribute.Name.Local == ns.Name.Local && attribute.Name.Space == ns.Name.Space {
+ exist = true
+ }
+ if attribute.Name.Local == "Ignorable" && attribute.Name.Space == "mc" {
+ ignore = true
+ }
+ if attribute.Name.Local == "mc" && attribute.Name.Space == "xmlns" {
+ mc = true
+ }
+ }
+ }
+ if !exist {
+ f.xmlAttr[path] = append(f.xmlAttr[path], ns)
+ if !mc {
+ f.xmlAttr[path] = append(f.xmlAttr[path], xml.Attr{
+ Name: xml.Name{Local: "mc", Space: "xmlns"},
+ Value: SourceRelationshipCompatibility,
+ })
+ }
+ if !ignore {
+ f.xmlAttr[path] = append(f.xmlAttr[path], xml.Attr{
+ Name: xml.Name{Local: "Ignorable", Space: "mc"},
+ Value: ns.Name.Local,
+ })
+ }
+ }
+}
+
+// addSheetNameSpace add XML attribute for worksheet.
+func (f *File) addSheetNameSpace(sheet string, ns xml.Attr) {
+ name, _ := f.sheetMap[trimSheetName(sheet)]
+ f.addNameSpaces(name, ns)
+}
+
// Stack defined an abstract data type that serves as a collection of elements.
type Stack struct {
list *list.List
diff --git a/picture.go b/picture.go
index c7f6e27..468cccd 100644
--- a/picture.go
+++ b/picture.go
@@ -168,6 +168,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
return err
}
f.addContentTypePart(drawingID, "drawings")
+ f.addSheetNameSpace(sheet, SourceRelationship)
return err
}
@@ -279,11 +280,11 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
if hyperlinkRID != 0 {
pic.NvPicPr.CNvPr.HlinkClick = &xlsxHlinkClick{
- R: SourceRelationship,
+ R: SourceRelationship.Value,
RID: "rId" + strconv.Itoa(hyperlinkRID),
}
}
- pic.BlipFill.Blip.R = SourceRelationship
+ pic.BlipFill.Blip.R = SourceRelationship.Value
pic.BlipFill.Blip.Embed = "rId" + strconv.Itoa(rID)
pic.SpPr.PrstGeom.Prst = "rect"
diff --git a/rows.go b/rows.go
index 535b010..320ba2f 100644
--- a/rows.go
+++ b/rows.go
@@ -121,11 +121,8 @@ func (rows *Rows) Columns() ([]string, error) {
}
}
blank := cellCol - len(columns)
- for i := 1; i < blank; i++ {
- columns = append(columns, "")
- }
val, _ := colCell.getValueFrom(rows.f, d)
- columns = append(columns, val)
+ columns = append(appendSpace(blank, columns), val)
}
case xml.EndElement:
inElement = startElement.Name.Local
@@ -137,6 +134,14 @@ func (rows *Rows) Columns() ([]string, error) {
return columns, err
}
+// appendSpace append blank characters to slice by given length and source slice.
+func appendSpace(l int, s []string) []string {
+ for i := 1; i < l; i++ {
+ s = append(s, "")
+ }
+ return s
+}
+
// ErrSheetNotExist defines an error of sheet is not exist
type ErrSheetNotExist struct {
SheetName string
@@ -173,7 +178,7 @@ func (f *File) Rows(sheet string) (*Rows, error) {
if f.Sheet[name] != nil {
// flush data
output, _ := xml.Marshal(f.Sheet[name])
- f.saveFileList(name, replaceRelationshipsNameSpaceBytes(output))
+ f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
}
var (
err error
diff --git a/shape.go b/shape.go
index 3160616..0a5164b 100644
--- a/shape.go
+++ b/shape.go
@@ -280,6 +280,7 @@ func (f *File) AddShape(sheet, cell, format string) error {
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(f.sheetMap[trimSheetName(sheet)], "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
f.addSheetDrawing(sheet, rID)
+ f.addSheetNameSpace(sheet, SourceRelationship)
}
err = f.addDrawingShape(sheet, drawingXML, cell, formatSet)
if err != nil {
diff --git a/sheet.go b/sheet.go
index 20bf7c7..31a36eb 100644
--- a/sheet.go
+++ b/sheet.go
@@ -92,15 +92,18 @@ func (f *File) contentTypesWriter() {
// structure after deserialization.
func (f *File) workbookReader() *xlsxWorkbook {
var err error
-
if f.WorkBook == nil {
f.WorkBook = new(xlsxWorkbook)
+ if _, ok := f.xmlAttr["xl/workbook.xml"]; !ok {
+ d := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML("xl/workbook.xml"))))
+ f.xmlAttr["xl/workbook.xml"] = append(f.xmlAttr["xl/workbook.xml"], getRootElement(d)...)
+ f.addNameSpaces("xl/workbook.xml", SourceRelationship)
+ }
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML("xl/workbook.xml")))).
Decode(f.WorkBook); err != nil && err != io.EOF {
log.Printf("xml decode error: %s", err)
}
}
-
return f.WorkBook
}
@@ -109,7 +112,7 @@ func (f *File) workbookReader() *xlsxWorkbook {
func (f *File) workBookWriter() {
if f.WorkBook != nil {
output, _ := xml.Marshal(f.WorkBook)
- f.saveFileList("xl/workbook.xml", replaceRelationshipsBytes(replaceRelationshipsNameSpaceBytes(output)))
+ f.saveFileList("xl/workbook.xml", replaceRelationshipsBytes(f.replaceNameSpaceBytes("xl/workbook.xml", output)))
}
}
@@ -122,7 +125,7 @@ func (f *File) workSheetWriter() {
f.Sheet[p].SheetData.Row[k].C = trimCell(v.C)
}
output, _ := xml.Marshal(sheet)
- f.saveFileList(p, replaceRelationshipsBytes(replaceRelationshipsNameSpaceBytes(output)))
+ f.saveFileList(p, replaceRelationshipsBytes(f.replaceNameSpaceBytes(p, output)))
ok := f.checked[p]
if ok {
delete(f.Sheet, p)
@@ -173,6 +176,7 @@ func (f *File) setSheet(index int, name string) {
path := "xl/worksheets/sheet" + strconv.Itoa(index) + ".xml"
f.sheetMap[trimSheetName(name)] = path
f.Sheet[path] = &xlsx
+ f.xmlAttr[path] = append(f.xmlAttr[path], NameSpaceSpreadSheet)
}
// setWorkbook update workbook property of the spreadsheet. Maximum 31
@@ -193,7 +197,7 @@ func (f *File) relsWriter() {
if rel != nil {
output, _ := xml.Marshal(rel)
if strings.HasPrefix(path, "xl/worksheets/sheet/rels/sheet") {
- output = replaceRelationshipsNameSpaceBytes(output)
+ output = f.replaceNameSpaceBytes(path, output)
}
f.saveFileList(path, replaceRelationshipsBytes(output))
}
@@ -440,6 +444,7 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(f.sheetMap[trimSheetName(sheet)], "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipImage, strings.Replace(name, "xl", "..", 1), "")
f.addSheetPicture(sheet, rID)
+ f.addSheetNameSpace(sheet, SourceRelationship)
f.setContentTypePartImageExtensions()
return err
}
@@ -479,6 +484,7 @@ func (f *File) DeleteSheet(name string) {
delete(f.XLSX, rels)
delete(f.Relationships, rels)
delete(f.Sheet, sheetXML)
+ delete(f.xmlAttr, sheetXML)
f.SheetCount--
}
}
@@ -557,6 +563,9 @@ func (f *File) copySheet(from, to int) error {
if ok {
f.XLSX[toRels] = f.XLSX[fromRels]
}
+ fromSheetXMLPath, _ := f.sheetMap[trimSheetName(fromSheet)]
+ fromSheetAttr, _ := f.xmlAttr[fromSheetXMLPath]
+ f.xmlAttr[path] = fromSheetAttr
return err
}
@@ -779,7 +788,7 @@ func (f *File) SearchSheet(sheet, value string, reg ...bool) ([]string, error) {
if f.Sheet[name] != nil {
// flush data
output, _ := xml.Marshal(f.Sheet[name])
- f.saveFileList(name, replaceRelationshipsNameSpaceBytes(output))
+ f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
}
return f.searchSheet(name, value, regSearch)
}
diff --git a/sparkline.go b/sparkline.go
index 9682db0..4004878 100644
--- a/sparkline.go
+++ b/sparkline.go
@@ -455,7 +455,7 @@ func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
}
ws.ExtLst.Ext = string(extBytes)
}
-
+ f.addSheetNameSpace(sheet, NameSpaceSpreadSheetX14)
return
}
diff --git a/stream.go b/stream.go
index bdc0d26..ec1e65b 100644
--- a/stream.go
+++ b/stream.go
@@ -151,7 +151,7 @@ func (sw *StreamWriter) AddTable(hcell, vcell, format string) error {
}
table := xlsxTable{
- XMLNS: NameSpaceSpreadSheet,
+ XMLNS: NameSpaceSpreadSheet.Value,
ID: tableID,
Name: name,
DisplayName: name,
diff --git a/styles.go b/styles.go
index 2ae1cd8..d7b1460 100644
--- a/styles.go
+++ b/styles.go
@@ -1022,7 +1022,7 @@ func (f *File) stylesReader() *xlsxStyleSheet {
func (f *File) styleSheetWriter() {
if f.Styles != nil {
output, _ := xml.Marshal(f.Styles)
- f.saveFileList("xl/styles.xml", replaceRelationshipsNameSpaceBytes(output))
+ f.saveFileList("xl/styles.xml", f.replaceNameSpaceBytes("xl/styles.xml", output))
}
}
@@ -1031,7 +1031,7 @@ func (f *File) styleSheetWriter() {
func (f *File) sharedStringsWriter() {
if f.SharedStrings != nil {
output, _ := xml.Marshal(f.SharedStrings)
- f.saveFileList("xl/sharedStrings.xml", replaceRelationshipsNameSpaceBytes(output))
+ f.saveFileList("xl/sharedStrings.xml", f.replaceNameSpaceBytes("xl/sharedStrings.xml", output))
}
}
diff --git a/table.go b/table.go
index d59322c..e26bbe2 100644
--- a/table.go
+++ b/table.go
@@ -83,9 +83,11 @@ func (f *File) AddTable(sheet, hcell, vcell, format string) error {
// Add first table for given sheet.
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(f.sheetMap[trimSheetName(sheet)], "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipTable, sheetRelationshipsTableXML, "")
- f.addSheetTable(sheet, rID)
- err = f.addTable(sheet, tableXML, hcol, hrow, vcol, vrow, tableID, formatSet)
- if err != nil {
+ if err = f.addSheetTable(sheet, rID); err != nil {
+ return err
+ }
+ f.addSheetNameSpace(sheet, SourceRelationship)
+ if err = f.addTable(sheet, tableXML, hcol, hrow, vcol, vrow, tableID, formatSet); err != nil {
return err
}
f.addContentTypePart(tableID, "table")
@@ -106,16 +108,20 @@ func (f *File) countTables() int {
// addSheetTable provides a function to add tablePart element to
// xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
-func (f *File) addSheetTable(sheet string, rID int) {
- xlsx, _ := f.workSheetReader(sheet)
+func (f *File) addSheetTable(sheet string, rID int) error {
+ ws, err := f.workSheetReader(sheet)
+ if err != nil {
+ return err
+ }
table := &xlsxTablePart{
RID: "rId" + strconv.Itoa(rID),
}
- if xlsx.TableParts == nil {
- xlsx.TableParts = &xlsxTableParts{}
+ if ws.TableParts == nil {
+ ws.TableParts = &xlsxTableParts{}
}
- xlsx.TableParts.Count++
- xlsx.TableParts.TableParts = append(xlsx.TableParts.TableParts, table)
+ ws.TableParts.Count++
+ ws.TableParts.TableParts = append(ws.TableParts.TableParts, table)
+ return err
}
// addTable provides a function to add table by given worksheet name,
@@ -159,7 +165,7 @@ func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, formatSet
name = "Table" + strconv.Itoa(i)
}
t := xlsxTable{
- XMLNS: NameSpaceSpreadSheet,
+ XMLNS: NameSpaceSpreadSheet.Value,
ID: i,
Name: name,
DisplayName: name,
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 9c7ef54..24df0fa 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -14,8 +14,14 @@ package excelize
import "encoding/xml"
// Source relationship and namespace.
+var (
+ SourceRelationship = xml.Attr{Name: xml.Name{Local: "r", Space: "xmlns"}, Value: "http://schemas.openxmlformats.org/officeDocument/2006/relationships"}
+ NameSpaceSpreadSheet = xml.Attr{Name: xml.Name{Local: "xmlns"}, Value: "http://schemas.openxmlformats.org/spreadsheetml/2006/main"}
+ NameSpaceSpreadSheetX14 = xml.Attr{Name: xml.Name{Local: "x14", Space: "xmlns"}, Value: "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"}
+)
+
+// 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"
@@ -37,8 +43,6 @@ const (
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"