Explorar o código

Resolve #106, #294 performance optimization for add hyperlink

xuri %!s(int64=6) %!d(string=hai) anos
pai
achega
f66212da9b
Modificáronse 6 ficheiros con 61 adicións e 31 borrados
  1. 5 5
      comment.go
  2. 2 0
      excelize.go
  3. 5 3
      file.go
  4. 18 17
      picture.go
  5. 31 6
      sheet.go
  6. 0 0
      test/CalcChain.xlsx

+ 5 - 5
comment.go

@@ -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 ""

+ 2 - 0
excelize.go

@@ -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()

+ 5 - 3
file.go

@@ -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 {

+ 18 - 17
picture.go

@@ -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

+ 31 - 6
sheet.go

@@ -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 - 0
test/CalcChain.xlsx