Skip to content

Commit 1427027

Browse files
BluesJhaoxuri
authored andcommitted
Resolve qax-os#235, performance optimization for add comments (qax-os#347)
1 parent c223815 commit 1427027

File tree

3 files changed

+120
-60
lines changed

3 files changed

+120
-60
lines changed

comment.go

Lines changed: 88 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -122,31 +122,34 @@ func (f *File) addDrawingVML(commentID int, drawingVML, cell string, lineCount,
122122
row, _ := strconv.Atoi(strings.Map(intOnlyMapF, cell))
123123
xAxis := row - 1
124124
yAxis := TitleToNumber(col)
125-
vml := vmlDrawing{
126-
XMLNSv: "urn:schemas-microsoft-com:vml",
127-
XMLNSo: "urn:schemas-microsoft-com:office:office",
128-
XMLNSx: "urn:schemas-microsoft-com:office:excel",
129-
XMLNSmv: "http://macVmlSchemaUri",
130-
Shapelayout: &xlsxShapelayout{
131-
Ext: "edit",
132-
IDmap: &xlsxIDmap{
133-
Ext: "edit",
134-
Data: commentID,
135-
},
136-
},
137-
Shapetype: &xlsxShapetype{
138-
ID: "_x0000_t202",
139-
Coordsize: "21600,21600",
140-
Spt: 202,
141-
Path: "m0,0l0,21600,21600,21600,21600,0xe",
142-
Stroke: &xlsxStroke{
143-
Joinstyle: "miter",
125+
vml := f.VMLDrawing[drawingVML]
126+
if vml == nil {
127+
vml = &vmlDrawing{
128+
XMLNSv: "urn:schemas-microsoft-com:vml",
129+
XMLNSo: "urn:schemas-microsoft-com:office:office",
130+
XMLNSx: "urn:schemas-microsoft-com:office:excel",
131+
XMLNSmv: "http://macVmlSchemaUri",
132+
Shapelayout: &xlsxShapelayout{
133+
Ext: "edit",
134+
IDmap: &xlsxIDmap{
135+
Ext: "edit",
136+
Data: commentID,
137+
},
144138
},
145-
VPath: &vPath{
146-
Gradientshapeok: "t",
147-
Connecttype: "miter",
139+
Shapetype: &xlsxShapetype{
140+
ID: "_x0000_t202",
141+
Coordsize: "21600,21600",
142+
Spt: 202,
143+
Path: "m0,0l0,21600,21600,21600,21600,0xe",
144+
Stroke: &xlsxStroke{
145+
Joinstyle: "miter",
146+
},
147+
VPath: &vPath{
148+
Gradientshapeok: "t",
149+
Connecttype: "miter",
150+
},
148151
},
149-
},
152+
}
150153
}
151154
sp := encodeShape{
152155
Fill: &vFill{
@@ -191,10 +194,8 @@ func (f *File) addDrawingVML(commentID int, drawingVML, cell string, lineCount,
191194
Strokecolor: "#edeaa1",
192195
Val: string(s[13 : len(s)-14]),
193196
}
194-
c, ok := f.XLSX[drawingVML]
195-
if ok {
196-
d := decodeVmlDrawing{}
197-
_ = xml.Unmarshal(namespaceStrictToTransitional(c), &d)
197+
d := f.decodeVMLDrawingReader(drawingVML)
198+
if d != nil {
198199
for _, v := range d.Shape {
199200
s := xlsxShape{
200201
ID: "_x0000_s1025",
@@ -208,8 +209,7 @@ func (f *File) addDrawingVML(commentID int, drawingVML, cell string, lineCount,
208209
}
209210
}
210211
vml.Shape = append(vml.Shape, shape)
211-
v, _ := xml.Marshal(vml)
212-
f.XLSX[drawingVML] = v
212+
f.VMLDrawing[drawingVML] = vml
213213
}
214214

215215
// addComment provides a function to create chart as xl/comments%d.xml by
@@ -223,12 +223,15 @@ func (f *File) addComment(commentsXML, cell string, formatSet *formatComment) {
223223
if len(t) > 32512 {
224224
t = t[0:32512]
225225
}
226-
comments := xlsxComments{
227-
Authors: []xlsxAuthor{
228-
{
229-
Author: formatSet.Author,
226+
comments := f.commentsReader(commentsXML)
227+
if comments == nil {
228+
comments = &xlsxComments{
229+
Authors: []xlsxAuthor{
230+
{
231+
Author: formatSet.Author,
232+
},
230233
},
231-
},
234+
}
232235
}
233236
cmt := xlsxComment{
234237
Ref: cell,
@@ -261,15 +264,8 @@ func (f *File) addComment(commentsXML, cell string, formatSet *formatComment) {
261264
},
262265
},
263266
}
264-
c, ok := f.XLSX[commentsXML]
265-
if ok {
266-
d := xlsxComments{}
267-
_ = xml.Unmarshal(namespaceStrictToTransitional(c), &d)
268-
comments.CommentList.Comment = append(comments.CommentList.Comment, d.CommentList.Comment...)
269-
}
270267
comments.CommentList.Comment = append(comments.CommentList.Comment, cmt)
271-
v, _ := xml.Marshal(comments)
272-
f.saveFileList(commentsXML, v)
268+
f.Comments[commentsXML] = comments
273269
}
274270

275271
// countComments provides a function to get comments files count storage in
@@ -283,3 +279,53 @@ func (f *File) countComments() int {
283279
}
284280
return count
285281
}
282+
283+
// decodeVMLDrawingReader provides a function to get the pointer to the
284+
// structure after deserialization of xl/drawings/vmlDrawing%d.xml.
285+
func (f *File) decodeVMLDrawingReader(path string) *decodeVmlDrawing {
286+
if f.DecodeVMLDrawing[path] == nil {
287+
c, ok := f.XLSX[path]
288+
if ok {
289+
d := decodeVmlDrawing{}
290+
_ = xml.Unmarshal(namespaceStrictToTransitional(c), &d)
291+
f.DecodeVMLDrawing[path] = &d
292+
}
293+
}
294+
return f.DecodeVMLDrawing[path]
295+
}
296+
297+
// vmlDrawingWriter provides a function to save xl/drawings/vmlDrawing%d.xml.
298+
// after serialize structure.
299+
func (f *File) vmlDrawingWriter() {
300+
for path, vml := range f.VMLDrawing {
301+
if vml != nil {
302+
v, _ := xml.Marshal(vml)
303+
f.XLSX[path] = v
304+
}
305+
}
306+
}
307+
308+
// commentsReader provides a function to get the pointer to the structure
309+
// after deserialization of xl/comments%d.xml.
310+
func (f *File) commentsReader(path string) *xlsxComments {
311+
if f.Comments[path] == nil {
312+
content, ok := f.XLSX[path]
313+
if ok {
314+
c := xlsxComments{}
315+
_ = xml.Unmarshal(namespaceStrictToTransitional(content), &c)
316+
f.Comments[path] = &c
317+
}
318+
}
319+
return f.Comments[path]
320+
}
321+
322+
// commentsWriter provides a function to save xl/comments%d.xml after
323+
// serialize structure.
324+
func (f *File) commentsWriter() {
325+
for path, c := range f.Comments {
326+
if c != nil {
327+
v, _ := xml.Marshal(c)
328+
f.saveFileList(path, v)
329+
}
330+
}
331+
}

excelize.go

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,22 @@ import (
2323

2424
// File define a populated XLSX file struct.
2525
type File struct {
26-
checked map[string]bool
27-
sheetMap map[string]string
28-
CalcChain *xlsxCalcChain
29-
ContentTypes *xlsxTypes
30-
Path string
31-
SharedStrings *xlsxSST
32-
Sheet map[string]*xlsxWorksheet
33-
SheetCount int
34-
Styles *xlsxStyleSheet
35-
Theme *xlsxTheme
36-
WorkBook *xlsxWorkbook
37-
WorkBookRels *xlsxWorkbookRels
38-
XLSX map[string][]byte
26+
checked map[string]bool
27+
sheetMap map[string]string
28+
CalcChain *xlsxCalcChain
29+
Comments map[string]*xlsxComments
30+
ContentTypes *xlsxTypes
31+
Path string
32+
SharedStrings *xlsxSST
33+
Sheet map[string]*xlsxWorksheet
34+
SheetCount int
35+
Styles *xlsxStyleSheet
36+
Theme *xlsxTheme
37+
DecodeVMLDrawing map[string]*decodeVmlDrawing
38+
VMLDrawing map[string]*vmlDrawing
39+
WorkBook *xlsxWorkbook
40+
WorkBookRels *xlsxWorkbookRels
41+
XLSX map[string][]byte
3942
}
4043

4144
// OpenFile take the name of an XLSX file and returns a populated XLSX file
@@ -71,11 +74,15 @@ func OpenReader(r io.Reader) (*File, error) {
7174
return nil, err
7275
}
7376
f := &File{
74-
checked: make(map[string]bool),
75-
Sheet: make(map[string]*xlsxWorksheet),
76-
SheetCount: sheetCount,
77-
XLSX: file,
77+
checked: make(map[string]bool),
78+
Comments: make(map[string]*xlsxComments),
79+
Sheet: make(map[string]*xlsxWorksheet),
80+
SheetCount: sheetCount,
81+
DecodeVMLDrawing: make(map[string]*decodeVmlDrawing),
82+
VMLDrawing: make(map[string]*vmlDrawing),
83+
XLSX: file,
7884
}
85+
f.CalcChain = f.calcChainReader()
7986
f.sheetMap = f.getSheetMap()
8087
f.Styles = f.stylesReader()
8188
f.Theme = f.themeReader()

file.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,12 @@ func NewFile() *File {
3939
SheetCount: 1,
4040
XLSX: file,
4141
}
42+
f.CalcChain = f.calcChainReader()
43+
f.Comments = make(map[string]*xlsxComments)
4244
f.ContentTypes = f.contentTypesReader()
4345
f.Styles = f.stylesReader()
46+
f.DecodeVMLDrawing = make(map[string]*decodeVmlDrawing)
47+
f.VMLDrawing = make(map[string]*vmlDrawing)
4448
f.WorkBook = f.workbookReader()
4549
f.WorkBookRels = f.workbookRelsReader()
4650
f.Sheet["xl/worksheets/sheet1.xml"] = f.workSheetReader("Sheet1")
@@ -87,12 +91,15 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
8791
func (f *File) WriteToBuffer() (*bytes.Buffer, error) {
8892
buf := new(bytes.Buffer)
8993
zw := zip.NewWriter(buf)
94+
f.calcChainWriter()
95+
f.commentsWriter()
9096
f.contentTypesWriter()
97+
f.vmlDrawingWriter()
9198
f.workbookWriter()
9299
f.workbookRelsWriter()
93100
f.worksheetWriter()
94101
f.styleSheetWriter()
95-
f.calcChainWriter()
102+
96103
for path, content := range f.XLSX {
97104
fi, err := zw.Create(path)
98105
if err != nil {

0 commit comments

Comments
 (0)