Combine functions:

workBookRelsWriter, drawingRelsWriter into relsWriter;
drawingRelsReader, workbookRelsReader, workSheetRelsReader into relsReader;
addDrawingRelationships, addSheetRelationships into addRels
This commit is contained in:
xuri 2019-09-16 01:17:35 +08:00
parent a3ee098ab6
commit 8922f65978
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
17 changed files with 190 additions and 273 deletions

View File

@ -1,4 +1,4 @@
<p align="center"><img width="650" src="./excelize.png" alt="Excelize logo"></p> <p align="center"><img width="650" src="./excelize.svg" alt="Excelize logo"></p>
<p align="center"> <p align="center">
<a href="https://travis-ci.org/360EntSecGroup-Skylar/excelize"><img src="https://travis-ci.org/360EntSecGroup-Skylar/excelize.svg?branch=master" alt="Build Status"></a> <a href="https://travis-ci.org/360EntSecGroup-Skylar/excelize"><img src="https://travis-ci.org/360EntSecGroup-Skylar/excelize.svg?branch=master" alt="Build Status"></a>

View File

@ -1,4 +1,4 @@
<p align="center"><img width="650" src="./excelize.png" alt="Excelize logo"></p> <p align="center"><img width="650" src="./excelize.svg" alt="Excelize logo"></p>
<p align="center"> <p align="center">
<a href="https://travis-ci.org/360EntSecGroup-Skylar/excelize"><img src="https://travis-ci.org/360EntSecGroup-Skylar/excelize.svg?branch=master" alt="Build Status"></a> <a href="https://travis-ci.org/360EntSecGroup-Skylar/excelize"><img src="https://travis-ci.org/360EntSecGroup-Skylar/excelize.svg?branch=master" alt="Build Status"></a>

View File

