summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-07-06 00:31:04 +0800
committerxuri <xuri.me@gmail.com>2021-07-06 00:31:04 +0800
commitb7fece51736977e7d84aca30ecce7f6b3a1251f2 (patch)
tree77c730b216adbdf54b1b5c3542478bfcb2e5c61b
parent544ef18a8cb9949fcb8833c6d2816783c90f3318 (diff)
Support concurrency add picture
-rw-r--r--calcchain.go2
-rw-r--r--cell_test.go5
-rw-r--r--comment.go2
-rw-r--r--drawing.go9
-rw-r--r--excelize.go8
-rw-r--r--picture.go16
-rw-r--r--rows.go2
-rw-r--r--sheet.go8
-rw-r--r--xmlContentTypes.go6
-rw-r--r--xmlDrawing.go6
-rw-r--r--xmlWorkbook.go6
11 files changed, 64 insertions, 6 deletions
diff --git a/calcchain.go b/calcchain.go
index 1b99a04..671d144 100644
--- a/calcchain.go
+++ b/calcchain.go
@@ -56,6 +56,8 @@ func (f *File) deleteCalcChain(index int, axis string) {
f.CalcChain = nil
f.Pkg.Delete("xl/calcChain.xml")
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
for k, v := range content.Overrides {
if v.PartName == "/xl/calcChain.xml" {
content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
diff --git a/cell_test.go b/cell_test.go
index e289983..91f4804 100644
--- a/cell_test.go
+++ b/cell_test.go
@@ -10,6 +10,8 @@ import (
"testing"
"time"
+ _ "image/jpeg"
+
"github.com/stretchr/testify/assert"
)
@@ -25,6 +27,9 @@ func TestConcurrency(t *testing.T) {
assert.NoError(t, f.SetCellValue("Sheet1", fmt.Sprintf("B%d", val), strconv.Itoa(val)))
_, err := f.GetCellValue("Sheet1", fmt.Sprintf("A%d", val))
assert.NoError(t, err)
+ // Concurrency add picture
+ assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
+ `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`))
// Concurrency get cell picture
name, raw, err := f.GetPicture("Sheet1", "A1")
assert.Equal(t, "", name)
diff --git a/comment.go b/comment.go
index 306826d..a89d2bb 100644
--- a/comment.go
+++ b/comment.go
@@ -76,6 +76,8 @@ func (f *File) GetComments() (comments map[string][]Comment) {
func (f *File) getSheetComments(sheetFile string) string {
var rels = "xl/worksheets/_rels/" + sheetFile + ".rels"
if sheetRels := f.relsReader(rels); sheetRels != nil {
+ sheetRels.Lock()
+ defer sheetRels.Unlock()
for _, v := range sheetRels.Relationships {
if v.Type == SourceRelationshipComments {
return v.Target
diff --git a/drawing.go b/drawing.go
index 181bb43..86d5ca6 100644
--- a/drawing.go
+++ b/drawing.go
@@ -1173,8 +1173,13 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
}
f.Drawings.Store(path, &content)
}
- wsDr, _ := f.Drawings.Load(path)
- return wsDr.(*xlsxWsDr), len(wsDr.(*xlsxWsDr).OneCellAnchor) + len(wsDr.(*xlsxWsDr).TwoCellAnchor) + 2
+ var wsDr *xlsxWsDr
+ if drawing, ok := f.Drawings.Load(path); ok && drawing != nil {
+ wsDr = drawing.(*xlsxWsDr)
+ }
+ wsDr.Lock()
+ defer wsDr.Unlock()
+ return wsDr, len(wsDr.OneCellAnchor) + len(wsDr.TwoCellAnchor) + 2
}
// addDrawingChart provides a function to add chart graphic frame by given
diff --git a/excelize.go b/excelize.go
index bdb7120..0091c82 100644
--- a/excelize.go
+++ b/excelize.go
@@ -43,7 +43,7 @@ type File struct {
Path string
SharedStrings *xlsxSST
sharedStringsMap map[string]int
- Sheet sync.Map // map[string]*xlsxWorksheet
+ Sheet sync.Map
SheetCount int
Styles *xlsxStyleSheet
Theme *xlsxTheme
@@ -257,6 +257,8 @@ func (f *File) addRels(relPath, relType, target, targetMode string) int {
if rels == nil {
rels = &xlsxRelationships{}
}
+ rels.Lock()
+ defer rels.Unlock()
var rID int
for idx, rel := range rels.Relationships {
ID, _ := strconv.Atoi(strings.TrimPrefix(rel.ID, "rId"))
@@ -357,6 +359,8 @@ func (f *File) AddVBAProject(bin string) error {
}
f.setContentTypePartVBAProjectExtensions()
wb := f.relsReader(f.getWorkbookRelsPath())
+ wb.Lock()
+ defer wb.Unlock()
var rID int
var ok bool
for _, rel := range wb.Relationships {
@@ -387,6 +391,8 @@ func (f *File) AddVBAProject(bin string) error {
func (f *File) setContentTypePartVBAProjectExtensions() {
var ok bool
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
for _, v := range content.Defaults {
if v.Extension == "bin" {
ok = true
diff --git a/picture.go b/picture.go
index 58fa909..e524224 100644
--- a/picture.go
+++ b/picture.go
@@ -184,6 +184,8 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
if sheetRels == nil {
sheetRels = &xlsxRelationships{}
}
+ sheetRels.Lock()
+ defer sheetRels.Unlock()
for k, v := range sheetRels.Relationships {
if v.ID == rID {
sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...)
@@ -297,6 +299,8 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
FLocksWithSheet: formatSet.FLocksWithSheet,
FPrintsWithSheet: formatSet.FPrintsWithSheet,
}
+ content.Lock()
+ defer content.Unlock()
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
f.Drawings.Store(drawingXML, content)
return err
@@ -344,6 +348,8 @@ func (f *File) addMedia(file []byte, ext string) string {
func (f *File) setContentTypePartImageExtensions() {
var imageTypes = map[string]bool{"jpeg": false, "png": false, "gif": false, "tiff": false}
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
for _, v := range content.Defaults {
_, ok := imageTypes[v.Extension]
if ok {
@@ -365,6 +371,8 @@ func (f *File) setContentTypePartImageExtensions() {
func (f *File) setContentTypePartVMLExtensions() {
vml := false
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
for _, v := range content.Defaults {
if v.Extension == "vml" {
vml = true
@@ -410,6 +418,8 @@ func (f *File) addContentTypePart(index int, contentType string) {
s()
}
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
for _, v := range content.Overrides {
if v.PartName == partNames[contentType] {
return
@@ -434,6 +444,8 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
if sheetRels == nil {
sheetRels = &xlsxRelationships{}
}
+ sheetRels.Lock()
+ defer sheetRels.Unlock()
for _, v := range sheetRels.Relationships {
if v.ID == rID {
return v.Target
@@ -560,6 +572,8 @@ func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsD
anchor *xdrCellAnchor
drawRel *xlsxRelationship
)
+ wsDr.Lock()
+ defer wsDr.Unlock()
for _, anchor = range wsDr.TwoCellAnchor {
if anchor.From != nil && anchor.Pic != nil {
if anchor.From.Col == col && anchor.From.Row == row {
@@ -584,6 +598,8 @@ func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsD
// relationship ID.
func (f *File) getDrawingRelationships(rels, rID string) *xlsxRelationship {
if drawingRels := f.relsReader(rels); drawingRels != nil {
+ drawingRels.Lock()
+ defer drawingRels.Unlock()
for _, v := range drawingRels.Relationships {
if v.ID == rID {
return &v
diff --git a/rows.go b/rows.go
index 229b12d..a40f4a9 100644
--- a/rows.go
+++ b/rows.go
@@ -272,6 +272,8 @@ func (f *File) SetRowHeight(sheet string, row int, height float64) error {
// name and row number.
func (f *File) getRowHeight(sheet string, row int) int {
ws, _ := f.workSheetReader(sheet)
+ ws.Lock()
+ defer ws.Unlock()
for i := range ws.SheetData.Row {
v := &ws.SheetData.Row[i]
if v.R == row && v.Ht != 0 {
diff --git a/sheet.go b/sheet.go
index 2b91495..3a55540 100644
--- a/sheet.go
+++ b/sheet.go
@@ -93,6 +93,8 @@ func (f *File) contentTypesWriter() {
// the spreadsheet.
func (f *File) getWorkbookPath() (path string) {
if rels := f.relsReader("_rels/.rels"); rels != nil {
+ rels.Lock()
+ defer rels.Unlock()
for _, rel := range rels.Relationships {
if rel.Type == SourceRelationshipOfficeDocument {
path = strings.TrimPrefix(rel.Target, "/")
@@ -198,6 +200,8 @@ func trimCell(column []xlsxC) []xlsxC {
// type of the spreadsheet.
func (f *File) setContentTypes(partName, contentType string) {
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
content.Overrides = append(content.Overrides, xlsxOverride{
PartName: partName,
ContentType: contentType,
@@ -540,6 +544,8 @@ func (f *File) DeleteSheet(name string) {
// relationships by given relationships ID in the file workbook.xml.rels.
func (f *File) deleteSheetFromWorkbookRels(rID string) string {
content := f.relsReader(f.getWorkbookRelsPath())
+ content.Lock()
+ defer content.Unlock()
for k, v := range content.Relationships {
if v.ID == rID {
content.Relationships = append(content.Relationships[:k], content.Relationships[k+1:]...)
@@ -556,6 +562,8 @@ func (f *File) deleteSheetFromContentTypes(target string) {
target = "/xl/" + target
}
content := f.contentTypesReader()
+ content.Lock()
+ defer content.Unlock()
for k, v := range content.Overrides {
if v.PartName == target {
content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
diff --git a/xmlContentTypes.go b/xmlContentTypes.go
index f429ef6..6b6db63 100644
--- a/xmlContentTypes.go
+++ b/xmlContentTypes.go
@@ -11,12 +11,16 @@
package excelize
-import "encoding/xml"
+import (
+ "encoding/xml"
+ "sync"
+)
// xlsxTypes directly maps the types element of content types for relationship
// parts, it takes a Multipurpose Internet Mail Extension (MIME) media type as a
// value.
type xlsxTypes struct {
+ sync.Mutex
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"`
Overrides []xlsxOverride `xml:"Override"`
Defaults []xlsxDefault `xml:"Default"`
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 4b51b63..4e35fcf 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -11,7 +11,10 @@
package excelize
-import "encoding/xml"
+import (
+ "encoding/xml"
+ "sync"
+)
// Source relationship and namespace list, associated prefixes and schema in which it was
// introduced.
@@ -303,6 +306,7 @@ type xlsxPoint2D struct {
// xlsxWsDr directly maps the root element for a part of this content type shall
// wsDr.
type xlsxWsDr struct {
+ sync.Mutex
XMLName xml.Name `xml:"xdr:wsDr"`
AbsoluteAnchor []*xdrCellAnchor `xml:"xdr:absoluteAnchor"`
OneCellAnchor []*xdrCellAnchor `xml:"xdr:oneCellAnchor"`
diff --git a/xmlWorkbook.go b/xmlWorkbook.go
index 7151c6f..0e8839b 100644
--- a/xmlWorkbook.go
+++ b/xmlWorkbook.go
@@ -11,10 +11,14 @@
package excelize
-import "encoding/xml"
+import (
+ "encoding/xml"
+ "sync"
+)
// xlsxRelationships describe references from parts to other internal resources in the package or to external resources.
type xlsxRelationships struct {
+ sync.Mutex
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
Relationships []xlsxRelationship `xml:"Relationship"`
}