Skip to content

Commit 0e02329

Browse files
committed
This closes qax-os#861, support concurrency get cell picture and remove unused internal function getSheetNameByID
1 parent 5ec6131 commit 0e02329

9 files changed

+58
-59
lines changed

cell_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,23 @@ import (
1414
)
1515

1616
func TestConcurrency(t *testing.T) {
17-
f := NewFile()
17+
f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
18+
assert.NoError(t, err)
1819
wg := new(sync.WaitGroup)
1920
for i := 1; i <= 5; i++ {
2021
wg.Add(1)
2122
go func(val int, t *testing.T) {
23+
// Concurrency set cell value
2224
assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("A%d", val), val))
2325
assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("B%d", val), strconv.Itoa(val)))
2426
_, err := f.GetCellValue("Sheet1", fmt.Sprintf("A%d", val))
2527
assert.NoError(t, err)
28+
// Concurrency get cell picture
29+
name, raw, err := f.GetPicture("Sheet1", "A1")
30+
assert.Equal(t, "", name)
31+
assert.Nil(t, raw)
32+
assert.NoError(t, err)
33+
2634
wg.Done()
2735
}(i, t)
2836
}

drawing.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,8 +1146,8 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
11461146
err error
11471147
ok bool
11481148
)
1149-
1150-
if f.Drawings[path] == nil {
1149+
_, ok = f.Drawings.Load(path)
1150+
if !ok {
11511151
content := xlsxWsDr{}
11521152
content.A = NameSpaceDrawingML.Value
11531153
content.Xdr = NameSpaceDrawingMLSpreadSheet.Value
@@ -1171,10 +1171,10 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
11711171
})
11721172
}
11731173
}
1174-
f.Drawings[path] = &content
1174+
f.Drawings.Store(path, &content)
11751175
}
1176-
wsDr := f.Drawings[path]
1177-
return wsDr, len(wsDr.OneCellAnchor) + len(wsDr.TwoCellAnchor) + 2
1176+
wsDr, _ := f.Drawings.Load(path)
1177+
return wsDr.(*xlsxWsDr), len(wsDr.(*xlsxWsDr).OneCellAnchor) + len(wsDr.(*xlsxWsDr).TwoCellAnchor) + 2
11781178
}
11791179

11801180
// addDrawingChart provides a function to add chart graphic frame by given
@@ -1232,7 +1232,7 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
12321232
FPrintsWithSheet: formatSet.FPrintsWithSheet,
12331233
}
12341234
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
1235-
f.Drawings[drawingXML] = content
1235+
f.Drawings.Store(drawingXML, content)
12361236
return err
12371237
}
12381238

@@ -1272,7 +1272,7 @@ func (f *File) addSheetDrawingChart(drawingXML string, rID int, formatSet *forma
12721272
FPrintsWithSheet: formatSet.FPrintsWithSheet,
12731273
}
12741274
content.AbsoluteAnchor = append(content.AbsoluteAnchor, &absoluteAnchor)
1275-
f.Drawings[drawingXML] = content
1275+
f.Drawings.Store(drawingXML, content)
12761276
}
12771277

12781278
// deleteDrawing provides a function to delete chart graphic frame by given by
@@ -1313,6 +1313,6 @@ func (f *File) deleteDrawing(col, row int, drawingXML, drawingType string) (err
13131313
}
13141314
}
13151315
}
1316-
f.Drawings[drawingXML] = wsDr
1316+
f.Drawings.Store(drawingXML, wsDr)
13171317
return err
13181318
}

drawing_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
package excelize
1313

1414
import (
15+
"sync"
1516
"testing"
1617
)
1718

