Resolve #106, #294 performance optimization for add hyperlink

This commit is contained in:
xuri 2019-02-26 14:21:44 +08:00
parent 1aed1d744b
commit f66212da9b
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
6 changed files with 61 additions and 31 deletions

View File

@ -57,11 +57,11 @@ func (f *File) GetComments() (comments map[string][]Comment) {
// given worksheet index.
func (f *File) getSheetComments(sheetID int) string {
var rels = "xl/worksheets/_rels/sheet" + strconv.Itoa(sheetID) + ".xml.rels"
var sheetRels xlsxWorkbookRels
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(rels)), &sheetRels)
for _, v := range sheetRels.Relationships {
if v.Type == SourceRelationshipComments {
return v.Target
if sheetRels := f.workSheetRelsReader(rels); sheetRels != nil {
for _, v := range sheetRels.Relationships {
if v.Type == SourceRelationshipComments {
return v.Target
}
}
}
return ""

View File

@ -40,6 +40,7 @@ type File struct {
VMLDrawing map[string]*vmlDrawing
WorkBook *xlsxWorkbook
WorkBookRels *xlsxWorkbookRels
WorkSheetRels map[string]*xlsxWorkbookRels
XLSX map[string][]byte
}
@ -84,6 +85,7 @@ func OpenReader(r io.Reader) (*File, error) {
SheetCount: sheetCount,
DecodeVMLDrawing: make(map[string]*decodeVmlDrawing),
VMLDrawing: make(map[string]*vmlDrawing),
WorkSheetRels: make(map[string]*xlsxWorkbookRels),
XLSX: file,
}
f.CalcChain = f.calcChainReader()

View File

@ -49,6 +49,7 @@ func NewFile() *File {
f.VMLDrawing = make(map[string]*vmlDrawing)
f.WorkBook = f.workbookReader()
f.WorkBookRels = f.workbookRelsReader()
f.WorkSheetRels = make(map[string]*xlsxWorkbookRels)
f.Sheet["xl/worksheets/sheet1.xml"] = f.workSheetReader("Sheet1")
f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
f.Theme = f.themeReader()
@ -99,9 +100,10 @@ func (f *File) WriteToBuffer() (*bytes.Buffer, error) {
f.drawingRelsWriter()
f.drawingsWriter()
f.vmlDrawingWriter()
f.workbookWriter()
f.workbookRelsWriter()
f.worksheetWriter()
f.workBookWriter()
f.workBookRelsWriter()
f.workSheetWriter()
f.workSheetRelsWriter()
f.styleSheetWriter()
for path, content := range f.XLSX {

View File

@ -177,27 +177,25 @@ func (f *File) addSheetRelationships(sheet, relType, target, targetMode string)
name = strings.ToLower(sheet) + ".xml"
}
var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
var sheetRels xlsxWorkbookRels
sheetRels := f.workSheetRelsReader(rels)
if sheetRels == nil {
sheetRels = &xlsxWorkbookRels{}
}
var rID = 1
var ID bytes.Buffer
ID.WriteString("rId")
ID.WriteString(strconv.Itoa(rID))
_, ok = f.XLSX[rels]
if ok {
ID.Reset()
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(rels)), &sheetRels)
rID = len(sheetRels.Relationships) + 1
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,
})
output, _ := xml.Marshal(sheetRels)
f.saveFileList(rels, output)
f.WorkSheetRels[rels] = sheetRels
return rID
}
@ -210,15 +208,16 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
name = strings.ToLower(sheet) + ".xml"
}
var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
var sheetRels xlsxWorkbookRels
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(rels)), &sheetRels)
sheetRels := f.workSheetRelsReader(rels)
if sheetRels == nil {
sheetRels = &xlsxWorkbookRels{}
}
for k, v := range sheetRels.Relationships {
if v.ID == rID {
sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...)
}
}
output, _ := xml.Marshal(sheetRels)
f.saveFileList(rels, output)
f.WorkSheetRels[rels] = sheetRels
}
// addSheetLegacyDrawing provides a function to add legacy drawing element to
@ -441,8 +440,10 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
name = strings.ToLower(sheet) + ".xml"
}
var rels = "xl/worksheets/_rels/" + strings.TrimPrefix(name, "xl/worksheets/") + ".rels"
var sheetRels xlsxWorkbookRels
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(rels)), &sheetRels)
sheetRels := f.workSheetRelsReader(rels)
if sheetRels == nil {
sheetRels = &xlsxWorkbookRels{}
}
for _, v := range sheetRels.Relationships {
if v.ID == rID {
return v.Target

View File

@ -88,18 +88,18 @@ func (f *File) workbookReader() *xlsxWorkbook {
return f.WorkBook
}
// workbookWriter provides a function to save xl/workbook.xml after serialize
// workBookWriter provides a function to save xl/workbook.xml after serialize
// structure.
func (f *File) workbookWriter() {
func (f *File) workBookWriter() {
if f.WorkBook != nil {
output, _ := xml.Marshal(f.WorkBook)
f.saveFileList("xl/workbook.xml", replaceRelationshipsNameSpaceBytes(output))
}
}
// worksheetWriter provides a function to save xl/worksheets/sheet%d.xml after
// workSheetWriter provides a function to save xl/worksheets/sheet%d.xml after
// serialize structure.
func (f *File) worksheetWriter() {
func (f *File) workSheetWriter() {
for path, sheet := range f.Sheet {
if sheet != nil {
for k, v := range sheet.SheetData.Row {
@ -172,9 +172,9 @@ func (f *File) workbookRelsReader() *xlsxWorkbookRels {
return f.WorkBookRels
}
// workbookRelsWriter provides a function to save xl/_rels/workbook.xml.rels after
// workBookRelsWriter provides a function to save xl/_rels/workbook.xml.rels after
// serialize structure.
func (f *File) workbookRelsWriter() {
func (f *File) workBookRelsWriter() {
if f.WorkBookRels != nil {
output, _ := xml.Marshal(f.WorkBookRels)
f.saveFileList("xl/_rels/workbook.xml.rels", output)
@ -1003,3 +1003,28 @@ func (f *File) GetPageLayout(sheet string, opts ...PageLayoutOptionPtr) error {
}
return nil
}
// workSheetRelsReader provides a function to get the pointer to the structure
// after deserialization of xl/worksheets/_rels/sheet%d.xml.rels.
func (f *File) workSheetRelsReader(path string) *xlsxWorkbookRels {
if f.WorkSheetRels[path] == nil {
_, ok := f.XLSX[path]
if ok {
c := xlsxWorkbookRels{}
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(path)), &c)
f.WorkSheetRels[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 path, r := range f.WorkSheetRels {
if r != nil {
v, _ := xml.Marshal(r)
f.saveFileList(path, v)
}
}
}

0
test/CalcChain.xlsx Executable file → Normal file
View File