@ -378,7 +378,9 @@ func (f *File) SetCellHyperLink(sheet, axis, link, linkType string) error {
linkData = xlsxHyperlink{ linkData = xlsxHyperlink{
Ref: axis, Ref: axis,
} }
rID := f.addSheetRelationships(sheet, SourceRelationshipHyperLink, link, linkType) sheetPath, _ := f.sheetMap[trimSheetName(sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipHyperLink, link, linkType)
linkData.RID = "rId" + strconv.Itoa(rID) linkData.RID = "rId" + strconv.Itoa(rID)
case "Location": case "Location":
linkData = xlsxHyperlink{ linkData = xlsxHyperlink{

View File

@ -727,7 +727,8 @@ func (f *File) AddChart(sheet, cell, format string) error {
chartID := f.countCharts() + 1 chartID := f.countCharts() + 1
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml" drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML) drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "") drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
drawingRID := f.addRels(drawingRels, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
err = f.addDrawingChart(sheet, drawingXML, cell, formatSet.Dimension.Width, formatSet.Dimension.Height, drawingRID, &formatSet.Format) err = f.addDrawingChart(sheet, drawingXML, cell, formatSet.Dimension.Width, formatSet.Dimension.Height, drawingRID, &formatSet.Format)
if err != nil { if err != nil {
return err return err
@ -761,7 +762,9 @@ func (f *File) prepareDrawing(xlsx *xlsxWorksheet, drawingID int, sheet, drawing
drawingXML = strings.Replace(sheetRelationshipsDrawingXML, "..", "xl", -1) drawingXML = strings.Replace(sheetRelationshipsDrawingXML, "..", "xl", -1)
} else { } else {
// Add first picture for given sheet. // Add first picture for given sheet.
rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "") sheetPath, _ := f.sheetMap[trimSheetName(sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
f.addSheetDrawing(sheet, rID) f.addSheetDrawing(sheet, rID)
} }
return drawingID, drawingXML return drawingID, drawingXML

View File

@ -60,7 +60,7 @@ func (f *File) GetComments() (comments map[string][]Comment) {
// given worksheet index. // given worksheet index.
func (f *File) getSheetComments(sheetID int) string { func (f *File) getSheetComments(sheetID int) string {
var rels = "xl/worksheets/_rels/sheet" + strconv.Itoa(sheetID) + ".xml.rels" var rels = "xl/worksheets/_rels/sheet" + strconv.Itoa(sheetID) + ".xml.rels"
if sheetRels := f.workSheetRelsReader(rels); sheetRels != nil { if sheetRels := f.relsReader(rels); sheetRels != nil {
for _, v := range sheetRels.Relationships { for _, v := range sheetRels.Relationships {
if v.Type == SourceRelationshipComments { if v.Type == SourceRelationshipComments {
return v.Target return v.Target
@ -98,8 +98,10 @@ func (f *File) AddComment(sheet, cell, format string) error {
drawingVML = strings.Replace(sheetRelationshipsDrawingVML, "..", "xl", -1) drawingVML = strings.Replace(sheetRelationshipsDrawingVML, "..", "xl", -1)
} else { } else {
// Add first comment for given sheet. // Add first comment for given sheet.
rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingVML, sheetRelationshipsDrawingVML, "") sheetPath, _ := f.sheetMap[trimSheetName(sheet)]
f.addSheetRelationships(sheet, SourceRelationshipComments, sheetRelationshipsComments, "") sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipDrawingVML, sheetRelationshipsDrawingVML, "")
f.addRels(sheetRels, SourceRelationshipComments, sheetRelationshipsComments, "")
f.addSheetLegacyDrawing(sheet, rID) f.addSheetLegacyDrawing(sheet, rID)
} }
commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml" commentsXML := "xl/comments" + strconv.Itoa(commentID) + ".xml"

View File

@ -31,7 +31,6 @@ type File struct {
CalcChain *xlsxCalcChain CalcChain *xlsxCalcChain
Comments map[string]*xlsxComments Comments map[string]*xlsxComments
ContentTypes *xlsxTypes ContentTypes *xlsxTypes
DrawingRels map[string]*xlsxWorkbookRels
Drawings map[string]*xlsxWsDr Drawings map[string]*xlsxWsDr
Path string Path string
SharedStrings *xlsxSST SharedStrings *xlsxSST
@ -42,8 +41,7 @@ type File struct {
DecodeVMLDrawing map[string]*decodeVmlDrawing DecodeVMLDrawing map[string]*decodeVmlDrawing
VMLDrawing map[string]*vmlDrawing VMLDrawing map[string]*vmlDrawing
WorkBook *xlsxWorkbook WorkBook *xlsxWorkbook
WorkBookRels *xlsxWorkbookRels Relationships map[string]*xlsxRelationships
WorkSheetRels map[string]*xlsxWorkbookRels
XLSX map[string][]byte XLSX map[string][]byte
} }
@ -93,13 +91,12 @@ func OpenReader(r io.Reader) (*File, error) {
f := &File{ f := &File{
checked: make(map[string]bool), checked: make(map[string]bool),
Comments: make(map[string]*xlsxComments), Comments: make(map[string]*xlsxComments),
DrawingRels: make(map[string]*xlsxWorkbookRels),
Drawings: make(map[string]*xlsxWsDr), Drawings: make(map[string]*xlsxWsDr),
Sheet: make(map[string]*xlsxWorksheet), Sheet: make(map[string]*xlsxWorksheet),
SheetCount: sheetCount, SheetCount: sheetCount,
DecodeVMLDrawing: make(map[string]*decodeVmlDrawing), DecodeVMLDrawing: make(map[string]*decodeVmlDrawing),
VMLDrawing: make(map[string]*vmlDrawing), VMLDrawing: make(map[string]*vmlDrawing),
WorkSheetRels: make(map[string]*xlsxWorkbookRels), Relationships: make(map[string]*xlsxRelationships),
XLSX: file, XLSX: file,
} }
f.CalcChain = f.calcChainReader() f.CalcChain = f.calcChainReader()
@ -176,6 +173,28 @@ func checkSheet(xlsx *xlsxWorksheet) {
xlsx.SheetData = sheetData xlsx.SheetData = sheetData
} }
// addRels provides a function to add relationships by given XML path,
// relationship type, target and target mode.
func (f *File) addRels(relPath, relType, target, targetMode string) int {
rels := f.relsReader(relPath)
rID := 0
if rels == nil {
rels = &xlsxRelationships{}
}
rID = len(rels.Relationships) + 1
var ID bytes.Buffer
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
rels.Relationships = append(rels.Relationships, xlsxRelationship{
ID: ID.String(),
Type: relType,
Target: target,
TargetMode: targetMode,
})
f.Relationships[relPath] = rels
return rID
}
// replaceWorkSheetsRelationshipsNameSpaceBytes provides a function to replace // replaceWorkSheetsRelationshipsNameSpaceBytes provides a function to replace
// xl/worksheets/sheet%d.xml XML tags to self-closing for compatible Microsoft // xl/worksheets/sheet%d.xml XML tags to self-closing for compatible Microsoft
// Office Excel 2007. // Office Excel 2007.
@ -265,7 +284,7 @@ func (f *File) AddVBAProject(bin string) error {
return errors.New("unsupported VBA project extension") return errors.New("unsupported VBA project extension")
} }
f.setContentTypePartVBAProjectExtensions() f.setContentTypePartVBAProjectExtensions()
wb := f.workbookRelsReader() wb := f.relsReader("xl/_rels/workbook.xml.rels")
var rID int var rID int
var ok bool var ok bool
for _, rel := range wb.Relationships { for _, rel := range wb.Relationships {
@ -280,7 +299,7 @@ func (f *File) AddVBAProject(bin string) error {
} }
rID++ rID++
if !ok { if !ok {
wb.Relationships = append(wb.Relationships, xlsxWorkbookRelation{ wb.Relationships = append(wb.Relationships, xlsxRelationship{
ID: "rId" + strconv.Itoa(rID), ID: "rId" + strconv.Itoa(rID),
Target: "vbaProject.bin", Target: "vbaProject.bin",
Type: SourceRelationshipVBAProject, Type: SourceRelationshipVBAProject,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

1
excelize.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -42,14 +42,13 @@ func NewFile() *File {
f.CalcChain = f.calcChainReader() f.CalcChain = f.calcChainReader()
f.Comments = make(map[string]*xlsxComments) f.Comments = make(map[string]*xlsxComments)
f.ContentTypes = f.contentTypesReader() f.ContentTypes = f.contentTypesReader()
f.DrawingRels = make(map[string]*xlsxWorkbookRels)
f.Drawings = make(map[string]*xlsxWsDr) f.Drawings = make(map[string]*xlsxWsDr)
f.Styles = f.stylesReader() f.Styles = f.stylesReader()
f.DecodeVMLDrawing = make(map[string]*decodeVmlDrawing) f.DecodeVMLDrawing = make(map[string]*decodeVmlDrawing)
f.VMLDrawing = make(map[string]*vmlDrawing) f.VMLDrawing = make(map[string]*vmlDrawing)
f.WorkBook = f.workbookReader() f.WorkBook = f.workbookReader()
f.WorkBookRels = f.workbookRelsReader() f.Relationships = make(map[string]*xlsxRelationships)
f.WorkSheetRels = make(map[string]*xlsxWorkbookRels) f.Relationships["xl/_rels/workbook.xml.rels"] = f.relsReader("xl/_rels/workbook.xml.rels")
f.Sheet["xl/worksheets/sheet1.xml"], _ = f.workSheetReader("Sheet1") f.Sheet["xl/worksheets/sheet1.xml"], _ = f.workSheetReader("Sheet1")
f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml" f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
f.Theme = f.themeReader() f.Theme = f.themeReader()
@ -97,13 +96,11 @@ func (f *File) WriteToBuffer() (*bytes.Buffer, error) {
f.calcChainWriter() f.calcChainWriter()
f.commentsWriter() f.commentsWriter()
f.contentTypesWriter() f.contentTypesWriter()
f.drawingRelsWriter()
f.drawingsWriter() f.drawingsWriter()
f.vmlDrawingWriter() f.vmlDrawingWriter()
f.workBookWriter() f.workBookWriter()
f.workBookRelsWriter()
f.workSheetWriter() f.workSheetWriter()
f.workSheetRelsWriter() f.relsWriter()
f.styleSheetWriter() f.styleSheetWriter()
for path, content := range f.XLSX { for path, content := range f.XLSX {

View File

@ -155,14 +155,15 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
drawingID := f.countDrawings() + 1 drawingID := f.countDrawings() + 1
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml" drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML) drawingID, drawingXML = f.prepareDrawing(xlsx, drawingID, sheet, drawingXML)
drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
mediaStr := ".." + strings.TrimPrefix(f.addMedia(file, ext), "xl") mediaStr := ".." + strings.TrimPrefix(f.addMedia(file, ext), "xl")
drawingRID := f.addDrawingRelationships(drawingID, SourceRelationshipImage, mediaStr, hyperlinkType) drawingRID := f.addRels(drawingRels, SourceRelationshipImage, mediaStr, hyperlinkType)
// Add picture with hyperlink. // Add picture with hyperlink.
if formatSet.Hyperlink != "" && formatSet.HyperlinkType != "" { if formatSet.Hyperlink != "" && formatSet.HyperlinkType != "" {
if formatSet.HyperlinkType == "External" { if formatSet.HyperlinkType == "External" {
hyperlinkType = formatSet.HyperlinkType hyperlinkType = formatSet.HyperlinkType
} }
drawingHyperlinkRID = f.addDrawingRelationships(drawingID, SourceRelationshipHyperLink, formatSet.Hyperlink, hyperlinkType) drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, formatSet.Hyperlink, hyperlinkType)
} }
err = f.addDrawingPicture(sheet, drawingXML, cell, name, img.Width, img.Height, drawingRID, drawingHyperlinkRID, formatSet) err = f.addDrawingPicture(sheet, drawingXML, cell, name, img.Width, img.Height, drawingRID, drawingHyperlinkRID, formatSet)
if err != nil { if err != nil {
@ -172,37 +173,6 @@ func (f *File) AddPictureFromBytes(sheet, cell, format, name, extension string,
return err return err
} }
// addSheetRelationships provides a function to add
// xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name, relationship
// type and target.
func (f *File) addSheetRelationships(sheet, relType, target, targetMode string) int {
name, ok := f.sheetMap[trimSheetName(sheet)]
if !ok {
name = strings.ToLower(sheet) + ".xml"
}
var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
sheetRels := f.workSheetRelsReader(rels)
if sheetRels == nil {
sheetRels = &xlsxWorkbookRels{}
}
var rID = 1
var ID bytes.Buffer
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
ID.Reset()
rID = len(sheetRels.Relationships) + 1
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
sheetRels.Relationships = append(sheetRels.Relationships, xlsxWorkbookRelation{
ID: ID.String(),
Type: relType,
Target: target,
TargetMode: targetMode,
})
f.WorkSheetRels[rels] = sheetRels
return rID
}
// deleteSheetRelationships provides a function to delete relationships in // deleteSheetRelationships provides a function to delete relationships in
// xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name and // xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name and
// relationship index. // relationship index.
@ -212,16 +182,16 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
name = strings.ToLower(sheet) + ".xml" name = strings.ToLower(sheet) + ".xml"
} }
var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels" var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
sheetRels := f.workSheetRelsReader(rels) sheetRels := f.relsReader(rels)
if sheetRels == nil { if sheetRels == nil {
sheetRels = &xlsxWorkbookRels{} sheetRels = &xlsxRelationships{}
} }
for k, v := range sheetRels.Relationships { for k, v := range sheetRels.Relationships {
if v.ID == rID { if v.ID == rID {
sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...) sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...)
} }
} }
f.WorkSheetRels[rels] = sheetRels f.Relationships[rels] = sheetRels
} }
// addSheetLegacyDrawing provides a function to add legacy drawing element to // addSheetLegacyDrawing provides a function to add legacy drawing element to
@ -325,33 +295,6 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
return err return err
} }
// addDrawingRelationships provides a function to add image part relationships
// in the file xl/drawings/_rels/drawing%d.xml.rels by given drawing index,
// relationship type and target.
func (f *File) addDrawingRelationships(index int, relType, target, targetMode string) int {
var rels = "xl/drawings/_rels/drawing" + strconv.Itoa(index) + ".xml.rels"
var rID = 1
var ID bytes.Buffer
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
drawingRels := f.drawingRelsReader(rels)
if drawingRels == nil {
drawingRels = &xlsxWorkbookRels{}
}
ID.Reset()
rID = len(drawingRels.Relationships) + 1
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
drawingRels.Relationships = append(drawingRels.Relationships, xlsxWorkbookRelation{
ID: ID.String(),
Type: relType,
Target: target,
TargetMode: targetMode,
})
f.DrawingRels[rels] = drawingRels
return rID
}
// countMedia provides a function to get media files count storage in the // countMedia provides a function to get media files count storage in the
// folder xl/media/image. // folder xl/media/image.
func (f *File) countMedia() int { func (f *File) countMedia() int {
@ -429,16 +372,20 @@ func (f *File) addContentTypePart(index int, contentType string) {
"drawings": f.setContentTypePartImageExtensions, "drawings": f.setContentTypePartImageExtensions,
} }
partNames := map[string]string{ partNames := map[string]string{
"chart": "/xl/charts/chart" + strconv.Itoa(index) + ".xml", "chart": "/xl/charts/chart" + strconv.Itoa(index) + ".xml",
"comments": "/xl/comments" + strconv.Itoa(index) + ".xml", "comments": "/xl/comments" + strconv.Itoa(index) + ".xml",
"drawings": "/xl/drawings/drawing" + strconv.Itoa(index) + ".xml", "drawings": "/xl/drawings/drawing" + strconv.Itoa(index) + ".xml",
"table": "/xl/tables/table" + strconv.Itoa(index) + ".xml", "table": "/xl/tables/table" + strconv.Itoa(index) + ".xml",
"pivotTable": "/xl/pivotTables/pivotTable" + strconv.Itoa(index) + ".xml",
"pivotCache": "/xl/pivotCache/pivotCacheDefinition" + strconv.Itoa(index) + ".xml",
} }
contentTypes := map[string]string{ contentTypes := map[string]string{
"chart": "application/vnd.openxmlformats-officedocument.drawingml.chart+xml", "chart": "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
"comments": "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml", "comments": "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
"drawings": "application/vnd.openxmlformats-officedocument.drawing+xml", "drawings": "application/vnd.openxmlformats-officedocument.drawing+xml",
"table": "application/vnd.openxmlformats-officedocument.spreadsheetml.table+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",
} }
s, ok := setContentType[contentType] s, ok := setContentType[contentType]
if ok { if ok {
@ -465,9 +412,9 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
name = strings.ToLower(sheet) + ".xml" name = strings.ToLower(sheet) + ".xml"
} }
var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels" var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
sheetRels := f.workSheetRelsReader(rels) sheetRels := f.relsReader(rels)
if sheetRels == nil { if sheetRels == nil {
sheetRels = &xlsxWorkbookRels{} sheetRels = &xlsxRelationships{}
} }
for _, v := range sheetRels.Relationships { for _, v := range sheetRels.Relationships {
if v.ID == rID { if v.ID == rID {
@ -529,12 +476,12 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
for _, anchor := range wsDr.TwoCellAnchor { for _, anchor := range wsDr.TwoCellAnchor {
if anchor.From != nil && anchor.Pic != nil { if anchor.From != nil && anchor.Pic != nil {
if anchor.From.Col == col && anchor.From.Row == row { if anchor.From.Col == col && anchor.From.Row == row {
xlsxWorkbookRelation := f.getDrawingRelationships(drawingRelationships, xlsxRelationship := f.getDrawingRelationships(drawingRelationships,
anchor.Pic.BlipFill.Blip.Embed) anchor.Pic.BlipFill.Blip.Embed)
_, ok := supportImageTypes[filepath.Ext(xlsxWorkbookRelation.Target)] _, ok := supportImageTypes[filepath.Ext(xlsxRelationship.Target)]
if ok { if ok {
return filepath.Base(xlsxWorkbookRelation.Target), return filepath.Base(xlsxRelationship.Target),
[]byte(f.XLSX[strings.Replace(xlsxWorkbookRelation.Target, []byte(f.XLSX[strings.Replace(xlsxRelationship.Target,
"..", "xl", -1)]), nil "..", "xl", -1)]), nil
} }
} }
@ -548,10 +495,10 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
_ = xml.Unmarshal([]byte("<decodeTwoCellAnchor>"+anchor.Content+"</decodeTwoCellAnchor>"), &decodeTwoCellAnchor) _ = xml.Unmarshal([]byte("<decodeTwoCellAnchor>"+anchor.Content+"</decodeTwoCellAnchor>"), &decodeTwoCellAnchor)
if decodeTwoCellAnchor.From != nil && decodeTwoCellAnchor.Pic != nil { if decodeTwoCellAnchor.From != nil && decodeTwoCellAnchor.Pic != nil {
if decodeTwoCellAnchor.From.Col == col && decodeTwoCellAnchor.From.Row == row { if decodeTwoCellAnchor.From.Col == col && decodeTwoCellAnchor.From.Row == row {
xlsxWorkbookRelation := f.getDrawingRelationships(drawingRelationships, decodeTwoCellAnchor.Pic.BlipFill.Blip.Embed) xlsxRelationship := f.getDrawingRelationships(drawingRelationships, decodeTwoCellAnchor.Pic.BlipFill.Blip.Embed)
_, ok := supportImageTypes[filepath.Ext(xlsxWorkbookRelation.Target)] _, ok := supportImageTypes[filepath.Ext(xlsxRelationship.Target)]
if ok { if ok {
return filepath.Base(xlsxWorkbookRelation.Target), []byte(f.XLSX[strings.Replace(xlsxWorkbookRelation.Target, "..", "xl", -1)]), nil return filepath.Base(xlsxRelationship.Target), []byte(f.XLSX[strings.Replace(xlsxRelationship.Target, "..", "xl", -1)]), nil
} }
} }
} }
@ -562,8 +509,8 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
// getDrawingRelationships provides a function to get drawing relationships // getDrawingRelationships provides a function to get drawing relationships
// from xl/drawings/_rels/drawing%s.xml.rels by given file name and // from xl/drawings/_rels/drawing%s.xml.rels by given file name and
// relationship ID. // relationship ID.
func (f *File) getDrawingRelationships(rels, rID string) *xlsxWorkbookRelation { func (f *File) getDrawingRelationships(rels, rID string) *xlsxRelationship {
if drawingRels := f.drawingRelsReader(rels); drawingRels != nil { if drawingRels := f.relsReader(rels); drawingRels != nil {
for _, v := range drawingRels.Relationships { for _, v := range drawingRels.Relationships {
if v.ID == rID { if v.ID == rID {
return &v return &v
@ -573,31 +520,6 @@ func (f *File) getDrawingRelationships(rels, rID string) *xlsxWorkbookRelation {
return nil return nil
} }
// drawingRelsReader provides a function to get the pointer to the structure
// after deserialization of xl/drawings/_rels/drawing%d.xml.rels.
func (f *File) drawingRelsReader(rel string) *xlsxWorkbookRels {
if f.DrawingRels[rel] == nil {
_, ok := f.XLSX[rel]
if ok {
d := xlsxWorkbookRels{}
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(rel)), &d)
f.DrawingRels[rel] = &d
}
}
return f.DrawingRels[rel]
}
// drawingRelsWriter provides a function to save
// xl/drawings/_rels/drawing%d.xml.rels after serialize structure.
func (f *File) drawingRelsWriter() {
for path, d := range f.DrawingRels {
if d != nil {
v, _ := xml.Marshal(d)
f.saveFileList(path, v)
}
}
}
// drawingsWriter provides a function to save xl/drawings/drawing%d.xml after // drawingsWriter provides a function to save xl/drawings/drawing%d.xml after
// serialize structure. // serialize structure.
func (f *File) drawingsWriter() { func (f *File) drawingsWriter() {

View File

@ -275,7 +275,9 @@ func (f *File) AddShape(sheet, cell, format string) error {
drawingXML = strings.Replace(sheetRelationshipsDrawingXML, "..", "xl", -1) drawingXML = strings.Replace(sheetRelationshipsDrawingXML, "..", "xl", -1)
} else { } else {
// Add first shape for given sheet. // Add first shape for given sheet.
rID := f.addSheetRelationships(sheet, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "") name, _ := f.sheetMap[trimSheetName(sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipDrawingML, sheetRelationshipsDrawingXML, "")
f.addSheetDrawing(sheet, rID) f.addSheetDrawing(sheet, rID)
} }
err = f.addDrawingShape(sheet, drawingXML, cell, formatSet) err = f.addDrawingShape(sheet, drawingXML, cell, formatSet)

View File

@ -52,7 +52,7 @@ func (f *File) NewSheet(name string) int {
// Create new sheet /xl/worksheets/sheet%d.xml // Create new sheet /xl/worksheets/sheet%d.xml
f.setSheet(sheetID, name) f.setSheet(sheetID, name)
// Update xl/_rels/workbook.xml.rels // Update xl/_rels/workbook.xml.rels
rID := f.addXlsxWorkbookRels(sheetID) rID := f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipWorkSheet, fmt.Sprintf("worksheets/sheet%d.xml", sheetID), "")
// Update xl/workbook.xml // Update xl/workbook.xml
f.setWorkbook(name, sheetID, rID) f.setWorkbook(name, sheetID, rID)
return sheetID return sheetID
@ -163,50 +163,18 @@ func (f *File) setWorkbook(name string, sheetID, rid int) {
}) })
} }
// workbookRelsReader provides a function to read and unmarshal workbook // relsWriter provides a function to save relationships after
// relationships of XLSX file.
func (f *File) workbookRelsReader() *xlsxWorkbookRels {
if f.WorkBookRels == nil {
var content xlsxWorkbookRels
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML("xl/_rels/workbook.xml.rels")), &content)
f.WorkBookRels = &content
}
return f.WorkBookRels
}
// workBookRelsWriter provides a function to save xl/_rels/workbook.xml.rels after
// serialize structure. // serialize structure.
func (f *File) workBookRelsWriter() { func (f *File) relsWriter() {
if f.WorkBookRels != nil { for path, rel := range f.Relationships {
output, _ := xml.Marshal(f.WorkBookRels) if rel != nil {
f.saveFileList("xl/_rels/workbook.xml.rels", output) output, _ := xml.Marshal(rel)
} if strings.HasPrefix(path, "xl/worksheets/sheet/rels/sheet") {
} output = replaceWorkSheetsRelationshipsNameSpaceBytes(output)
}
// addXlsxWorkbookRels update workbook relationships property of XLSX. f.saveFileList(path, replaceRelationshipsBytes(output))
func (f *File) addXlsxWorkbookRels(sheet int) int {
content := f.workbookRelsReader()
rID := 0
for _, v := range content.Relationships {
t, _ := strconv.Atoi(strings.TrimPrefix(v.ID, "rId"))
if t > rID {
rID = t
} }
} }
rID++
ID := bytes.Buffer{}
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
target := bytes.Buffer{}
target.WriteString("worksheets/sheet")
target.WriteString(strconv.Itoa(sheet))
target.WriteString(".xml")
content.Relationships = append(content.Relationships, xlsxWorkbookRelation{
ID: ID.String(),
Target: target.String(),
Type: SourceRelationshipWorkSheet,
})
return rID
} }
// setAppXML update docProps/app.xml file of XML. // setAppXML update docProps/app.xml file of XML.
@ -365,7 +333,7 @@ func (f *File) GetSheetMap() map[int]string {
// of XLSX. // of XLSX.
func (f *File) getSheetMap() map[string]string { func (f *File) getSheetMap() map[string]string {
content := f.workbookReader() content := f.workbookReader()
rels := f.workbookRelsReader() rels := f.relsReader("xl/_rels/workbook.xml.rels")
maps := map[string]string{} maps := map[string]string{}
for _, v := range content.Sheets.Sheet { for _, v := range content.Sheets.Sheet {
for _, rel := range rels.Relationships { for _, rel := range rels.Relationships {
@ -396,7 +364,9 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
} }
file, _ := ioutil.ReadFile(picture) file, _ := ioutil.ReadFile(picture)
name := f.addMedia(file, ext) name := f.addMedia(file, ext)
rID := f.addSheetRelationships(sheet, SourceRelationshipImage, strings.Replace(name, "xl", "..", 1), "") sheetPath, _ := f.sheetMap[trimSheetName(sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipImage, strings.Replace(name, "xl", "..", 1), "")
f.addSheetPicture(sheet, rID) f.addSheetPicture(sheet, rID)
f.setContentTypePartImageExtensions() f.setContentTypePartImageExtensions()
return err return err
@ -413,7 +383,7 @@ func (f *File) DeleteSheet(name string) {
} }
sheetName := trimSheetName(name) sheetName := trimSheetName(name)
wb := f.workbookReader() wb := f.workbookReader()
wbRels := f.workbookRelsReader() wbRels := f.relsReader("xl/_rels/workbook.xml.rels")
for idx, sheet := range wb.Sheets.Sheet { for idx, sheet := range wb.Sheets.Sheet {
if sheet.Name == sheetName { if sheet.Name == sheetName {
wb.Sheets.Sheet = append(wb.Sheets.Sheet[:idx], wb.Sheets.Sheet[idx+1:]...) wb.Sheets.Sheet = append(wb.Sheets.Sheet[:idx], wb.Sheets.Sheet[idx+1:]...)
@ -443,7 +413,7 @@ func (f *File) DeleteSheet(name string) {
// relationships by given relationships ID in the file // relationships by given relationships ID in the file
// xl/_rels/workbook.xml.rels. // xl/_rels/workbook.xml.rels.
func (f *File) deleteSheetFromWorkbookRels(rID string) string { func (f *File) deleteSheetFromWorkbookRels(rID string) string {
content := f.workbookRelsReader() content := f.relsReader("xl/_rels/workbook.xml.rels")
for k, v := range content.Relationships { for k, v := range content.Relationships {
if v.ID == rID { if v.ID == rID {
content.Relationships = append(content.Relationships[:k], content.Relationships[k+1:]...) content.Relationships = append(content.Relationships[:k], content.Relationships[k+1:]...)
@ -1387,29 +1357,18 @@ func (f *File) UngroupSheets() error {
return nil return nil
} }
// workSheetRelsReader provides a function to get the pointer to the structure // relsReader provides a function to get the pointer to the structure
// after deserialization of xl/worksheets/_rels/sheet%d.xml.rels. // after deserialization of xl/worksheets/_rels/sheet%d.xml.rels.
func (f *File) workSheetRelsReader(path string) *xlsxWorkbookRels { func (f *File) relsReader(path string) *xlsxRelationships {
if f.WorkSheetRels[path] == nil { if f.Relationships[path] == nil {
_, ok := f.XLSX[path] _, ok := f.XLSX[path]
if ok { if ok {
c := xlsxWorkbookRels{} c := xlsxRelationships{}
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(path)), &c) _ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(path)), &c)
f.WorkSheetRels[path] = &c f.Relationships[path] = &c
}
}
return f.WorkSheetRels[path]
}
// workSheetRelsWriter provides a function to save
// xl/worksheets/_rels/sheet%d.xml.rels after serialize structure.
func (f *File) workSheetRelsWriter() {
for p, r := range f.WorkSheetRels {
if r != nil {
v, _ := xml.Marshal(r)
f.saveFileList(p, v)
} }
} }
return f.Relationships[path]
} }
// fillSheetData ensures there are enough rows, and columns in the chosen // fillSheetData ensures there are enough rows, and columns in the chosen

View File

@ -77,7 +77,9 @@ func (f *File) AddTable(sheet, hcell, vcell, format string) error {
sheetRelationshipsTableXML := "../tables/table" + strconv.Itoa(tableID) + ".xml" sheetRelationshipsTableXML := "../tables/table" + strconv.Itoa(tableID) + ".xml"
tableXML := strings.Replace(sheetRelationshipsTableXML, "..", "xl", -1) tableXML := strings.Replace(sheetRelationshipsTableXML, "..", "xl", -1)
// Add first table for given sheet. // Add first table for given sheet.
rID := f.addSheetRelationships(sheet, SourceRelationshipTable, sheetRelationshipsTableXML, "") sheetPath, _ := f.sheetMap[trimSheetName(sheet)]
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetPath, "xl/worksheets/") + ".rels"
rID := f.addRels(sheetRels, SourceRelationshipTable, sheetRelationshipsTableXML, "")
f.addSheetTable(sheet, rID) f.addSheetTable(sheet, rID)
err = f.addTable(sheet, tableXML, hcol, hrow, vcol, vrow, tableID, formatSet) err = f.addTable(sheet, tableXML, hcol, hrow, vcol, vrow, tableID, formatSet)
if err != nil { if err != nil {

View File

@ -22,6 +22,8 @@ const (
SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing" SourceRelationshipDrawingVML = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"
SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" SourceRelationshipHyperLink = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
SourceRelationshipWorkSheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" 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" SourceRelationshipVBAProject = "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
SourceRelationshipChart201506 = "http://schemas.microsoft.com/office/drawing/2015/06/chart" SourceRelationshipChart201506 = "http://schemas.microsoft.com/office/drawing/2015/06/chart"
SourceRelationshipChart20070802 = "http://schemas.microsoft.com/office/drawing/2007/8/2/chart" SourceRelationshipChart20070802 = "http://schemas.microsoft.com/office/drawing/2007/8/2/chart"

View File

@ -2,11 +2,11 @@ package excelize
import "encoding/xml" import "encoding/xml"
// pivotCacheDefinition represents the pivotCacheDefinition part. This part // xlsxPivotCacheDefinition represents the pivotCacheDefinition part. This part
// defines each field in the source data, including the name, the string // defines each field in the source data, including the name, the string
// resources of the instance data (for shared items), and information about // resources of the instance data (for shared items), and information about
// the type of data that appears in the field. // the type of data that appears in the field.
type xmlPivotCacheDefinition struct { type xlsxPivotCacheDefinition struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main pivotCacheDefinition"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main pivotCacheDefinition"`
RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"` RID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
Invalid bool `xml:"invalid,attr,omitempty"` Invalid bool `xml:"invalid,attr,omitempty"`

View File

@ -15,78 +15,84 @@ import "encoding/xml"
// non-null PivotTables. There exists one pivotTableDefinition for each // non-null PivotTables. There exists one pivotTableDefinition for each
// PivotTableDefinition part // PivotTableDefinition part
type xlsxPivotTableDefinition struct { type xlsxPivotTableDefinition struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main pivotTableDefinition"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main pivotTableDefinition"`
Name string `xml:"name,attr"` Name string `xml:"name,attr"`
CacheID int `xml:"cacheId,attr"` CacheID int `xml:"cacheId,attr"`
DataOnRows bool `xml:"dataOnRows,attr"` ApplyNumberFormats bool `xml:"applyNumberFormats,attr,omitempty"`
DataPosition int `xml:"dataPosition,attr"` ApplyBorderFormats bool `xml:"applyBorderFormats,attr,omitempty"`
DataCaption string `xml:"dataCaption,attr"` ApplyFontFormats bool `xml:"applyFontFormats,attr,omitempty"`
GrandTotalCaption string `xml:"grandTotalCaption,attr"` ApplyPatternFormats bool `xml:"applyPatternFormats,attr,omitempty"`
ErrorCaption string `xml:"errorCaption,attr"` ApplyAlignmentFormats bool `xml:"applyAlignmentFormats,attr,omitempty"`
ShowError bool `xml:"showError,attr"` ApplyWidthHeightFormats bool `xml:"applyWidthHeightFormats,attr,omitempty"`
MissingCaption string `xml:"missingCaption,attr"` DataOnRows bool `xml:"dataOnRows,attr,omitempty"`
ShowMissing bool `xml:"showMissing,attr"` DataPosition int `xml:"dataPosition,attr,omitempty"`
PageStyle string `xml:"pageStyle,attr"` DataCaption string `xml:"dataCaption,attr"`
PivotTableStyle string `xml:"pivotTableStyle,attr"` GrandTotalCaption string `xml:"grandTotalCaption,attr,omitempty"`
VacatedStyle string `xml:"vacatedStyle,attr"` ErrorCaption string `xml:"errorCaption,attr,omitempty"`
Tag string `xml:"tag,attr"` ShowError bool `xml:"showError,attr,omitempty"`
UpdatedVersion int `xml:"updatedVersion,attr"` MissingCaption string `xml:"missingCaption,attr,omitempty"`
MinRefreshableVersion int `xml:"minRefreshableVersion,attr"` ShowMissing bool `xml:"showMissing,attr,omitempty"`
AsteriskTotals bool `xml:"asteriskTotals,attr"` PageStyle string `xml:"pageStyle,attr,omitempty"`
ShowItems bool `xml:"showItems,attr"` PivotTableStyle string `xml:"pivotTableStyle,attr,omitempty"`
EditData bool `xml:"editData,attr"` VacatedStyle string `xml:"vacatedStyle,attr,omitempty"`
DisableFieldList bool `xml:"disableFieldList,attr"` Tag string `xml:"tag,attr,omitempty"`
ShowCalcMbrs bool `xml:"showCalcMbrs,attr"` UpdatedVersion int `xml:"updatedVersion,attr"`
VisualTotals bool `xml:"visualTotals,attr"` MinRefreshableVersion int `xml:"minRefreshableVersion,attr"`
ShowMultipleLabel bool `xml:"showMultipleLabel,attr"` AsteriskTotals bool `xml:"asteriskTotals,attr,omitempty"`
ShowDataDropDown bool `xml:"showDataDropDown,attr"` ShowItems bool `xml:"showItems,attr,omitempty"`
ShowDrill bool `xml:"showDrill,attr"` EditData bool `xml:"editData,attr,omitempty"`
PrintDrill bool `xml:"printDrill,attr"` DisableFieldList bool `xml:"disableFieldList,attr,omitempty"`
ShowMemberPropertyTips bool `xml:"showMemberPropertyTips,attr"` ShowCalcMbrs bool `xml:"showCalcMbrs,attr,omitempty"`
ShowDataTips bool `xml:"showDataTips,attr"` VisualTotals bool `xml:"visualTotals,attr,omitempty"`
EnableWizard bool `xml:"enableWizard,attr"` ShowMultipleLabel bool `xml:"showMultipleLabel,attr,omitempty"`
EnableDrill bool `xml:"enableDrill,attr"` ShowDataDropDown bool `xml:"showDataDropDown,attr,omitempty"`
EnableFieldProperties bool `xml:"enableFieldProperties,attr"` ShowDrill bool `xml:"showDrill,attr,omitempty"`
PreserveFormatting bool `xml:"preserveFormatting,attr"` PrintDrill bool `xml:"printDrill,attr,omitempty"`
UseAutoFormatting bool `xml:"useAutoFormatting,attr"` ShowMemberPropertyTips bool `xml:"showMemberPropertyTips,attr,omitempty"`
PageWrap int `xml:"pageWrap,attr"` ShowDataTips bool `xml:"showDataTips,attr,omitempty"`
PageOverThenDown bool `xml:"pageOverThenDown,attr"` EnableWizard bool `xml:"enableWizard,attr,omitempty"`
SubtotalHiddenItems bool `xml:"subtotalHiddenItems,attr"` EnableDrill bool `xml:"enableDrill,attr,omitempty"`
RowGrandTotals bool `xml:"rowGrandTotals,attr"` EnableFieldProperties bool `xml:"enableFieldProperties,attr,omitempty"`
ColGrandTotals bool `xml:"colGrandTotals,attr"` PreserveFormatting bool `xml:"preserveFormatting,attr,omitempty"`
FieldPrintTitles bool `xml:"fieldPrintTitles,attr"` UseAutoFormatting bool `xml:"useAutoFormatting,attr"`
ItemPrintTitles bool `xml:"itemPrintTitles,attr"` PageWrap int `xml:"pageWrap,attr,omitempty"`
MergeItem bool `xml:"mergeItem,attr"` PageOverThenDown bool `xml:"pageOverThenDown,attr,omitempty"`
ShowDropZones bool `xml:"showDropZones,attr"` SubtotalHiddenItems bool `xml:"subtotalHiddenItems,attr,omitempty"`
CreatedVersion int `xml:"createdVersion,attr"` RowGrandTotals bool `xml:"rowGrandTotals,attr,omitempty"`
Indent int `xml:"indent,attr"` ColGrandTotals bool `xml:"colGrandTotals,attr,omitempty"`
ShowEmptyRow bool `xml:"showEmptyRow,attr"` FieldPrintTitles bool `xml:"fieldPrintTitles,attr,omitempty"`
ShowEmptyCol bool `xml:"showEmptyCol,attr"` ItemPrintTitles bool `xml:"itemPrintTitles,attr"`
ShowHeaders bool `xml:"showHeaders,attr"` MergeItem bool `xml:"mergeItem,attr,omitempty"`
Compact bool `xml:"compact,attr"` ShowDropZones bool `xml:"showDropZones,attr,omitempty"`
Outline bool `xml:"outline,attr"` CreatedVersion int `xml:"createdVersion,attr"`
OutlineData bool `xml:"outlineData,attr"` Indent int `xml:"indent,attr,omitempty"`
CompactData bool `xml:"compactData,attr"` ShowEmptyRow bool `xml:"showEmptyRow,attr,omitempty"`
Published bool `xml:"published,attr"` ShowEmptyCol bool `xml:"showEmptyCol,attr,omitempty"`
GridDropZones bool `xml:"gridDropZones,attr"` ShowHeaders bool `xml:"showHeaders,attr,omitempty"`
Immersive bool `xml:"immersive,attr"` Compact bool `xml:"compact,attr,omitempty"`
MultipleFieldFilters bool `xml:"multipleFieldFilters,attr"` Outline bool `xml:"outline,attr,omitempty"`
ChartFormat int `xml:"chartFormat,attr"` OutlineData bool `xml:"outlineData,attr,omitempty"`
RowHeaderCaption string `xml:"rowHeaderCaption,attr"` CompactData bool `xml:"compactData,attr,omitempty"`
ColHeaderCaption string `xml:"colHeaderCaption,attr"` Published bool `xml:"published,attr,omitempty"`
FieldListSortAscending bool `xml:"fieldListSortAscending,attr"` GridDropZones bool `xml:"gridDropZones,attr"`
MdxSubqueries bool `xml:"mdxSubqueries,attr"` Immersive bool `xml:"immersive,attr,omitempty"`
CustomListSort bool `xml:"customListSort,attr"` MultipleFieldFilters bool `xml:"multipleFieldFilters,attr,omitempty"`
Location *xlsxLocation `xml:"location"` ChartFormat int `xml:"chartFormat,attr,omitempty"`
PivotFields *xlsxPivotFields `xml:"pivotFields"` RowHeaderCaption string `xml:"rowHeaderCaption,attr,omitempty"`
RowFields *xlsxRowFields `xml:"rowFields"` ColHeaderCaption string `xml:"colHeaderCaption,attr,omitempty"`
RowItems *xlsxRowItems `xml:"rowItems"` FieldListSortAscending bool `xml:"fieldListSortAscending,attr,omitempty"`
ColFields *xlsxColFields `xml:"colFields"` MdxSubqueries bool `xml:"mdxSubqueries,attr,omitempty"`
ColItems *xlsxColItems `xml:"colItems"` CustomListSort bool `xml:"customListSort,attr,omitempty"`
PageFields *xlsxPageFields `xml:"pageFields"` Location *xlsxLocation `xml:"location"`
DataFields *xlsxDataFields `xml:"dataFields"` PivotFields *xlsxPivotFields `xml:"pivotFields"`
ConditionalFormats *xlsxConditionalFormats `xml:"conditionalFormats"` RowFields *xlsxRowFields `xml:"rowFields"`
PivotTableStyleInfo *xlsxPivotTableStyleInfo `xml:"pivotTableStyleInfo"` RowItems *xlsxRowItems `xml:"rowItems"`
ColFields *xlsxColFields `xml:"colFields"`
ColItems *xlsxColItems `xml:"colItems"`
PageFields *xlsxPageFields `xml:"pageFields"`
DataFields *xlsxDataFields `xml:"dataFields"`
ConditionalFormats *xlsxConditionalFormats `xml:"conditionalFormats"`
PivotTableStyleInfo *xlsxPivotTableStyleInfo `xml:"pivotTableStyleInfo"`
} }
// xlsxLocation represents location information for the PivotTable. // xlsxLocation represents location information for the PivotTable.

View File

@ -11,14 +11,14 @@ package excelize
import "encoding/xml" import "encoding/xml"
// xmlxWorkbookRels contains xmlxWorkbookRelations which maps sheet id and sheet XML. // xlsxRelationships describe references from parts to other internal resources in the package or to external resources.
type xlsxWorkbookRels struct { type xlsxRelationships struct {
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"` XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
Relationships []xlsxWorkbookRelation `xml:"Relationship"` Relationships []xlsxRelationship `xml:"Relationship"`
} }
// xmlxWorkbookRelation maps sheet id and xl/worksheets/_rels/sheet%d.xml.rels // xlsxRelationship contains relations which maps id and XML.
type xlsxWorkbookRelation struct { type xlsxRelationship struct {
ID string `xml:"Id,attr"` ID string `xml:"Id,attr"`
Target string `xml:",attr"` Target string `xml:",attr"`
Type string `xml:",attr"` Type string `xml:",attr"`