1819
func TestDrawingParser(t *testing.T) {
1920
f := File{
20-
Drawings: make(map[string]*xlsxWsDr),
21+
Drawings: sync.Map{},
2122
XLSX: map[string][]byte{
2223
"charset": MacintoshCyrillicCharset,
2324
"wsDr": []byte(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"><xdr:oneCellAnchor><xdr:graphicFrame/></xdr:oneCellAnchor></xdr:wsDr>`)},

excelize.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ type File struct {
3939
CalcChain *xlsxCalcChain
4040
Comments map[string]*xlsxComments
4141
ContentTypes *xlsxTypes
42-
Drawings map[string]*xlsxWsDr
42+
Drawings sync.Map
4343
Path string
4444
SharedStrings *xlsxSST
4545
sharedStringsMap map[string]int
@@ -50,7 +50,7 @@ type File struct {
5050
DecodeVMLDrawing map[string]*decodeVmlDrawing
5151
VMLDrawing map[string]*vmlDrawing
5252
WorkBook *xlsxWorkbook
53-
Relationships map[string]*xlsxRelationships
53+
Relationships sync.Map
5454
XLSX map[string][]byte
5555
CharsetReader charsetTranscoderFn
5656
}
@@ -93,12 +93,12 @@ func newFile() *File {
9393
checked: make(map[string]bool),
9494
sheetMap: make(map[string]string),
9595
Comments: make(map[string]*xlsxComments),
96-
Drawings: make(map[string]*xlsxWsDr),
96+
Drawings: sync.Map{},
9797
sharedStringsMap: make(map[string]int),
9898
Sheet: make(map[string]*xlsxWorksheet),
9999
DecodeVMLDrawing: make(map[string]*decodeVmlDrawing),
100100
VMLDrawing: make(map[string]*vmlDrawing),
101-
Relationships: make(map[string]*xlsxRelationships),
101+
Relationships: sync.Map{},
102102
CharsetReader: charset.NewReaderLabel,
103103
}
104104
}
@@ -277,7 +277,7 @@ func (f *File) addRels(relPath, relType, target, targetMode string) int {
277277
Target: target,
278278
TargetMode: targetMode,
279279
})
280-
f.Relationships[relPath] = rels
280+
f.Relationships.Store(relPath, rels)
281281
return rID
282282
}
283283

excelize_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ func TestGetActiveSheetIndex(t *testing.T) {
975975

976976
func TestRelsWriter(t *testing.T) {
977977
f := NewFile()
978-
f.Relationships["xl/worksheets/sheet/rels/sheet1.xml.rel"] = &xlsxRelationships{}
978+
f.Relationships.Store("xl/worksheets/sheet/rels/sheet1.xml.rel", &xlsxRelationships{})
979979
f.relsWriter()
980980
}
981981

@@ -1231,15 +1231,15 @@ func TestRelsReader(t *testing.T) {
12311231
// Test unsupported charset.
12321232
f := NewFile()
12331233
rels := "xl/_rels/workbook.xml.rels"
1234-
f.Relationships[rels] = nil
1234+
f.Relationships.Store(rels, nil)
12351235
f.XLSX[rels] = MacintoshCyrillicCharset
12361236
f.relsReader(rels)
12371237
}
12381238

12391239
func TestDeleteSheetFromWorkbookRels(t *testing.T) {
12401240
f := NewFile()
12411241
rels := "xl/_rels/workbook.xml.rels"
1242-
f.Relationships[rels] = nil
1242+
f.Relationships.Store(rels, nil)
12431243
assert.Equal(t, f.deleteSheetFromWorkbookRels("rID"), "")
12441244
}
12451245

file.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"fmt"
1818
"io"
1919
"os"
20+
"sync"
2021
)
2122

2223
// NewFile provides a function to create new file by default template. For
@@ -40,13 +41,13 @@ func NewFile() *File {
4041
f.CalcChain = f.calcChainReader()
4142
f.Comments = make(map[string]*xlsxComments)
4243
f.ContentTypes = f.contentTypesReader()
43-
f.Drawings = make(map[string]*xlsxWsDr)
44+
f.Drawings = sync.Map{}
4445
f.Styles = f.stylesReader()
4546
f.DecodeVMLDrawing = make(map[string]*decodeVmlDrawing)
4647
f.VMLDrawing = make(map[string]*vmlDrawing)
4748
f.WorkBook = f.workbookReader()
48-
f.Relationships = make(map[string]*xlsxRelationships)
49-
f.Relationships["xl/_rels/workbook.xml.rels"] = f.relsReader("xl/_rels/workbook.xml.rels")
49+
f.Relationships = sync.Map{}
50+
f.Relationships.Store("xl/_rels/workbook.xml.rels", f.relsReader("xl/_rels/workbook.xml.rels"))
5051
f.Sheet["xl/worksheets/sheet1.xml"], _ = f.workSheetReader("Sheet1")
5152
f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
5253
f.Theme = f.themeReader()

picture.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
189189
sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...)
190190
}
191191
}
192-
f.Relationships[rels] = sheetRels
192+
f.Relationships.Store(rels, sheetRels)
193193
}
194194

195195
// addSheetLegacyDrawing provides a function to add legacy drawing element to
@@ -228,11 +228,12 @@ func (f *File) countDrawings() int {
228228
c1++
229229
}
230230
}
231-
for rel := range f.Drawings {
232-
if strings.Contains(rel, "xl/drawings/drawing") {
231+
f.Drawings.Range(func(rel, value interface{}) bool {
232+
if strings.Contains(rel.(string), "xl/drawings/drawing") {
233233
c2++
234234
}
235-
}
235+
return true
236+
})
236237
if c1 < c2 {
237238
return c2
238239
}
@@ -296,7 +297,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
296297
FPrintsWithSheet: formatSet.FPrintsWithSheet,
297298
}
298299
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
299-
f.Drawings[drawingXML] = content
300+
f.Drawings.Store(drawingXML, content)
300301
return err
301302
}
302303

