forked from p30928647/excelize
Support concurrency add picture
This commit is contained in:
parent
544ef18a8c
commit
b7fece5173
|
@ -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:]...)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
16
picture.go
16
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
|
||||
|
|
2
rows.go
2
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 {
|
||||
|
|
8
sheet.go
8
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:]...)
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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"`
|
||||
|
|
|
@ -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"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue