forked from p30928647/excelize
This optimizes internal functions signature and mutex declarations
This commit is contained in:
parent
787453c6f0
commit
93c72b4d55
|
@ -60,8 +60,8 @@ func (f *File) adjustHelper(sheet string, dir adjustDirection, num, offset int)
|
|||
if err = f.adjustCalcChain(dir, num, offset, sheetID); err != nil {
|
||||
return err
|
||||
}
|
||||
checkSheet(ws)
|
||||
_ = checkRow(ws)
|
||||
ws.checkSheet()
|
||||
_ = ws.checkRow()
|
||||
|
||||
if ws.MergeCells != nil && len(ws.MergeCells.Cells) == 0 {
|
||||
ws.MergeCells = nil
|
||||
|
|
10
calc.go
10
calc.go
|
@ -215,7 +215,7 @@ var (
|
|||
|
||||
// calcContext defines the formula execution context.
|
||||
type calcContext struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
entry string
|
||||
maxCalcIterations uint
|
||||
iterations map[string]uint
|
||||
|
@ -1553,19 +1553,19 @@ func (f *File) cellResolver(ctx *calcContext, sheet, cell string) (formulaArg, e
|
|||
)
|
||||
ref := fmt.Sprintf("%s!%s", sheet, cell)
|
||||
if formula, _ := f.GetCellFormula(sheet, cell); len(formula) != 0 {
|
||||
ctx.Lock()
|
||||
ctx.mu.Lock()
|
||||
if ctx.entry != ref {
|
||||
if ctx.iterations[ref] <= f.options.MaxCalcIterations {
|
||||
ctx.iterations[ref]++
|
||||
ctx.Unlock()
|
||||
ctx.mu.Unlock()
|
||||
arg, _ = f.calcCellValue(ctx, sheet, cell)
|
||||
ctx.iterationsCache[ref] = arg
|
||||
return arg, nil
|
||||
}
|
||||
ctx.Unlock()
|
||||
ctx.mu.Unlock()
|
||||
return ctx.iterationsCache[ref], nil
|
||||
}
|
||||
ctx.Unlock()
|
||||
ctx.mu.Unlock()
|
||||
}
|
||||
if value, err = f.GetCellValue(sheet, cell, Options{RawCellValue: true}); err != nil {
|
||||
return arg, err
|
||||
|
|
|
@ -58,8 +58,8 @@ func (f *File) deleteCalcChain(index int, cell string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
for k, v := range content.Overrides {
|
||||
if v.PartName == "/xl/calcChain.xml" {
|
||||
content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
|
||||
|
|
92
cell.go
92
cell.go
|
@ -236,13 +236,13 @@ func (f *File) setCellTimeFunc(sheet, cell string, value time.Time) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
ws.mu.Unlock()
|
||||
var date1904, isNum bool
|
||||
wb, err := f.workbookReader()
|
||||
if err != nil {
|
||||
|
@ -292,13 +292,13 @@ func (f *File) SetCellInt(sheet, cell string, value int) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
c.T, c.V = setCellInt(value)
|
||||
c.IS = nil
|
||||
return f.removeFormula(c, ws, sheet)
|
||||
|
@ -318,13 +318,13 @@ func (f *File) SetCellBool(sheet, cell string, value bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
c.T, c.V = setCellBool(value)
|
||||
c.IS = nil
|
||||
return f.removeFormula(c, ws, sheet)
|
||||
|
@ -355,13 +355,13 @@ func (f *File) SetCellFloat(sheet, cell string, value float64, precision, bitSiz
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
c.T, c.V = setCellFloat(value, precision, bitSize)
|
||||
c.IS = nil
|
||||
return f.removeFormula(c, ws, sheet)
|
||||
|
@ -381,13 +381,13 @@ func (f *File) SetCellStr(sheet, cell, value string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
if c.T, c.V, err = f.setCellString(value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -413,8 +413,8 @@ func (f *File) setCellString(value string) (t, v string, err error) {
|
|||
// sharedStringsLoader load shared string table from system temporary file to
|
||||
// memory, and reset shared string table for reader.
|
||||
func (f *File) sharedStringsLoader() (err error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
if path, ok := f.tempFiles.Load(defaultXMLPathSharedStrings); ok {
|
||||
f.Pkg.Store(defaultXMLPathSharedStrings, f.readBytes(defaultXMLPathSharedStrings))
|
||||
f.tempFiles.Delete(defaultXMLPathSharedStrings)
|
||||
|
@ -443,8 +443,8 @@ func (f *File) setSharedString(val string) (int, error) {
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
if i, ok := f.sharedStringsMap[val]; ok {
|
||||
return i, nil
|
||||
}
|
||||
|
@ -558,8 +558,8 @@ func (c *xlsxC) getCellDate(f *File, raw bool) (string, error) {
|
|||
// intended to be used with for range on rows an argument with the spreadsheet
|
||||
// opened file.
|
||||
func (c *xlsxC) getValueFrom(f *File, d *xlsxSST, raw bool) (string, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
switch c.T {
|
||||
case "b":
|
||||
return c.getCellBool(f, raw)
|
||||
|
@ -600,13 +600,13 @@ func (f *File) SetCellDefault(sheet, cell, value string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
c.setCellDefault(value)
|
||||
return f.removeFormula(c, ws, sheet)
|
||||
}
|
||||
|
@ -718,7 +718,7 @@ func (f *File) SetCellFormula(sheet, cell, formula string, opts ...FormulaOpts)
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, _, _, err := f.prepareCell(ws, cell)
|
||||
c, _, _, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -763,7 +763,7 @@ func (ws *xlsxWorksheet) setSharedFormula(ref string) error {
|
|||
cnt := ws.countSharedFormula()
|
||||
for c := coordinates[0]; c <= coordinates[2]; c++ {
|
||||
for r := coordinates[1]; r <= coordinates[3]; r++ {
|
||||
prepareSheetXML(ws, c, r)
|
||||
ws.prepareSheetXML(c, r)
|
||||
cell := &ws.SheetData.Row[r-1].C[c-1]
|
||||
if cell.F == nil {
|
||||
cell.F = &xlsxF{}
|
||||
|
@ -867,7 +867,7 @@ func (f *File) SetCellHyperLink(sheet, cell, link, linkType string, opts ...Hype
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cell, err = f.mergeCellsParser(ws, cell); err != nil {
|
||||
if cell, err = ws.mergeCellsParser(cell); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -944,7 +944,7 @@ func (f *File) GetCellRichText(sheet, cell string) (runs []RichTextRun, err erro
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
c, _, _, err := f.prepareCell(ws, cell)
|
||||
c, _, _, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -1171,14 +1171,14 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, col, row, err := f.prepareCell(ws, cell)
|
||||
c, col, row, err := ws.prepareCell(cell)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.sharedStringsLoader(); err != nil {
|
||||
return err
|
||||
}
|
||||
c.S = f.prepareCellStyle(ws, col, row, c.S)
|
||||
c.S = ws.prepareCellStyle(col, row, c.S)
|
||||
si := xlsxSI{}
|
||||
sst, err := f.sharedStringsReader()
|
||||
if err != nil {
|
||||
|
@ -1252,9 +1252,9 @@ func (f *File) setSheetCells(sheet, cell string, slice interface{}, dir adjustDi
|
|||
}
|
||||
|
||||
// getCellInfo does common preparation for all set cell value functions.
|
||||
func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, error) {
|
||||
func (ws *xlsxWorksheet) prepareCell(cell string) (*xlsxC, int, int, error) {
|
||||
var err error
|
||||
cell, err = f.mergeCellsParser(ws, cell)
|
||||
cell, err = ws.mergeCellsParser(cell)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
|
@ -1263,9 +1263,9 @@ func (f *File) prepareCell(ws *xlsxWorksheet, cell string) (*xlsxC, int, int, er
|
|||
return nil, 0, 0, err
|
||||
}
|
||||
|
||||
prepareSheetXML(ws, col, row)
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.prepareSheetXML(col, row)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
return &ws.SheetData.Row[row-1].C[col-1], col, row, err
|
||||
}
|
||||
|
||||
|
@ -1277,7 +1277,7 @@ func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
cell, err = f.mergeCellsParser(ws, cell)
|
||||
cell, err = ws.mergeCellsParser(cell)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -1286,8 +1286,8 @@ func (f *File) getCellStringFunc(sheet, cell string, fn func(x *xlsxWorksheet, c
|
|||
return "", err
|
||||
}
|
||||
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
|
||||
lastRowNum := 0
|
||||
if l := len(ws.SheetData.Row); l > 0 {
|
||||
|
@ -1366,7 +1366,7 @@ func (f *File) formattedValue(c *xlsxC, raw bool, cellType CellType) (string, er
|
|||
|
||||
// prepareCellStyle provides a function to prepare style index of cell in
|
||||
// worksheet by given column index and style index.
|
||||
func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
|
||||
func (ws *xlsxWorksheet) prepareCellStyle(col, row, style int) int {
|
||||
if style != 0 {
|
||||
return style
|
||||
}
|
||||
|
@ -1387,7 +1387,7 @@ func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
|
|||
|
||||
// mergeCellsParser provides a function to check merged cells in worksheet by
|
||||
// given cell reference.
|
||||
func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error) {
|
||||
func (ws *xlsxWorksheet) mergeCellsParser(cell string) (string, error) {
|
||||
cell = strings.ToUpper(cell)
|
||||
col, row, err := CellNameToCoordinates(cell)
|
||||
if err != nil {
|
||||
|
|
44
col.go
44
col.go
|
@ -215,11 +215,11 @@ func (f *File) Cols(sheet string) (*Cols, error) {
|
|||
if !ok {
|
||||
return nil, ErrSheetNotExist{sheet}
|
||||
}
|
||||
if ws, ok := f.Sheet.Load(name); ok && ws != nil {
|
||||
worksheet := ws.(*xlsxWorksheet)
|
||||
worksheet.Lock()
|
||||
defer worksheet.Unlock()
|
||||
output, _ := xml.Marshal(worksheet)
|
||||
if worksheet, ok := f.Sheet.Load(name); ok && worksheet != nil {
|
||||
ws := worksheet.(*xlsxWorksheet)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
output, _ := xml.Marshal(ws)
|
||||
f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
|
||||
}
|
||||
var colIterator columnXMLIterator
|
||||
|
@ -261,8 +261,8 @@ func (f *File) GetColVisible(sheet, col string) (bool, error) {
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
if ws.Cols == nil {
|
||||
return true, err
|
||||
}
|
||||
|
@ -295,8 +295,8 @@ func (f *File) SetColVisible(sheet, columns string, visible bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
colData := xlsxCol{
|
||||
Min: min,
|
||||
Max: max,
|
||||
|
@ -432,17 +432,17 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Lock()
|
||||
s.mu.Lock()
|
||||
if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
|
||||
s.Unlock()
|
||||
s.mu.Unlock()
|
||||
return newInvalidStyleID(styleID)
|
||||
}
|
||||
s.Unlock()
|
||||
s.mu.Unlock()
|
||||
ws, err := f.workSheetReader(sheet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
ws.mu.Lock()
|
||||
if ws.Cols == nil {
|
||||
ws.Cols = &xlsxCols{}
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
|
|||
fc.Width = c.Width
|
||||
return fc
|
||||
})
|
||||
ws.Unlock()
|
||||
ws.mu.Unlock()
|
||||
if rows := len(ws.SheetData.Row); rows > 0 {
|
||||
for col := min; col <= max; col++ {
|
||||
from, _ := CoordinatesToCellName(col, 1)
|
||||
|
@ -488,8 +488,8 @@ func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
col := xlsxCol{
|
||||
Min: min,
|
||||
Max: max,
|
||||
|
@ -634,8 +634,8 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
|
|||
// sheet name and column number.
|
||||
func (f *File) getColWidth(sheet string, col int) int {
|
||||
ws, _ := f.workSheetReader(sheet)
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
if ws.Cols != nil {
|
||||
var width float64
|
||||
for _, v := range ws.Cols.Col {
|
||||
|
@ -663,8 +663,8 @@ func (f *File) GetColStyle(sheet, col string) (int, error) {
|
|||
if err != nil {
|
||||
return styleID, err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
if ws.Cols != nil {
|
||||
for _, v := range ws.Cols.Col {
|
||||
if v.Min <= colNum && colNum <= v.Max {
|
||||
|
@ -686,8 +686,8 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
|
|||
if err != nil {
|
||||
return defaultColWidth, err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
if ws.Cols != nil {
|
||||
var width float64
|
||||
for _, v := range ws.Cols.Col {
|
||||
|
|
|
@ -68,8 +68,8 @@ func (f *File) GetComments(sheet string) ([]Comment, error) {
|
|||
func (f *File) getSheetComments(sheetFile string) string {
|
||||
rels, _ := f.relsReader("xl/worksheets/_rels/" + sheetFile + ".rels")
|
||||
if sheetRels := rels; sheetRels != nil {
|
||||
sheetRels.Lock()
|
||||
defer sheetRels.Unlock()
|
||||
sheetRels.mu.Lock()
|
||||
defer sheetRels.mu.Unlock()
|
||||
for _, v := range sheetRels.Relationships {
|
||||
if v.Type == SourceRelationshipComments {
|
||||
return v.Target
|
||||
|
|
|
@ -1285,8 +1285,8 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int, error) {
|
|||
if drawing, ok := f.Drawings.Load(path); ok && drawing != nil {
|
||||
wsDr = drawing.(*xlsxWsDr)
|
||||
}
|
||||
wsDr.Lock()
|
||||
defer wsDr.Unlock()
|
||||
wsDr.mu.Lock()
|
||||
defer wsDr.mu.Unlock()
|
||||
return wsDr, len(wsDr.OneCellAnchor) + len(wsDr.TwoCellAnchor) + 2, nil
|
||||
}
|
||||
|
||||
|
|
32
excelize.go
32
excelize.go
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
// File define a populated spreadsheet file struct.
|
||||
type File struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
options *Options
|
||||
xmlAttr map[string][]xml.Attr
|
||||
checked map[string]bool
|
||||
|
@ -234,8 +234,8 @@ func (f *File) setDefaultTimeStyle(sheet, cell string, format int) error {
|
|||
// workSheetReader provides a function to get the pointer to the structure
|
||||
// after deserialization by given worksheet name.
|
||||
func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
var (
|
||||
name string
|
||||
ok bool
|
||||
|
@ -271,8 +271,8 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
|
|||
f.checked = make(map[string]bool)
|
||||
}
|
||||
if ok = f.checked[name]; !ok {
|
||||
checkSheet(ws)
|
||||
if err = checkRow(ws); err != nil {
|
||||
ws.checkSheet()
|
||||
if err = ws.checkRow(); err != nil {
|
||||
return
|
||||
}
|
||||
f.checked[name] = true
|
||||
|
@ -283,7 +283,7 @@ func (f *File) workSheetReader(sheet string) (ws *xlsxWorksheet, err error) {
|
|||
|
||||
// checkSheet provides a function to fill each row element and make that is
|
||||
// continuous in a worksheet of XML.
|
||||
func checkSheet(ws *xlsxWorksheet) {
|
||||
func (ws *xlsxWorksheet) checkSheet() {
|
||||
var row int
|
||||
var r0 xlsxRow
|
||||
for i, r := range ws.SheetData.Row {
|
||||
|
@ -319,13 +319,13 @@ func checkSheet(ws *xlsxWorksheet) {
|
|||
for i := 1; i <= row; i++ {
|
||||
sheetData.Row[i-1].R = i
|
||||
}
|
||||
checkSheetR0(ws, &sheetData, &r0)
|
||||
ws.checkSheetR0(&sheetData, &r0)
|
||||
}
|
||||
|
||||
// checkSheetR0 handle the row element with r="0" attribute, cells in this row
|
||||
// could be disorderly, the cell in this row can be used as the value of
|
||||
// which cell is empty in the normal rows.
|
||||
func checkSheetR0(ws *xlsxWorksheet, sheetData *xlsxSheetData, r0 *xlsxRow) {
|
||||
func (ws *xlsxWorksheet) checkSheetR0(sheetData *xlsxSheetData, r0 *xlsxRow) {
|
||||
for _, cell := range r0.C {
|
||||
if col, row, err := CellNameToCoordinates(cell.R); err == nil {
|
||||
rows, rowIdx := len(sheetData.Row), row-1
|
||||
|
@ -351,8 +351,8 @@ func (f *File) setRels(rID, relPath, relType, target, targetMode string) int {
|
|||
if rels == nil || rID == "" {
|
||||
return f.addRels(relPath, relType, target, targetMode)
|
||||
}
|
||||
rels.Lock()
|
||||
defer rels.Unlock()
|
||||
rels.mu.Lock()
|
||||
defer rels.mu.Unlock()
|
||||
var ID int
|
||||
for i, rel := range rels.Relationships {
|
||||
if rel.ID == rID {
|
||||
|
@ -376,8 +376,8 @@ func (f *File) addRels(relPath, relType, target, targetMode string) int {
|
|||
if rels == nil {
|
||||
rels = &xlsxRelationships{}
|
||||
}
|
||||
rels.Lock()
|
||||
defer rels.Unlock()
|
||||
rels.mu.Lock()
|
||||
defer rels.mu.Unlock()
|
||||
var rID int
|
||||
for idx, rel := range rels.Relationships {
|
||||
ID, _ := strconv.Atoi(strings.TrimPrefix(rel.ID, "rId"))
|
||||
|
@ -490,8 +490,8 @@ func (f *File) AddVBAProject(file []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rels.Lock()
|
||||
defer rels.Unlock()
|
||||
rels.mu.Lock()
|
||||
defer rels.mu.Unlock()
|
||||
var rID int
|
||||
var ok bool
|
||||
for _, rel := range rels.Relationships {
|
||||
|
@ -524,8 +524,8 @@ func (f *File) setContentTypePartProjectExtensions(contentType string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
for _, v := range content.Defaults {
|
||||
if v.Extension == "bin" {
|
||||
ok = true
|
||||
|
|
8
merge.go
8
merge.go
|
@ -64,8 +64,8 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
ref := hCell + ":" + vCell
|
||||
if ws.MergeCells != nil {
|
||||
ws.MergeCells.Cells = append(ws.MergeCells.Cells, &xlsxMergeCell{Ref: ref, rect: rect})
|
||||
|
@ -87,8 +87,8 @@ func (f *File) UnmergeCell(sheet, hCell, vCell string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
rect1, err := rangeRefToCoordinates(hCell + ":" + vCell)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -207,7 +207,7 @@ func TestFlatMergedCells(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMergeCellsParser(t *testing.T) {
|
||||
f := NewFile()
|
||||
_, err := f.mergeCellsParser(&xlsxWorksheet{MergeCells: &xlsxMergeCells{Cells: []*xlsxMergeCell{nil}}}, "A1")
|
||||
ws := &xlsxWorksheet{MergeCells: &xlsxMergeCells{Cells: []*xlsxMergeCell{nil}}}
|
||||
_, err := ws.mergeCellsParser("A1")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
|
36
picture.go
36
picture.go
|
@ -216,7 +216,7 @@ func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ws.Lock()
|
||||
ws.mu.Lock()
|
||||
// Add first picture for given sheet, create xl/drawings/ and xl/drawings/_rels/ folder.
|
||||
drawingID := f.countDrawings() + 1
|
||||
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
|
||||
|
@ -231,7 +231,7 @@ func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
|
|||
}
|
||||
drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType)
|
||||
}
|
||||
ws.Unlock()
|
||||
ws.mu.Unlock()
|
||||
err = f.addDrawingPicture(sheet, drawingXML, cell, ext, drawingRID, drawingHyperlinkRID, img, options)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -256,8 +256,8 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
|
|||
if sheetRels == nil {
|
||||
sheetRels = &xlsxRelationships{}
|
||||
}
|
||||
sheetRels.Lock()
|
||||
defer sheetRels.Unlock()
|
||||
sheetRels.mu.Lock()
|
||||
defer sheetRels.mu.Unlock()
|
||||
for k, v := range sheetRels.Relationships {
|
||||
if v.ID == rID {
|
||||
sheetRels.Relationships = append(sheetRels.Relationships[:k], sheetRels.Relationships[k+1:]...)
|
||||
|
@ -391,8 +391,8 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, ext string, rID, hyper
|
|||
FLocksWithSheet: *opts.Locked,
|
||||
FPrintsWithSheet: *opts.PrintObject,
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
content.TwoCellAnchor = append(content.TwoCellAnchor, &twoCellAnchor)
|
||||
f.Drawings.Store(drawingXML, content)
|
||||
return err
|
||||
|
@ -447,8 +447,8 @@ func (f *File) setContentTypePartImageExtensions() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
for _, file := range content.Defaults {
|
||||
delete(imageTypes, file.Extension)
|
||||
}
|
||||
|
@ -469,8 +469,8 @@ func (f *File) setContentTypePartVMLExtensions() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
for _, v := range content.Defaults {
|
||||
if v.Extension == "vml" {
|
||||
vml = true
|
||||
|
@ -522,8 +522,8 @@ func (f *File) addContentTypePart(index int, contentType string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
for _, v := range content.Overrides {
|
||||
if v.PartName == partNames[contentType] {
|
||||
return err
|
||||
|
@ -549,8 +549,8 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
|
|||
if sheetRels == nil {
|
||||
sheetRels = &xlsxRelationships{}
|
||||
}
|
||||
sheetRels.Lock()
|
||||
defer sheetRels.Unlock()
|
||||
sheetRels.mu.Lock()
|
||||
defer sheetRels.mu.Unlock()
|
||||
for _, v := range sheetRels.Relationships {
|
||||
if v.ID == rID {
|
||||
return v.Target
|
||||
|
@ -683,8 +683,8 @@ func (f *File) getPicturesFromWsDr(row, col int, drawingRelationships string, ws
|
|||
anchor *xdrCellAnchor
|
||||
drawRel *xlsxRelationship
|
||||
)
|
||||
wsDr.Lock()
|
||||
defer wsDr.Unlock()
|
||||
wsDr.mu.Lock()
|
||||
defer wsDr.mu.Unlock()
|
||||
for _, anchor = range wsDr.TwoCellAnchor {
|
||||
if anchor.From != nil && anchor.Pic != nil {
|
||||
if anchor.From.Col == col && anchor.From.Row == row {
|
||||
|
@ -710,8 +710,8 @@ func (f *File) getPicturesFromWsDr(row, col int, drawingRelationships string, ws
|
|||
// relationship ID.
|
||||
func (f *File) getDrawingRelationships(rels, rID string) *xlsxRelationship {
|
||||
if drawingRels, _ := f.relsReader(rels); drawingRels != nil {
|
||||
drawingRels.Lock()
|
||||
defer drawingRels.Unlock()
|
||||
drawingRels.mu.Lock()
|
||||
defer drawingRels.mu.Unlock()
|
||||
for _, v := range drawingRels.Relationships {
|
||||
if v.ID == rID {
|
||||
return &v
|
||||
|
|
32
rows.go
32
rows.go
|
@ -267,12 +267,12 @@ func (f *File) Rows(sheet string) (*Rows, error) {
|
|||
if !ok {
|
||||
return nil, ErrSheetNotExist{sheet}
|
||||
}
|
||||
if ws, ok := f.Sheet.Load(name); ok && ws != nil {
|
||||
worksheet := ws.(*xlsxWorksheet)
|
||||
worksheet.Lock()
|
||||
defer worksheet.Unlock()
|
||||
if worksheet, ok := f.Sheet.Load(name); ok && worksheet != nil {
|
||||
ws := worksheet.(*xlsxWorksheet)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
// Flush data
|
||||
output, _ := xml.Marshal(worksheet)
|
||||
output, _ := xml.Marshal(ws)
|
||||
f.saveFileList(name, f.replaceNameSpaceBytes(name, output))
|
||||
}
|
||||
var err error
|
||||
|
@ -360,7 +360,7 @@ func (f *File) SetRowHeight(sheet string, row int, height float64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
prepareSheetXML(ws, 0, row)
|
||||
ws.prepareSheetXML(0, row)
|
||||
|
||||
rowIdx := row - 1
|
||||
ws.SheetData.Row[rowIdx].Ht = float64Ptr(height)
|
||||
|
@ -372,8 +372,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()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
for i := range ws.SheetData.Row {
|
||||
v := &ws.SheetData.Row[i]
|
||||
if v.R == row && v.Ht != nil {
|
||||
|
@ -416,8 +416,8 @@ func (f *File) GetRowHeight(sheet string, row int) (float64, error) {
|
|||
// after deserialization of xl/sharedStrings.xml.
|
||||
func (f *File) sharedStringsReader() (*xlsxSST, error) {
|
||||
var err error
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
relPath := f.getWorkbookRelsPath()
|
||||
if f.SharedStrings == nil {
|
||||
var sharedStrings xlsxSST
|
||||
|
@ -470,7 +470,7 @@ func (f *File) SetRowVisible(sheet string, row int, visible bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(ws, 0, row)
|
||||
ws.prepareSheetXML(0, row)
|
||||
ws.SheetData.Row[row-1].Hidden = !visible
|
||||
return nil
|
||||
}
|
||||
|
@ -511,7 +511,7 @@ func (f *File) SetRowOutlineLevel(sheet string, row int, level uint8) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(ws, 0, row)
|
||||
ws.prepareSheetXML(0, row)
|
||||
ws.SheetData.Row[row-1].OutlineLevel = level
|
||||
return nil
|
||||
}
|
||||
|
@ -724,7 +724,7 @@ func (f *File) duplicateMergeCells(sheet string, ws *xlsxWorksheet, row, row2 in
|
|||
//
|
||||
// Notice: this method could be very slow for large spreadsheets (more than
|
||||
// 3000 rows one sheet).
|
||||
func checkRow(ws *xlsxWorksheet) error {
|
||||
func (ws *xlsxWorksheet) checkRow() error {
|
||||
for rowIdx := range ws.SheetData.Row {
|
||||
rowData := &ws.SheetData.Row[rowIdx]
|
||||
|
||||
|
@ -814,8 +814,8 @@ func (f *File) SetRowStyle(sheet string, start, end, styleID int) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
|
||||
return newInvalidStyleID(styleID)
|
||||
}
|
||||
|
@ -823,7 +823,7 @@ func (f *File) SetRowStyle(sheet string, start, end, styleID int) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(ws, 0, end)
|
||||
ws.prepareSheetXML(0, end)
|
||||
for row := start - 1; row < end; row++ {
|
||||
ws.SheetData.Row[row].S = styleID
|
||||
ws.SheetData.Row[row].CustomFormat = true
|
||||
|
|
26
sheet.go
26
sheet.go
|
@ -70,8 +70,8 @@ func (f *File) NewSheet(sheet string) (int, error) {
|
|||
func (f *File) contentTypesReader() (*xlsxTypes, error) {
|
||||
if f.ContentTypes == nil {
|
||||
f.ContentTypes = new(xlsxTypes)
|
||||
f.ContentTypes.Lock()
|
||||
defer f.ContentTypes.Unlock()
|
||||
f.ContentTypes.mu.Lock()
|
||||
defer f.ContentTypes.mu.Unlock()
|
||||
if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathContentTypes)))).
|
||||
Decode(f.ContentTypes); err != nil && err != io.EOF {
|
||||
return f.ContentTypes, err
|
||||
|
@ -217,8 +217,8 @@ func (f *File) setContentTypes(partName, contentType string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
content.Overrides = append(content.Overrides, xlsxOverride{
|
||||
PartName: partName,
|
||||
ContentType: contentType,
|
||||
|
@ -615,8 +615,8 @@ func deleteAndAdjustDefinedNames(wb *xlsxWorkbook, deleteLocalSheetID int) {
|
|||
// relationships by given relationships ID in the file workbook.xml.rels.
|
||||
func (f *File) deleteSheetFromWorkbookRels(rID string) string {
|
||||
rels, _ := f.relsReader(f.getWorkbookRelsPath())
|
||||
rels.Lock()
|
||||
defer rels.Unlock()
|
||||
rels.mu.Lock()
|
||||
defer rels.mu.Unlock()
|
||||
for k, v := range rels.Relationships {
|
||||
if v.ID == rID {
|
||||
rels.Relationships = append(rels.Relationships[:k], rels.Relationships[k+1:]...)
|
||||
|
@ -636,8 +636,8 @@ func (f *File) deleteSheetFromContentTypes(target string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content.Lock()
|
||||
defer content.Unlock()
|
||||
content.mu.Lock()
|
||||
defer content.mu.Unlock()
|
||||
for k, v := range content.Overrides {
|
||||
if v.PartName == target {
|
||||
content.Overrides = append(content.Overrides[:k], content.Overrides[k+1:]...)
|
||||
|
@ -1842,9 +1842,9 @@ func (f *File) relsReader(path string) (*xlsxRelationships, error) {
|
|||
// fillSheetData ensures there are enough rows, and columns in the chosen
|
||||
// row to accept data. Missing rows are backfilled and given their row number
|
||||
// Uses the last populated row as a hint for the size of the next row to add
|
||||
func prepareSheetXML(ws *xlsxWorksheet, col int, row int) {
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
func (ws *xlsxWorksheet) prepareSheetXML(col int, row int) {
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
rowCount := len(ws.SheetData.Row)
|
||||
sizeHint := 0
|
||||
var ht *float64
|
||||
|
@ -1879,8 +1879,8 @@ func fillColumns(rowData *xlsxRow, col, row int) {
|
|||
|
||||
// makeContiguousColumns make columns in specific rows as contiguous.
|
||||
func makeContiguousColumns(ws *xlsxWorksheet, fromRow, toRow, colCount int) {
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
for ; fromRow < toRow; fromRow++ {
|
||||
rowData := &ws.SheetData.Row[fromRow-1]
|
||||
fillColumns(rowData, colCount, fromRow)
|
||||
|
|
22
styles.go
22
styles.go
|
@ -2008,8 +2008,8 @@ func (f *File) NewStyle(style *Style) (int, error) {
|
|||
if err != nil {
|
||||
return cellXfsID, err
|
||||
}
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
// check given style already exist.
|
||||
if cellXfsID, err = f.getStyleID(s, fs); err != nil || cellXfsID != -1 {
|
||||
return cellXfsID, err
|
||||
|
@ -2669,10 +2669,10 @@ func (f *File) GetCellStyle(sheet, cell string) (int, error) {
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
prepareSheetXML(ws, col, row)
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
return f.prepareCellStyle(ws, col, row, ws.SheetData.Row[row-1].C[col-1].S), err
|
||||
ws.prepareSheetXML(col, row)
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
return ws.prepareCellStyle(col, row, ws.SheetData.Row[row-1].C[col-1].S), err
|
||||
}
|
||||
|
||||
// SetCellStyle provides a function to add style attribute for cells by given
|
||||
|
@ -2808,17 +2808,17 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prepareSheetXML(ws, vCol, vRow)
|
||||
ws.prepareSheetXML(vCol, vRow)
|
||||
makeContiguousColumns(ws, hRow, vRow, vCol)
|
||||
ws.Lock()
|
||||
defer ws.Unlock()
|
||||
ws.mu.Lock()
|
||||
defer ws.mu.Unlock()
|
||||
|
||||
s, err := f.stylesReader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if styleID < 0 || s.CellXfs == nil || len(s.CellXfs.Xf) <= styleID {
|
||||
return newInvalidStyleID(styleID)
|
||||
}
|
||||
|
|
|
@ -145,8 +145,8 @@ func (f *File) setWorkbook(name string, sheetID, rid int) {
|
|||
// the spreadsheet.
|
||||
func (f *File) getWorkbookPath() (path string) {
|
||||
if rels, _ := f.relsReader("_rels/.rels"); rels != nil {
|
||||
rels.Lock()
|
||||
defer rels.Unlock()
|
||||
rels.mu.Lock()
|
||||
defer rels.mu.Unlock()
|
||||
for _, rel := range rels.Relationships {
|
||||
if rel.Type == SourceRelationshipOfficeDocument {
|
||||
path = strings.TrimPrefix(rel.Target, "/")
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
// parts, it takes a Multipurpose Internet Mail Extension (MIME) media type as a
|
||||
// value.
|
||||
type xlsxTypes struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/content-types Types"`
|
||||
Defaults []xlsxDefault `xml:"Default"`
|
||||
Overrides []xlsxOverride `xml:"Override"`
|
||||
|
|
|
@ -440,7 +440,7 @@ type xlsxPoint2D struct {
|
|||
// xlsxWsDr directly maps the root element for a part of this content type shall
|
||||
// wsDr.
|
||||
type xlsxWsDr struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
XMLName xml.Name `xml:"xdr:wsDr"`
|
||||
A string `xml:"xmlns:a,attr,omitempty"`
|
||||
Xdr string `xml:"xmlns:xdr,attr,omitempty"`
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
// xlsxStyleSheet is the root element of the Styles part.
|
||||
type xlsxStyleSheet struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main styleSheet"`
|
||||
NumFmts *xlsxNumFmts `xml:"numFmts"`
|
||||
Fonts *xlsxFonts `xml:"fonts"`
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
// xlsxRelationships describe references from parts to other internal resources in the package or to external resources.
|
||||
type xlsxRelationships struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/package/2006/relationships Relationships"`
|
||||
Relationships []xlsxRelationship `xml:"Relationship"`
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
// xlsxWorksheet directly maps the worksheet element in the namespace
|
||||
// http://schemas.openxmlformats.org/spreadsheetml/2006/main.
|
||||
type xlsxWorksheet struct {
|
||||
sync.Mutex
|
||||
mu sync.Mutex
|
||||
XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"`
|
||||
SheetPr *xlsxSheetPr `xml:"sheetPr"`
|
||||
Dimension *xlsxDimension `xml:"dimension"`
|
||||
|
|
Loading…
Reference in New Issue