@@ -582,12 +583,13 @@ func (f *File) getDrawingRelationships(rels, rID string) *xlsxRelationship {
582583
// drawingsWriter provides a function to save xl/drawings/drawing%d.xml after
583584
// serialize structure.
584585
func (f *File) drawingsWriter() {
585-
for path, d := range f.Drawings {
586+
f.Drawings.Range(func(path, d interface{}) bool {
586587
if d != nil {
587-
v, _ := xml.Marshal(d)
588-
f.saveFileList(path, v)
588+
v, _ := xml.Marshal(d.(*xlsxWsDr))
589+
f.saveFileList(path.(string), v)
589590
}
590-
}
591+
return true
592+
})
591593
}
592594

593595
// drawingResize calculate the height and width after resizing.

shape.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, formatSet *format
436436
FPrintsWithSheet: formatSet.Format.FPrintsWithSheet,
437437
}
438438
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
439-
f.Drawings[drawingXML] = content
439+
f.Drawings.Store(drawingXML, content)
440440
return err
441441
}
442442

sheet.go

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,16 @@ func (f *File) setWorkbook(name string, sheetID, rid int) {
231231
// relsWriter provides a function to save relationships after
232232
// serialize structure.
233233
func (f *File) relsWriter() {
234-
for path, rel := range f.Relationships {
234+
f.Relationships.Range(func(path, rel interface{}) bool {
235235
if rel != nil {
236-
output, _ := xml.Marshal(rel)
237-
if strings.HasPrefix(path, "xl/worksheets/sheet/rels/sheet") {
238-
output = f.replaceNameSpaceBytes(path, output)
236+
output, _ := xml.Marshal(rel.(*xlsxRelationships))
237+
if strings.HasPrefix(path.(string), "xl/worksheets/sheet/rels/sheet") {
238+
output = f.replaceNameSpaceBytes(path.(string), output)
239239
}
240-
f.saveFileList(path, replaceRelationshipsBytes(output))
240+
f.saveFileList(path.(string), replaceRelationshipsBytes(output))
241241
}
242-
}
242+
return true
243+
})
243244
}
244245

245246
// setAppXML update docProps/app.xml file of XML.
@@ -359,22 +360,6 @@ func (f *File) SetSheetName(oldName, newName string) {
359360
}
360361
}
361362

362-
// getSheetNameByID provides a function to get worksheet name of the
363-
// spreadsheet by given worksheet ID. If given sheet ID is invalid, will
364-
// return an empty string.
365-
func (f *File) getSheetNameByID(ID int) string {
366-
wb := f.workbookReader()
367-
if wb == nil || ID < 1 {
368-
return ""
369-
}
370-
for _, sheet := range wb.Sheets.Sheet {
371-
if ID == sheet.SheetID {
372-
return sheet.Name
373-
}
374-
}
375-
return ""
376-
}
377-
378363
// GetSheetName provides a function to get the sheet name of the workbook by
379364
// the given sheet index. If the given sheet index is invalid, it will return
380365
// an empty string.
@@ -541,7 +526,7 @@ func (f *File) DeleteSheet(name string) {
541526
delete(f.sheetMap, sheetName)
542527
delete(f.XLSX, sheetXML)
543528
delete(f.XLSX, rels)
544-
delete(f.Relationships, rels)
529+
f.Relationships.Delete(rels)
545530
delete(f.Sheet, sheetXML)
546531
delete(f.xmlAttr, sheetXML)
547532
f.SheetCount--
@@ -1727,20 +1712,22 @@ func (f *File) RemovePageBreak(sheet, cell string) (err error) {
17271712
// after deserialization of xl/worksheets/_rels/sheet%d.xml.rels.
17281713
func (f *File) relsReader(path string) *xlsxRelationships {
17291714
var err error
1730-
1731-
if f.Relationships[path] == nil {
1715+
rels, _ := f.Relationships.Load(path)
1716+
if rels == nil {
17321717
_, ok := f.XLSX[path]
17331718
if ok {
17341719
c := xlsxRelationships{}
17351720
if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(path)))).
17361721
Decode(&c); err != nil && err != io.EOF {
17371722
log.Printf("xml decode error: %s", err)
17381723
}
1739-
f.Relationships[path] = &c
1724+
f.Relationships.Store(path, &c)
17401725
}
17411726
}
1742-
1743-
return f.Relationships[path]
1727+
if rels, _ = f.Relationships.Load(path); rels != nil {
1728+
return rels.(*xlsxRelationships)
1729+
}
1730+
return nil
17441731
}
17451732

17461733
// fillSheetData ensures there are enough rows, and columns in the chosen

0 commit comments

Comments
 (0)